001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 * 
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 * 
019 */
020package org.apache.directory.api.ldap.model.schema;
021
022
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.directory.api.i18n.I18n;
027
028
029/**
030 * Represents an LDAP MatchingRuleUseDescription defined in RFC 2252.
031 * <p>
032 * According to ldapbis [MODELS]:
033 * </p>
034 * 
035 * <pre>
036 *  Values of the matchingRuleUse list the attributes which are suitable
037 *  for use with an extensible matching rule.
038 * 
039 *    Matching rule use descriptions are written according to the following
040 *    ABNF:
041 * 
042 *      MatchingRuleUseDescription = LPAREN WSP
043 *          numericoid                ; object identifier
044 *          [ SP &quot;NAME&quot; SP qdescrs ]  ; short names (descriptors)
045 *          [ SP &quot;DESC&quot; SP qdstring ] ; description
046 *          [ SP &quot;OBSOLETE&quot; ]         ; not active
047 *          SP &quot;APPLIES&quot; SP oids      ; attribute types
048 *          extensions WSP RPAREN     ; extensions
049 * 
050 *    where:
051 *      [numericoid] is the object identifier of the matching rule
052 *          associated with this matching rule use description;
053 *      NAME [qdescrs] are short names (descriptors) identifying this
054 *          matching rule use;
055 *      DESC [qdstring] is a short descriptive string;
056 *      OBSOLETE indicates this matching rule use is not active;
057 *      APPLIES provides a list of attribute types the matching rule applies
058 *          to; and
059 *      [extensions] describe extensions.
060 * 
061 *  The matchingRule within the MatchingRuleUse definition can be used by an
062 *  extensible match assertion if the assertion is based on the attributes
063 *  listed within the MatchingRuleUse definition.  If an extensible match
064 *  assertion is based on attributes other than those listed within the
065 *  MatchingRuleUse definition then the assertion is deemed undefined.
066 * 
067 *  Also according to 3.3.20 of [SYNTAXES] (ldapbis working group):
068 * 
069 *  A value of the Matching Rule Use Description syntax indicates the
070 *  attribute types to which a matching rule may be applied in an
071 *  extensibleMatch search filter [PROT].  The LDAP-specific encoding of
072 *  a value of this syntax is defined by the &lt;MatchingRuleUseDescription&gt;
073 *  rule in [MODELS] above.
074 * </pre>
075 * 
076 * @see <a
077 *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
078 *      [MODELS]</a>
079 * @see <a
080 *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-syntaxes-09.txt">ldapbis
081 *      [SYNTAXES]</a>
082 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
083 */
084public class MatchingRuleUse extends AbstractSchemaObject
085{
086    /** The mandatory serialVersionUID */
087    public static final long serialVersionUID = 1L;
088
089    /** The list of attributes types OID the matching rule applies to */
090    private List<String> applicableAttributeOids;
091
092    /** The list of attributes types the matching rule applies to */
093    private List<AttributeType> applicableAttributes;
094
095
096    /**
097     * Creates a new instance of MatchingRuleUseDescription
098     */
099    public MatchingRuleUse( String oid )
100    {
101        super( SchemaObjectType.MATCHING_RULE_USE, oid );
102
103        applicableAttributeOids = new ArrayList<String>();
104        applicableAttributes = new ArrayList<AttributeType>();
105    }
106
107
108    /**
109     * @return The matchingRule's list of AttributeType OIDs the MRU applies to
110     */
111    public List<String> getApplicableAttributeOids()
112    {
113        return applicableAttributeOids;
114    }
115
116
117    /**
118     * @return The matchingRule's list of AttributeType OIDs the MRU applies to
119     */
120    public List<AttributeType> getApplicableAttributes()
121    {
122        return applicableAttributes;
123    }
124
125
126    /**
127     * Set the matchingRule's AttributeType OIDs the MRU applies to.
128     *
129     * @param applicableAttributeOids The AttributeType OIDs list
130     */
131    public void setApplicableAttributeOids( List<String> applicableAttributeOids )
132    {
133        if ( locked )
134        {
135            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
136        }
137
138        if ( !isReadOnly )
139        {
140            this.applicableAttributeOids = applicableAttributeOids;
141        }
142    }
143
144
145    /**
146     * Set the matchingRule's AttributeType the MRU applies to.
147     *
148     * @param applicableAttributes The AttributeType list
149     */
150    public void setApplicableAttributes( List<AttributeType> applicableAttributes )
151    {
152        if ( locked )
153        {
154            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
155        }
156
157        if ( !isReadOnly )
158        {
159            this.applicableAttributes = applicableAttributes;
160
161            // update the OIDS now
162            applicableAttributeOids.clear();
163
164            for ( AttributeType at : applicableAttributes )
165            {
166                applicableAttributeOids.add( at.getOid() );
167            }
168        }
169    }
170
171
172    /**
173     * Add a matchingRule's AttributeType OIDs the MRU applies to.
174     *
175     * @param oid A matchingRule's AttributeType OIDs the MRU applies to
176     */
177    public void addApplicableAttributeOids( String oid )
178    {
179        if ( locked )
180        {
181            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
182        }
183
184        if ( !isReadOnly && !applicableAttributeOids.contains( oid ) )
185        {
186            applicableAttributeOids.add( oid );
187        }
188    }
189
190
191    /**
192     * Add a matchingRule's AttributeType the MRU applies to.
193     *
194     * @param attributeType A matchingRule's AttributeType the MRU applies to
195     */
196    public void addApplicableAttribute( AttributeType attributeType )
197    {
198        if ( locked )
199        {
200            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
201        }
202
203        if ( !isReadOnly && !applicableAttributeOids.contains( attributeType.getOid() ) )
204        {
205            applicableAttributes.add( attributeType );
206            applicableAttributeOids.add( attributeType.getOid() );
207        }
208    }
209
210
211    /**
212     * @see Object#toString()
213     */
214    public String toString()
215    {
216        return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
217    }
218
219
220    /**
221     * Copy an MatchingRuleUse
222     */
223    public MatchingRuleUse copy()
224    {
225        MatchingRuleUse copy = new MatchingRuleUse( oid );
226
227        // Copy the SchemaObject common data
228        copy.copy( this );
229
230        // Clone the APPLY AttributeTypes
231        copy.applicableAttributeOids = new ArrayList<String>();
232
233        // Copy the APPLIES oid list
234        for ( String oid : applicableAttributeOids )
235        {
236            copy.applicableAttributeOids.add( oid );
237        }
238
239        // Copy the APPLIES list (will be empty)
240        copy.applicableAttributes = new ArrayList<AttributeType>();
241
242        return copy;
243    }
244
245
246    /**
247     * @see Object#equals(Object)
248     */
249    @Override
250    public boolean equals( Object o )
251    {
252        if ( !super.equals( o ) )
253        {
254            return false;
255        }
256
257        if ( !( o instanceof MatchingRuleUse ) )
258        {
259            return false;
260        }
261
262        @SuppressWarnings("unused")
263        MatchingRuleUse that = ( MatchingRuleUse ) o;
264
265        // TODO : complete the checks
266        return true;
267    }
268
269
270    /**
271     * {@inheritDoc}
272     */
273    public void clear()
274    {
275        // Clear the common elements
276        super.clear();
277
278        // Clear the references
279        applicableAttributes.clear();
280        applicableAttributeOids.clear();
281    }
282}