001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2008 Sun Microsystems, Inc.
015 * Portions Copyright 2013-2016 ForgeRock AS.
016 */
017package org.opends.server.types;
018
019import org.forgerock.opendj.ldap.schema.AttributeType;
020
021import java.util.LinkedHashMap;
022import java.util.LinkedHashSet;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026
027import org.forgerock.i18n.slf4j.LocalizedLogger;
028import org.forgerock.opendj.ldap.schema.MatchingRule;
029
030import static org.forgerock.util.Reject.*;
031import static org.opends.server.util.ServerConstants.*;
032
033/**
034 * This class defines a data structure for storing and interacting
035 * with a matching rule use definition, which may be used to restrict
036 * the set of attribute types that may be used for a given matching
037 * rule.
038 */
039@org.opends.server.types.PublicAPI(
040     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
041     mayInstantiate=false,
042     mayExtend=false,
043     mayInvoke=true)
044public final class MatchingRuleUse
045       implements SchemaFileElement
046{
047  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
048
049  /** Indicates whether this matching rule use is declared "obsolete". */
050  private final boolean isObsolete;
051
052  /**
053   * The set of additional name-value pairs associated with this
054   * matching rule use definition.
055   */
056  private final Map<String,List<String>> extraProperties;
057
058  /**
059   * The set of names that may be used to refer to this matching rule
060   * use, mapped between their all-lowercase representations and the
061   * user-defined representations.
062   */
063  private final Map<String,String> names;
064
065  /**
066   * The matching rule with which this matching rule use is associated.
067   */
068  private final MatchingRule matchingRule;
069
070  /**
071   * The set of attribute types with which this matching rule use is associated.
072   */
073  private final Set<AttributeType> attributes;
074
075  /** The definition string used to create this matching rule use. */
076  private final String definition;
077
078  /** The description for this matching rule use. */
079  private final String description;
080
081
082
083  /**
084   * Creates a new matching rule use definition with the provided
085   * information.
086   *
087   * @param  definition       The definition string used to create
088   *                          this matching rule use.  It must not be
089   *                          {@code null}.
090   * @param  matchingRule     The matching rule for this matching rule
091   *                          use.  It must not be {@code null}.
092   * @param  names            The set of names for this matching rule
093   *                          use.
094   * @param  description      The description for this matching rule
095   *                          use.
096   * @param  isObsolete       Indicates whether this matching rule use
097   *                          is declared "obsolete".
098   * @param  attributes       The set of attribute types for this
099   *                          matching rule use.
100   * @param  extraProperties  A set of "extra" properties that may be
101   *                          associated with this matching rule use.
102   */
103  public MatchingRuleUse(String definition, MatchingRule matchingRule,
104                         Map<String,String> names, String description,
105                         boolean isObsolete,
106                         Set<AttributeType> attributes,
107                         Map<String,List<String>> extraProperties)
108  {
109    ifNull(definition, matchingRule);
110
111    this.matchingRule = matchingRule;
112    this.description  = description;
113    this.isObsolete   = isObsolete;
114
115    int schemaFilePos = definition.indexOf(SCHEMA_PROPERTY_FILENAME);
116    if (schemaFilePos > 0)
117    {
118      String defStr;
119      try
120      {
121        int firstQuotePos = definition.indexOf('\'', schemaFilePos);
122        int secondQuotePos = definition.indexOf('\'',
123                                                firstQuotePos+1);
124
125        defStr = definition.substring(0, schemaFilePos).trim() + " " +
126                 definition.substring(secondQuotePos+1).trim();
127      }
128      catch (Exception e)
129      {
130        logger.traceException(e);
131
132        defStr = definition;
133      }
134
135      this.definition = defStr;
136    }
137    else
138    {
139      this.definition = definition;
140    }
141
142    if (names == null || names.isEmpty())
143    {
144      this.names = new LinkedHashMap<>(0);
145    }
146    else
147    {
148      this.names = new LinkedHashMap<>(names);
149    }
150
151    if (attributes == null || attributes.isEmpty())
152    {
153      this.attributes = new LinkedHashSet<>(0);
154    }
155    else
156    {
157      this.attributes = new LinkedHashSet<>(attributes);
158    }
159
160    if (extraProperties == null || extraProperties.isEmpty())
161    {
162      this.extraProperties = new LinkedHashMap<>(0);
163    }
164    else
165    {
166      this.extraProperties = new LinkedHashMap<>(extraProperties);
167    }
168  }
169
170
171
172  /**
173   * Retrieves the matching rule for this matching rule use.
174   *
175   * @return  The matching rule for this matching rule use.
176   */
177  public MatchingRule getMatchingRule()
178  {
179    return matchingRule;
180  }
181
182
183
184  /**
185   * Retrieves the set of names for this matching rule use.  The
186   * mapping will be between the names in all lowercase form and the
187   * names in the user-defined form.
188   *
189   * @return  The set of names for this matching rule use.
190   */
191  public Map<String,String> getNames()
192  {
193    return names;
194  }
195
196
197
198  /**
199   * Retrieves the primary name to use when referencing this matching
200   * rule use.
201   *
202   * @return  The primary name to use when referencing this matching
203   *          rule use, or {@code null} if there is none.
204   */
205  public String getNameOrOID()
206  {
207    if (names.isEmpty())
208    {
209      return null;
210    }
211    else
212    {
213      return names.values().iterator().next();
214    }
215  }
216
217
218
219  /**
220   * Indicates whether this matching rule use has the specified name.
221   *
222   * @param  lowerName  The name for which to make the determination,
223   *                    formatted in all lowercase characters.
224   *
225   * @return  {@code true} if this matching rule use has the specified
226   *          name, or {@code false} if not.
227   */
228  public boolean hasName(String lowerName)
229  {
230    return names.containsKey(lowerName);
231  }
232
233
234
235  /**
236   * Retrieves the description for this matching rule use.
237   *
238   * @return  The description for this matching rule use, or
239   *          {@code null} if there is none.
240   */
241  public String getDescription()
242  {
243    return description;
244  }
245
246
247
248  /**
249   * Indicates whether this matching rule use is declared "obsolete".
250   *
251   * @return  {@code true} if this matching rule use is declared
252   *          "obsolete", or {@code false} if it is not.
253   */
254  public boolean isObsolete()
255  {
256    return isObsolete;
257  }
258
259
260
261  /**
262   * Retrieves the set of attributes associated with this matching
263   * rule use.
264   *
265   * @return  The set of attributes associated with this matching
266   *          rule use.
267   */
268  public Set<AttributeType> getAttributes()
269  {
270    return attributes;
271  }
272
273
274
275  /**
276   * Indicates whether the provided attribute type is referenced by
277   * this matching rule use.
278   *
279   * @param  attributeType  The attribute type for which to make the
280   *                        determination.
281   *
282   * @return  {@code true} if the provided attribute type is
283   *          referenced by this matching rule use, or {@code false}
284   *          if it is not.
285   */
286  boolean appliesToAttribute(AttributeType attributeType)
287  {
288    return attributes.contains(attributeType);
289  }
290
291
292
293  /**
294   * Retrieves a mapping between the names of any extra non-standard
295   * properties that may be associated with this matching rule use and
296   * the value for that property.
297   *
298   * @return  A mapping between the names of any extra non-standard
299   *          properties that may be associated with this matching
300   *          rule use and the value for that property.
301   */
302  @Override
303  public Map<String,List<String>> getExtraProperties()
304  {
305    return extraProperties;
306  }
307
308
309
310  /**
311   * Indicates whether the provided object is equal to this matching
312   * rule use.  The object will be considered equal if it is a
313   * matching rule use with the same matching rule.
314   *
315   * @param  o  The object for which to make the determination.
316   *
317   * @return  {@code true} if the provided object is equal to this
318   *          matching rule use, or {@code false} if not.
319   */
320  @Override
321  public boolean equals(Object o)
322  {
323    if (this == o)
324    {
325      return true;
326    }
327    if (!(o instanceof MatchingRuleUse))
328    {
329      return false;
330    }
331    return matchingRule.equals(((MatchingRuleUse) o).matchingRule);
332  }
333
334
335
336  /**
337   * Retrieves the hash code for this matching rule use.  It will be
338   * equal to the hash code for the associated matching rule.
339   *
340   * @return  The hash code for this matching rule use.
341   */
342  @Override
343  public int hashCode()
344  {
345    return matchingRule.hashCode();
346  }
347
348
349
350  /**
351   * Retrieves the string representation of this matching rule use in
352   * the form specified in RFC 2252.
353   *
354   * @return  The string representation of this matching rule use in
355   *          the form specified in RFC 2252.
356   */
357  @Override
358  public String toString()
359  {
360    return definition;
361  }
362
363}