001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2008 Sun Microsystems, Inc.
026     */
027    
028    package org.opends.server.util.args;
029    
030    import org.opends.messages.Message;
031    
032    import java.util.List;
033    import java.util.LinkedList;
034    import java.util.Collections;
035    import java.util.Iterator;
036    
037    /**
038     * Class for organizing options into logical groups when arguement
039     * usage is printed.  To use an argument group, create an instance
040     * and use {@link org.opends.server.util.args.ArgumentParser
041     * #addArgument(Argument, ArgumentGroup)} when adding arguments for
042     * to the parser.
043     */
044    public class ArgumentGroup implements Comparable<ArgumentGroup> {
045    
046      // Description for this group of arguments
047      private Message description = null;
048    
049      // List of arguments belonging to this group
050      private List<Argument> args = null;
051    
052      // Governs groups position within usage statement
053      private Integer priority;
054    
055      /**
056       * Creates a parameterized instance.
057       *
058       * @param description for options in this group that is printed before
059       *        argument descriptions in usage output
060       * @param priority number governing the position of this group within
061       *        the usage statement.  Groups with higher priority values appear
062       *        before groups with lower priority.
063       */
064      public ArgumentGroup(Message description, int priority) {
065        this.description = description;
066        this.priority = priority;
067        this.args = new LinkedList<Argument>();
068      }
069    
070      /**
071       * Gets the description for this group of arguments.
072       *
073       * @return description for this argument group
074       */
075      public Message getDescription() {
076        return this.description;
077      }
078    
079      /**
080       * Sets the description for this group of arguments.
081       *
082       * @param description for this argument group
083       */
084      public void setDescription(Message description) {
085        this.description = description;
086      }
087    
088      /**
089       * Gets the list of arguments associated with this group.
090       *
091       * @return list of associated arguments
092       */
093      List<Argument> getArguments() {
094        return Collections.unmodifiableList(args);
095      }
096    
097      /**
098       * {@inheritDoc}
099       */
100      public int compareTo(ArgumentGroup o)
101      {
102        // Groups with higher priority numbers appear before
103        // those with lower priority in the usage output
104        return -1 * priority.compareTo(o.priority);
105      }
106    
107      /**
108       * Indicates whether this group contains any members.
109       *
110       * @return boolean where true means this group contains members
111       */
112      boolean containsArguments()
113      {
114        return this.args.size() > 0;
115      }
116    
117    
118      /**
119       * Indicates whether this group contains any non-hidden members.
120       *
121       * @return boolean where true means this group contains non-hidden members
122       */
123      boolean containsNonHiddenArguments()
124      {
125        for (Argument arg : args)
126        {
127          if (!arg.isHidden())
128          {
129            return true;
130          }
131        }
132        return false;
133      }
134    
135    
136      /**
137       * Adds an argument to this group.
138       *
139       * @param arg to add
140       * @return boolean where true indicates the add was successful
141       */
142      boolean addArgument(Argument arg) {
143        boolean success = false;
144        if (arg != null) {
145          Character newShort = arg.getShortIdentifier();
146          String newLong = arg.getLongIdentifier();
147    
148          // See if there is already an argument in this group that the
149          // new argument should replace
150          for (Iterator<Argument> it = this.args.iterator(); it.hasNext();)
151          {
152            Argument a = it.next();
153            if (newShort != null && newShort.equals(a.getShortIdentifier()) ||
154                    newLong != null && newLong.equals(a.getLongIdentifier())) {
155              it.remove();
156              break;
157            }
158          }
159    
160          success = this.args.add(arg);
161        }
162        return success;
163      }
164    
165      /**
166       * Removes an argument from this group.
167       *
168       * @param arg to remove
169       * @return boolean where true indicates the remove was successful
170       */
171      boolean removeArgument(Argument arg) {
172        return this.args.remove(arg);
173      }
174    
175    }