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    package org.opends.server.tools.makeldif;
028    
029    
030    
031    import java.util.List;
032    import java.util.Random;
033    
034    import org.opends.server.types.InitializationException;
035    
036    import static org.opends.messages.ToolMessages.*;
037    import org.opends.messages.Message;
038    
039    
040    /**
041     * This class defines a tag that may be used to select a value from a
042     * pre-defined list, optionally defining weights for each value that can impact
043     * the likelihood of a given item being selected.  The itemts to include in the
044     * list should be specified as arguments to the tag.  If the argument ends with
045     * a semicolon followed by an integer, then that will be the weight for that
046     * particular item.  If no weight is given, then the weight for that item will
047     * be assumed to be one.
048     */
049    public class ListTag
050           extends Tag
051    {
052      // The ultimate cumulative weight.
053      private int cumulativeWeight;
054    
055      // The set of cumulative weights for the list items.
056      private int[] valueWeights;
057    
058      // The set of values in the list.
059      private String[] valueStrings;
060    
061      // The random number generator for this tag.
062      private Random random;
063    
064    
065    
066      /**
067       * Creates a new instance of this list tag.
068       */
069      public ListTag()
070      {
071        // No implementation required.
072      }
073    
074    
075    
076      /**
077       * Retrieves the name for this tag.
078       *
079       * @return  The name for this tag.
080       */
081      public String getName()
082      {
083        return "List";
084      }
085    
086    
087    
088      /**
089       * Indicates whether this tag is allowed for use in the extra lines for
090       * branches.
091       *
092       * @return  <CODE>true</CODE> if this tag may be used in branch definitions,
093       *          or <CODE>false</CODE> if not.
094       */
095      public boolean allowedInBranch()
096      {
097        return true;
098      }
099    
100    
101    
102      /**
103       * Performs any initialization for this tag that may be needed while parsing
104       * a branch definition.
105       *
106       * @param  templateFile  The template file in which this tag is used.
107       * @param  branch        The branch in which this tag is used.
108       * @param  arguments     The set of arguments provided for this tag.
109       * @param  lineNumber    The line number on which this tag appears in the
110       *                       template file.
111       * @param  warnings      A list into which any appropriate warning messages
112       *                       may be placed.
113       *
114       * @throws  InitializationException  If a problem occurs while initializing
115       *                                   this tag.
116       */
117      public void initializeForBranch(TemplateFile templateFile, Branch branch,
118                                      String[] arguments, int lineNumber,
119                                      List<Message> warnings)
120             throws InitializationException
121      {
122        initializeInternal(templateFile, arguments, lineNumber, warnings);
123      }
124    
125    
126    
127      /**
128       * Performs any initialization for this tag that may be needed while parsing
129       * a template definition.
130       *
131       * @param  templateFile  The template file in which this tag is used.
132       * @param  template      The template in which this tag is used.
133       * @param  arguments     The set of arguments provided for this tag.
134       * @param  lineNumber    The line number on which this tag appears in the
135       *                       template file.
136       * @param  warnings      A list into which any appropriate warning messages
137       *                       may be placed.
138       *
139       * @throws  InitializationException  If a problem occurs while initializing
140       *                                   this tag.
141       */
142      public void initializeForTemplate(TemplateFile templateFile,
143                                        Template template, String[] arguments,
144                                        int lineNumber, List<Message> warnings)
145             throws InitializationException
146      {
147        initializeInternal(templateFile, arguments, lineNumber, warnings);
148      }
149    
150    
151    
152      /**
153       * Performs any initialization for this tag that may be needed for this tag.
154       *
155       * @param  templateFile  The template file in which this tag is used.
156       * @param  arguments     The set of arguments provided for this tag.
157       * @param  lineNumber    The line number on which this tag appears in the
158       *                       template file.
159       * @param  warnings      A list into which any appropriate warning messages
160       *                       may be placed.
161       *
162       * @throws  InitializationException  If a problem occurs while initializing
163       *                                   this tag.
164       */
165      private void initializeInternal(TemplateFile templateFile, String[] arguments,
166                                      int lineNumber, List<Message> warnings)
167              throws InitializationException
168      {
169        if (arguments.length == 0)
170        {
171          throw new InitializationException(
172                  ERR_MAKELDIF_TAG_LIST_NO_ARGUMENTS.get(lineNumber));
173        }
174    
175    
176        valueStrings     = new String[arguments.length];
177        valueWeights     = new int[arguments.length];
178        cumulativeWeight = 0;
179        random           = templateFile.getRandom();
180    
181        for (int i=0; i < arguments.length; i++)
182        {
183          String s = arguments[i];
184    
185          int weight = 1;
186          int semicolonPos = s.lastIndexOf(';');
187          if (semicolonPos >= 0)
188          {
189            try
190            {
191              weight = Integer.parseInt(s.substring(semicolonPos+1));
192              s = s.substring(0, semicolonPos);
193            }
194            catch (Exception e)
195            {
196              warnings.add(WARN_MAKELDIF_TAG_LIST_INVALID_WEIGHT.get(
197                              lineNumber,s));
198            }
199          }
200    
201          cumulativeWeight += weight;
202          valueStrings[i] = s;
203          valueWeights[i] = cumulativeWeight;
204        }
205      }
206    
207    
208    
209      /**
210       * Generates the content for this tag by appending it to the provided tag.
211       *
212       * @param  templateEntry  The entry for which this tag is being generated.
213       * @param  templateValue  The template value to which the generated content
214       *                        should be appended.
215       *
216       * @return  The result of generating content for this tag.
217       */
218      public TagResult generateValue(TemplateEntry templateEntry,
219                                     TemplateValue templateValue)
220      {
221        int selectedWeight = random.nextInt(cumulativeWeight) + 1;
222        for (int i=0; i < valueWeights.length; i++)
223        {
224          if (selectedWeight <= valueWeights[i])
225          {
226            templateValue.getValue().append(valueStrings[i]);
227            break;
228          }
229        }
230    
231    
232        return TagResult.SUCCESS_RESULT;
233      }
234    }
235