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.inifile.editor.model;
  
  
  /**
   * An interface for high-level manipulation of the contents of an ini file
   * (as sections and entries).
   *
   * This interface does not try to make sense of section names, key names
   * and values -- they are just treated as strings. Additional layer(s)
   * may be needed to deal with these details.
   *
   * Some entries may not be editable (i.e. they are readonly), because they
   * come from included ini files, or for some other reason. It it an error
   * to try to modify or remove these entries.
   *
   * This interface assumes that within a section, keys are unique (i.e. multiple
   * appearances of the same key should be flagged as an error during parsing.)
   * If there're non-unique keys, behavior is undefined: this interface
   * should not be used until this condition gets resolved.
   *
   * Note: it is not possible to distinguish multiple sections of the same name
   * (i.e. a non-contiguous section): this interface presents them as a single section.
   *
   * @author Andras
   */
  public interface IInifileDocument extends IReadonlyInifileDocument {
  
      /**
       * Sets the value of the given entry. Throws error if key does not exist
       * in that section, or it is readonly.
       */
      void setRawValue(String section, String key, String value);
  
      /**
       * Creates a new entry. Throws error if already exists, or section or beforeKey does not exist.
       * @param comment should be "", or include the leading "#" and potential preceding whitespace
       * @param beforeKey may be null (meaning append)
       */
      void addEntry(String section, String key, String value, String rawComment, String beforeKey);
  
      /**
       * Creates several new entries in one operation. If any of the keys already exists,
       * the method throws an exception without changing the document. Also throws exception
       * when section or beforeKey does not exist, or any of the arrays are wrong (see below).
       * @param keys  may not be null or contain nulls
       * @param values may be null; when non-null, size must match keys[] and may contain nulls
       * @param rawComments may be null; when non-null, size must match keys[] and may contain nulls
       * @param beforeKey may be null (meaning append)
       */
      void addEntries(String section, String[] keys, String[] values, String[] rawComments, String beforeKey);
  
      /**
       * Sets the comment for an entry. Specify null to remove the comment.
       * The comment should be passed without the leading "# " or "#".
       * Note: "" means empty comment ("#" followed by nothing.)
       * Throws error if key doesn't exist, or the entry is readonly.
       */
      void setComment(String section, String key, String comment);
  
      /**
       * Sets the comment for an entry. The comment should be passed with
       * the leading "#" and preceding whitespace. Specify "" to
       * remove the comment (null is not accepted).
       * Throws error if key doesn't exist, the entry is readonly.
       */
      void setRawComment(String section, String key, String comment);
  
      /**
       * Renames the given key. Throws error if key doesn't exist, or the entry is readonly.
       */
      void renameKey(String section, String oldKey, String newKey);
  
      /**
       * Removes the given key from the given section. Nothing happens if it's not there.
       * Throws an error if this entry is not editable (readonly).
       */
      void removeKey(String section, String key);
  
      /**
       * Batch operation: removes the given entries in one go. The sections[] and keys[]
       * arrays must be the same size, and must not contain nulls.
       */
      void removeKeys(String[] sections, String keys[]);
  
      /**
       * Moves the given key before the given one. Throws error if the entry does
       * not exist, or beforeKey does not exist.
       * @param comment may be null
       * @param beforeKey may be null (meaning append)
       */
      void moveKey(String section, String key, String beforeKey);
  
      /**
       * Removes all sections with that name. If there's no such section, nothing happens.
       * If some parts are in included files (i.e. readonly parts), those parts are
       * not skipped, and an exception is thrown at the end of the operation.
       */
      void removeSection(String section);
  
      /**
       * Adds a section. Throws an error if such section already exists.
       * (This effectively means that this interface does not support creating
       * and populating non-contiguous sections).  beforeSection==null means
       * append.
       */
      void addSection(String sectionName, String beforeSection);
  
      /**
       * Renames a section. Throws an error if a section with the new name
       * already exists.
       */
      void renameSection(String sectionName, String newName);
  
      /**
       * Sets the comment on the section heading's line.
       * Sets the comment of the first heading if there're more than one.
       * The comment should be passed without the leading "# " or "#";
       * specify null to remove the comment.
       * Note: "" means empty comment ("#" followed by nothing.)
       * Throws error if section doesn't exist, or if the section heading line
       * is readonly.
       */
      void setSectionComment(String section, String comment);
  
      /**
       * Sets the comment on the section heading's line.
       * Sets the comment of the first heading if there're more than one.
       * The comment should be passed with the leading "#" and preceding whitespace.
       * Specify "" to remove the comment (null is not accepted.)
       * Throws error if section doesn't exist, or if the section heading line
       * is readonly.
       */
      void setRawSectionComment(String section, String comment);
  
      /**
       * Performs basic syntactic validation on the section name string
       * (not empty, contains no illegal characters, etc).
       * @return null if no problem, otherwise the description of the problem
       */
      String validateSectionName(String section);
  
      /**
       * Performs basic syntactic validation on the key string (not empty,
       * contains no illegal characters, etc).
       * @return null if no problem, otherwise the description of the problem
       */
      String validateKey(String key);
  
      /**
       * Returns the included files at the top of the primary (edited) file.
       * Other includes are not returned.
       */
      String[] getTopIncludes();
  
      /**
       * Adds an include at the top of the file.
       * @param beforeInclude specify null to append
       */
      void addTopInclude(String include, String beforeInclude);
  
      /**
       * Removes the given include. Throws error if include does not exist.
       */
      void removeTopInclude(String include);
  
      /**
       * Returns the included files at the bottom of the primary (edited) file.
       * Other includes are not returned.
       */
      String[] getBottomIncludes();
  
      /**
       * Adds an include at the bottom of the file.
       * @param beforeInclude specify null to append
       */
      void addBottomInclude(String include, String before);
  
      /**
       * Removes the given include. Throws error if include does not exist.
       */
      void removeBottomInclude(String include);
  
      /**
       * Attach a (single, unnamed) user data object to the given key.
       */
      void setKeyData(String section, String key, Object data);
  
      /**
       * Attach a (single, unnamed) user data object to the given section.
       */
      void setSectionData(String section, Object data);
  
      /**
       * Adds a listener to this document
       */
      void addInifileChangeListener(IInifileChangeListener listener);
  
      /**
       * Removes a listener from this document
       */
      void removeInifileChangeListener(IInifileChangeListener listener);
  
      /**
       * Creates a read-only copy of this ini file.
       * The copy is cached and returned until this document has not been changed.
       */
      IReadonlyInifileDocument getImmutableCopy();
  
      /**
       * Checks if the given copy is the current one.
       */
      boolean isImmutableCopyUpToDate(IReadonlyInifileDocument copy);
  
      /**
       * Called when the editor is closed to allow freeing resources.
       */
      void dispose();
  
      /**
       * Force parsing the document now.
       */
      void parse();
  }
  