001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.client.monitoring;
020
021import java.io.Serializable;
022import java.util.*;
023
024/**
025 * Base superclass for components of a JPPF grid topology.
026 * This class proivdes an API to navigate the topology tree and attributes common to all ellements in te tree.
027 * @param <E> the type of component.
028 * @author Laurent Cohen
029 * @since 5.1
030 */
031@SuppressWarnings("rawtypes")
032public abstract class AbstractComponent<E extends AbstractComponent> implements Serializable {
033  /**
034   * Explicit serialVersionUID.
035   */
036  private static final long serialVersionUID = 1L;
037  /**
038   * The children of this component.
039   */
040  protected transient final Map<String, E> children = new HashMap<>();
041  /**
042   * The parent of this component.
043   */
044  protected transient E parent;
045  /**
046   * The uuid of this component.
047   */
048  protected final String uuid;
049
050  /**
051   * Initialize this component witht he specified uuid.
052   * @param uuid the uuid assigned to this component.
053   */
054  protected AbstractComponent(final String uuid) {
055    this.uuid = uuid;
056  }
057
058  /**
059   * Get the parent of this compponent.
060   * @return the parent as a {@link AbstractComponent} instance.
061   */
062  public synchronized E getParent() {
063    return parent;
064  }
065
066  /**
067   * Set the parent of this compponent.
068   * @param parent the parent as a {@link AbstractComponent} instance.
069   */
070  synchronized void setParent(final E parent) {
071    this.parent = parent;
072  }
073
074  /**
075   * Get the child with the specified uuid.
076   * @param uuid the uuid of the child to look for.
077   * @return a {@link AbstractComponent} or {@code null} if there is no child with this uuid.
078   */
079  public synchronized E getChild(final String uuid) {
080    return children.get(uuid);
081  }
082
083  /**
084   * Get the number of children of this topology component.
085   * @return the number of children.
086   */
087  public synchronized int getChildCount() {
088    return children.size();
089  }
090
091  /**
092   * Get the children of this component in a thread-safe way.
093   * The returned list is a copy of the list of children and can be mainupalted without affect the internal state of this object.
094   * @return a list of {@link AbstractComponent} instances.
095   */
096  public synchronized List<E> getChildren() {
097    return new ArrayList<>(children.values());
098  }
099
100  /**
101   * Add a child to this component.
102   * @param child the child component to add.
103   * @exclude
104   */
105  @SuppressWarnings("unchecked")
106  public synchronized void add(final E child) {
107    children.put(child.getUuid(), child);
108    child.setParent(this);
109  }
110
111  /**
112   * Remove a child from this component.
113   * @param child the child component to remove.
114   * @exclude
115   */
116  @SuppressWarnings("unchecked")
117  public synchronized void remove(final E child) {
118    if (child != null) {
119      children.remove(child.getUuid());
120      child.setParent(null);
121    }
122  }
123
124  /**
125   * Get the uuid of this ocmponent.
126   * @return the uuid as a strring.
127   */
128  public synchronized String getUuid() {
129    return uuid;
130  }
131
132  /**
133   * Get a user-friendly representation of this topology component.
134   * @return a displayable string representing this object.
135   */
136  public String getDisplayName() {
137    return toString();
138  }
139
140  @Override
141  public int hashCode() {
142    final int prime = 31;
143    int result = 1;
144    result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
145    return result;
146  }
147
148  @Override
149  public boolean equals(final Object obj) {
150    if (this == obj) return true;
151    if (obj == null) return false;
152    if (getClass() != obj.getClass()) return false;
153    final AbstractComponent<?> other = (AbstractComponent<?>) obj;
154    if (uuid == null) return other.getUuid() == null;
155    return uuid.equals(other.getUuid());
156  }
157}