code: /*--------------------------------------------------------------*
    Copyright (C) 2006-2015 OpenSim Ltd.
  
    This file is distributed WITHOUT ANY WARRANTY. See the file
    'License' for details on this and other legal matters.
  *--------------------------------------------------------------*/
  
  package org.omnetpp.ned.model;
  
  import java.util.List;
  
  import org.omnetpp.ned.model.ex.MsgFileElementEx;
  import org.omnetpp.ned.model.ex.NedFileElementEx;
  import org.omnetpp.ned.model.interfaces.INedTypeElement;
  import org.omnetpp.ned.model.interfaces.INedTypeLookupContext;
  import org.omnetpp.ned.model.interfaces.INedTypeResolver;
  import org.omnetpp.ned.model.notification.INedChangeListener;
  import org.omnetpp.ned.model.notification.NedModelEvent;
  import org.omnetpp.ned.model.pojo.NedElementTags;
  
  /**
   * Base class for objects in a NED object tree, the XML-based
   * in-memory representation for NED files. An instance of a INedElement
   * subclass represent an XML element.
   *
   * INedElement provides a DOM-like, generic access to the tree;
   * subclasses additionally provide a typed interface.
   *
   * @author andras, rhornig
   */
  public interface INedElement extends Iterable<INedElement>, NedElementTags, NedElementConstants {
  
      public static final int SEVERITY_NONE = -1;
  
      /**
       * Returns the name of the XML element the class represents.
       */
      public String getTagName();
  
      /**
       * Returns the element type as a lower case string suitable for displaying
       * in the UI; e.g. for a SimpleModuleElement it returns "simple module".
       * Usually derived from getTagName().
       */
      public String getReadableTagName();
  
      /**
       * Returns the numeric code (NED_xxx) of the XML element the class represents.
       */
      public int getTagCode();
  
      /**
       * Returns a unique id, originally set by the constructor.
       */
      public long getId();
  
      /**
       * Unique id assigned by the constructor can be overwritten here.
       */
      public void setId(long _id);
  
      /**
       * Returns a string containing a file/line position showing where this
       * element originally came from.
       */
      public String getSourceLocation();
  
      /**
       * Sets location string (a string containing a file/line position showing
       * where this element originally came from). Called by the (NED/XML) parser.
       */
      public void setSourceLocation(String fileName, int lineNumber);
  
      /**
       * Returns the name of the NED file this element originally came from.
       */
      public String getSourceFileName();
  
      /**
       * Returns the line number in the NED file this element originally came from.
       */
      public int getSourceLineNumber();
  
      /**
       * Returns the source region, containing a line:col region in the source file
       * that corresponds to this element. May be null.
       */
      public NedSourceRegion getSourceRegion();
  
      /**
       * Sets source region, containing a line:col region in the source file
       * that corresponds to this element. Info comes from the NED parser.
       */
      public void setSourceRegion(NedSourceRegion region);
  
      /**
       * Sets every attribute to its default value (as returned by getAttributeDefault()).
       * Attributes without a default value are not affected.
       *
       * This method is called from the constructors of derived classes.
       */
      public void applyDefaults();
  
      /**
       * Returns the number of attributes defined in the DTD.
       */
      public int getNumAttributes();
  
      /**
       * Returns the name of the kth attribute as defined in the DTD.
       *
       * It should return null if k is out of range (i.e. negative or greater than
       * getNumAttributes()).
       */
      public String getAttributeName(int k);
  
      /**
       * Returns the index of the given attribute. It returns -1 if the attribute
       * is not found. Relies on getNumAttributes() and getAttributeName().
       */
      public int lookupAttribute(String attr);
  
      /**
       * Returns true if the element supports the given attribute, whether currently set or not.
       */
      public boolean hasAttribute(String attr);
  
      /**
       * Returns the value of the kth attribute (i.e. the attribute with the name
       * getAttributeName(k)).
       *
       * It should return null if k is out of range (i.e. negative or greater than
       * getNumAttributes()).
       */
      public String getAttribute(int k);
  
      /**
       * Returns the value of the attribute with the given name.
       * Relies on lookupAttribute() and getAttribute().
       *
       * It returns null if the given attribute is not found.
       */
      public String getAttribute(String attr);
  
      /**
       * Sets the value of the kth attribute (i.e. the attribute with the name
       * getAttributeName(k)).
       *
       * If k is out of range (i.e. negative or greater than getNumAttributes()),
       * the call should be ignored.
       */
      public void setAttribute(int k, String value);
  
      /**
       * Sets the value of the attribute with the given name.
       * Relies on lookupAttribute() and setAttribute().
       *
       * If the given attribute is not found, the call has no effect.
       */
      public void setAttribute(String attr, String value);
  
      /**
       * Returns the default value of the kth attribute, as defined in the DTD.
       *
       * It should return null if k is out of range (i.e. negative or greater than
       * getNumAttributes()), or if the attribute is #REQUIRED; and return ""
       * if the attribute is #IMPLIED.
       */
      public String getAttributeDefault(int k);
  
      /**
       * Returns the default value of the given attribute, as defined in the DTD.
       * Relies on lookupAttribute() and getAttributeDefault().
       *
       * It returns null if the given attribute is not found.
       */
      public String getAttributeDefault(String attr);
  
      /**
       * Returns the parent element, or null if this element has no parent.
       */
      public INedElement getParent();
  
      /**
       * Returns the index'th child element. Throws ArrayIndexOutOfBoundsException
       * if the index is out of bounds (see getNumChildren()).
       */
      public INedElement getChild(int index);
  
      /**
       * Returns pointer to the first child element, or null if this element
       * has no children.
       */
      public INedElement getFirstChild();
  
      /**
       * Returns pointer to the last child element, or null if this element
       * has no children.
       */
      public INedElement getLastChild();
  
      /**
       * Returns pointer to the next sibling of this element (i.e. the next child
       * in the parent element). Returns null if there're no subsequent elements.
       *
       * getFirstChild() and getNextSibling() can be used to loop through
       * the child list:
       *
       * <pre>
       * for (INedElement *child=node.getFirstChild(); child; child = child.getNextSibling())
       * {
       *    ...
       * }
       * </pre>
       *
       */
      public INedElement getNextSibling();
  
      /**
       * Returns pointer to the previous sibling of this element (i.e. the previous child
       * in the parent element). Returns null if there're no elements before this one.
       */
      public INedElement getPrevSibling();
  
      /**
       * Appends the given element at the end of the child element list.
       *
       * The node pointer passed should not be null.
       */
      public void appendChild(INedElement node);
  
      /**
       * Inserts the given element just before the specified child element
       * in the child element list.
       *
       * The where element must be a child of this element. If where == NULL
       * the node is appended at the end of the list.
       * The node pointer passed should not be null.
       */
      public void insertChildBefore(INedElement where, INedElement node);
  
      /**
       * Removes the given element from the child element list.
       *
       * The pointer passed should be a child of this element.
       */
      public INedElement removeChild(INedElement node);
  
      /**
       * Removes all child elements from the element.
       */
      public void removeAllChildren();
  
      /**
       * Creates and returns a list containing the child elements.
       */
      public List<INedElement> getChildren();
  
      /**
       * Returns pointer to the first child element with the given tag code,
       * or null if this element has no such children.
       */
      public INedElement getFirstChildWithTag(int tagcode);
  
      /**
       * Returns pointer to the next sibling of this element with the given
       * tag code. Returns null if there's no such element.
       *
       * getFirstChildWithTag() and getNextSiblingWithTag() are a convenient way
       * to loop through elements with a certain tag code in the child list:
       *
       * <pre>
       * for (INedElement *child=node.getFirstChildWithTag(tagcode); child; child = child.getNextSiblingWithTag(tagcode))
       * {
       *     ...
       * }
       * </pre>
       */
      public INedElement getNextSiblingWithTag(int tagcode);
  
      /**
       * Returns pointer to the previous sibling of this element with the given
       * tag code. Returns null if there's no such element.
       */
      public INedElement getPreviousSiblingWithTag(int tagcode);
  
      /**
       * Creates and returns a list containing the child elements that have the given tagcode.
       */
      public List<INedElement> getChildrenWithTag(int tagcode);
  
      /**
       * Returns the number of child elements.
       */
      public int getNumChildren();
  
      /**
       * Returns the number of child elements with the given tag code.
       */
      public int getNumChildrenWithTag(int tagcode);
  
      /**
       * Returns find first child element with the give tagcode and the given
       * attribute (optionally) having the given value. Returns null if not found.
       */
      public INedElement getFirstChildWithAttribute(int tagcode, String attr,
              String attrvalue);
  
      /**
       * Climb up in the element tree until it finds an element with the given tagcode.
       * Returns null if not found and the element itself if it matches the tag immediately.
       */
      public INedElement getSelfOrAncestorWithTag(int tagcode);
  
      /**
       * Finds and returns the element with the given Id in this subtree, or null if not found.
       */
      public INedElement findElementWithId(long id);
  
      /**
       * Remove this node from the parent if it has one.
       */
      public void removeFromParent();
  
      /**
       * Returns whether this element has any child elements
       */
      public boolean hasChildren();
  
      /**
       * Derived classes can override this method to print extra transient information for debugging
       */
      public String debugString();
  
      /**
       * Creates a shallow copy of the node, for use in the default NED type resolver.
       * Equivalent to dup(NedElement.getDefaultNedTypeResolver(), false).
       * @see NedElement.getDefaultNedTypeResolver().
       */
      public INedElement dup();
  
      /**
       * Creates a shallow copy of the node, for use in the given target NED type resolver.
       * The rememberOriginal parameter controls whether the clone should store a pointer
       * back to the original element.
       * @see getOriginal()
       */
      public INedElement dup(INedTypeResolver targetResolver, boolean rememberOriginal, boolean cloneId);
  
      /**
       * Creates a deep copy of the tree, for use in the default NED type resolver.
       * Equivalent to deepDup(NedElement.getDefaultNedTypeResolver(), false).
       * @see NedElement.getDefaultNedTypeResolver().
       */
      public INedElement deepDup();
  
      /**
       * Creates a deep copy of the tree, for use in the given target NED type resolver.
       * The rememberOriginal parameter controls whether the clone should store a pointer
       * back to the original element.
       * @see getOriginal()
       */
      public INedElement deepDup(INedTypeResolver targetResolver, boolean rememberOriginal, boolean cloneId);
  
      /**
       * If this element was created by dup() or deepDup() called with rememberOriginal=true,
       * this method returns the INedElement that was cloned to produce this object;
       * otherwise it returns null.
       */
      public INedElement getOriginal();
  
      /**
       * Returns the first parent which is an INedTypeElement, or null. For example,
       * for a parameter it returns the container NED type; for a submodule node or a
       * submodule display string it finds the compound module; for an inner type it
       * returns the parent type; and for a toplevel type it returns null.
       */
      public INedTypeElement getEnclosingTypeElement();
  
      /**
       * Like getEnclosingTypeElement(), but for NED types (INedTypeElement) it returns itself.
       */
      public INedTypeElement getSelfOrEnclosingTypeElement();
  
      /**
       * Returns the (nearest) NedFileElementEx ancestor of this element (or the element itself
       * if called on NedFileElementEx), or null if not found.
       */
      public NedFileElementEx getContainingNedFileElement();
  
      /**
       * Returns the (nearest) MsgFileElementEx ancestor of this element (or the element itself
       * if called on MsgFileElementEx), or null if not found.
       */
      public MsgFileElementEx getContainingMsgFileElement();
  
      /**
       * Returns the nearest INedTypeLookupContext parent of the element. This will
       * be the containing compound module, or the NED file.
       */
      public INedTypeLookupContext getEnclosingLookupContext();
  
      /**
       * Adds a new NED change listener to the element. The
       * listener will receive notifications from the whole
       * NedElement subtree (i.e. this element and all elements
       * under it.
       */
      public void addNedChangeListener(INedChangeListener listener);
  
      /**
       * Removes a NED change listener from the element.
       */
      public void removeNedChangeListener(INedChangeListener listener);
  
      /**
       * Fires a model change element (forwards it to the listener list if any)
       * and propagates it up to the parent.
       */
      public void fireModelEvent(NedModelEvent event);
  
      /**
       * Returns the banner comment belonging to the element (if any)
       */
      public String getComment();
  
      /**
       * Returns the re-generated source (text form) of this element
       */
      public String getNedSource();
  
      /**
       * Clears stored syntax problem severities recursively on this subtree
       */
      public void clearSyntaxProblemMarkerSeverities();
  
      /**
       * Clears stored consistency problem severities recursively on this subtree
       */
      public void clearConsistencyProblemMarkerSeverities();
  
      /**
       * To be called when a syntax problem (error or warning) is detected for this
       * element. It invokes setSyntaxProblemMaxLocalSeverity(severity) if the new
       * is more severe than the currently stored maximum local severity, otherwise
       * it does nothing. Severity is one of the IMarker severity constants.
       */
      public void syntaxProblemMarkerAdded(int severity);
  
      /**
       * To be called when a consistency problem (error or warning) is detected for this
       * element. It invokes setConsistencyProblemMaxLocalSeverity(severity) if the new
       * is more severe than the currently stored maximum local severity, otherwise
       * it does nothing. Severity is one of the IMarker severity constants.
       */
      public void consistencyProblemMarkerAdded(int severity);
  
      /**
       * Sets the syntax problem max local severity to the given value.
       * Use IMarker severity constants or INedElement.SEVERITY_NONE.
       */
      public void setSyntaxProblemMaxLocalSeverity(int severity);
  
      /**
       * Sets the consistency problem max local severity to the given value.
       * Use IMarker severity constants or INedElement.SEVERITY_NONE.
       */
      public void setConsistencyProblemMaxLocalSeverity(int severity);
  
      /**
       * Returns the severity of the most severe syntax problem annotated onto
       * this element since error marker severities were last cleared.
       * Returns one of the IMarker severity constants or INedElement.SEVERITY_NONE.
       * @see clearSyntaxProblemMarkerSeverities(), syntaxProblemMarkerAdded()
       */
      public int getSyntaxProblemMaxLocalSeverity();
  
      /**
       * Returns the severity of the most severe consistency problem annotated onto
       * this element since error marker severities were last cleared.
       * Returns one of the IMarker severity constants or INedElement.SEVERITY_NONE.
       * @see clearConsistencyProblemMarkerSeverities(), consistencyProblemMarkerAdded()
       */
      public int getConsistencyProblemMaxLocalSeverity();
  
      /**
       * Returns the maximum of the local syntax problem max severities in this subtree.
       */
      public int getSyntaxProblemMaxCumulatedSeverity();
  
      /**
       * Returns the maximum of the local consistency problem max severities in this subtree.
       */
      public int getConsistencyProblemMaxCumulatedSeverity();
  
      /**
       * Convenience method: returns true if this element or any element below
       * contains a syntax error. Based on getSyntaxProblemMaxCumulatedSeverity().
       */
      public boolean hasSyntaxError();
  
      /**
       * Convenience method: returns true if this element or any element below
       * contains a consistency error. Based on getConsistencyProblemMaxCumulatedSeverity().
       */
      public boolean hasConsistencyError();
  
      /**
       * Convenience method: returns the maximum severity of syntax or consistency
       * problems on this element or any element below, i.e.
       * max(getSyntaxProblemMaxCumulatedSeverity(), getConsistencyProblemMaxCumulatedSeverity()).
       * The result is one of the IMarker severity constants or INedElement.SEVERITY_NONE.
       */
      public int getMaxProblemSeverity();
  }
  