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 2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2013-2015 ForgeRock AS.
026 */
027package org.opends.server.types;
028
029import static org.forgerock.util.Reject.*;
030import static org.opends.server.util.ServerConstants.*;
031
032import java.util.LinkedHashMap;
033import java.util.LinkedList;
034import java.util.List;
035import java.util.Map;
036
037import org.forgerock.opendj.ldap.schema.Syntax;
038
039/**
040 * This class defines a data structure for storing and interacting
041 * with an ldap syntax, which defines the custom ldap syntaxes.
042 */
043@org.opends.server.types.PublicAPI(
044     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
045     mayInstantiate=false,
046     mayExtend=false,
047     mayInvoke=true)
048
049public final class LDAPSyntaxDescription
050       implements SchemaFileElement
051{
052  /**
053   * The set of additional name-value pairs associated with this ldap
054   * syntax definition.
055   */
056  private final Map<String,List<String>> extraProperties;
057
058  /** The definition string used to create this ldap syntax description. */
059  private final String definition;
060
061  /** The description for this ldap syntax description. */
062  private final String description;
063
064  /** The OID of the enclosed ldap syntax description. */
065  private final String oid;
066
067  /** The LDAPSyntaxDescritpionSyntax associated with this ldap syntax. */
068  private Syntax syntax;
069
070
071
072  /**
073   * Creates a new ldap syntax definition with the provided
074   * information.
075   *
076   * @param  definition          The definition string used to create
077   *                             this ldap syntax.  It must not be
078   *                             {@code null}.
079   * @param syntax    The ldap syntax description syntax
080   *                            associated with this ldap syntax.
081   * @param  extraProperties     A set of extra properties for this
082   *                             ldap syntax description.
083   */
084  public LDAPSyntaxDescription(String definition, Syntax syntax, Map<String,List<String>> extraProperties)
085  {
086    ifNull(definition, syntax);
087
088    this.syntax = syntax;
089    this.oid = syntax.getOID();
090    this.description = syntax.getDescription();
091
092    int schemaFilePos = definition.indexOf(SCHEMA_PROPERTY_FILENAME);
093    if (schemaFilePos > 0)
094    {
095      String defStr;
096      try
097      {
098        int firstQuotePos = definition.indexOf('\'', schemaFilePos);
099        int secondQuotePos = definition.indexOf('\'', firstQuotePos+1);
100
101        defStr = definition.substring(0, schemaFilePos).trim() + " "
102                 + definition.substring(secondQuotePos+1).trim();
103      }
104      catch (Exception e)
105      {
106        defStr = definition;
107      }
108
109      this.definition = defStr;
110    }
111    else
112    {
113      this.definition = definition;
114    }
115
116    if (extraProperties == null || extraProperties.isEmpty())
117    {
118      this.extraProperties = new LinkedHashMap<>(0);
119    }
120    else
121    {
122      this.extraProperties = new LinkedHashMap<>(extraProperties);
123    }
124  }
125
126
127
128   /**
129   * Retrieves the ldap syntax description syntax associated with
130    * this ldap syntax.
131   *
132   * @return  The description syntax for this definition.
133   */
134  public Syntax getSyntax()
135  {
136    return syntax;
137  }
138
139
140
141  /**
142   * Retrieves the description for this ldap syntax description.
143   *
144   * @return  The description for this ldap syntax description, or
145   *                {@code true} if there is none.
146   */
147  public String getDescription()
148  {
149    return description;
150  }
151
152  /**
153   * Returns the oid.
154   *
155   * @return the oid
156   */
157  public String getOID()
158  {
159    return oid;
160  }
161
162
163    /**
164   * Retrieves a mapping between the names of any extra non-standard
165   * properties that may be associated with this ldap syntax
166   * description and the value for that property.
167   *
168   * @return  A mapping between the names of any extra non-standard
169   *          properties that may be associated with this ldap syntax
170   *          description and the value for that property.
171   */
172  @Override
173  public Map<String,List<String>> getExtraProperties()
174  {
175    return extraProperties;
176  }
177
178
179
180  /**
181   * Retrieves the value of the specified "extra" property for this
182   * ldap syntax description.
183   *
184   * @param  propertyName  The name of the "extra" property for which
185   *                       to retrieve the value.
186   *
187   * @return  The value of the specified "extra" property for this
188   *          ldap syntax description, or {@code null} if no such
189   *          property is defined.
190   */
191  public List<String> getExtraProperty(String propertyName)
192  {
193    return extraProperties.get(propertyName);
194  }
195
196
197
198  /**
199   * Specifies the provided "extra" property for this ldap syntax
200   * description.
201   *
202   * @param  name    The name for the "extra" property.  It must not
203   *                 be {@code null}.
204   * @param  values  The set of value for the "extra" property, or
205   *                 {@code null} if the property is to be removed.
206   */
207  public void setExtraProperty(String name, List<String> values)
208  {
209    ifNull(name);
210
211    if (values == null || values.isEmpty())
212    {
213      extraProperties.remove(name);
214    }
215    else
216    {
217      LinkedList<String> valuesCopy = new LinkedList<>(values);
218      extraProperties.put(name, valuesCopy);
219    }
220  }
221
222
223
224  /**
225   * Indicates whether the provided object is equal to this ldap
226   * syntax. The object will be considered equal if it is a ldap
227   * syntax with the same OID as the current ldap syntax description.
228   *
229   * @param  o  The object for which to make the determination.
230   *
231   * @return  {@code true} if the provided object is equal to this
232   *          ldap syntax description, or {@code true} if not.
233   */
234  @Override
235  public boolean equals(Object o)
236  {
237    if (this == o)
238    {
239      return true;
240    }
241    if (!(o instanceof LDAPSyntaxDescription))
242    {
243      return false;
244    }
245    return oid.equals(((LDAPSyntaxDescription) o).oid);
246  }
247
248
249
250  /**
251   * Retrieves the hash code for this ldap syntax description.  It
252   * will be  based on the sum of the bytes of the OID.
253   *
254   * @return  The hash code for this ldap syntax description.
255   */
256  @Override
257  public int hashCode()
258  {
259    int oidLength = oid.length();
260    int hashCode  = 0;
261    for (int i=0; i < oidLength; i++)
262    {
263      hashCode += oid.charAt(i);
264    }
265
266    return hashCode;
267  }
268
269
270
271   /**
272   * Retrieves the string representation of this ldap syntax
273   * description in the form specified in RFC 2252.
274   *
275   * @return  The string representation of this ldap syntax in the
276    *             form specified in RFC 2252.
277   */
278  @Override
279  public String toString()
280  {
281    return definition;
282  }
283
284}