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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.tools.makeldif;
028
029
030
031import java.util.List;
032import java.util.Random;
033
034import org.opends.server.types.InitializationException;
035
036import static org.opends.messages.ToolMessages.*;
037import org.forgerock.i18n.LocalizableMessage;
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 */
049public 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<LocalizableMessage> 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<LocalizableMessage> 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<LocalizableMessage> 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