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     * @param oid the MatchingRuleUse's OID
100     */
101    public MatchingRuleUse( String oid )
102    {
103        super( SchemaObjectType.MATCHING_RULE_USE, oid );
104
105        applicableAttributeOids = new ArrayList<>();
106        applicableAttributes = new ArrayList<>();
107    }
108
109
110    /**
111     * @return The matchingRule's list of AttributeType OIDs the MRU applies to
112     */
113    public List<String> getApplicableAttributeOids()
114    {
115        return applicableAttributeOids;
116    }
117
118
119    /**
120     * @return The matchingRule's list of AttributeType OIDs the MRU applies to
121     */
122    public List<AttributeType> getApplicableAttributes()
123    {
124        return applicableAttributes;
125    }
126
127
128    /**
129     * Set the matchingRule's AttributeType OIDs the MRU applies to.
130     *
131     * @param applicableAttributeOids The AttributeType OIDs list
132     */
133    public void setApplicableAttributeOids( List<String> applicableAttributeOids )
134    {
135        if ( locked )
136        {
137            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
138        }
139
140        if ( !isReadOnly )
141        {
142            this.applicableAttributeOids = applicableAttributeOids;
143        }
144    }
145
146
147    /**
148     * Set the matchingRule's AttributeType the MRU applies to.
149     *
150     * @param applicableAttributes The AttributeType list
151     */
152    public void setApplicableAttributes( List<AttributeType> applicableAttributes )
153    {
154        if ( locked )
155        {
156            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
157        }
158
159        if ( !isReadOnly )
160        {
161            this.applicableAttributes = applicableAttributes;
162
163            // update the OIDS now
164            applicableAttributeOids.clear();
165
166            for ( AttributeType at : applicableAttributes )
167            {
168                applicableAttributeOids.add( at.getOid() );
169            }
170        }
171    }
172
173
174    /**
175     * Add a matchingRule's AttributeType OIDs the MRU applies to.
176     *
177     * @param oid A matchingRule's AttributeType OIDs the MRU applies to
178     */
179    public void addApplicableAttributeOids( String oid )
180    {
181        if ( locked )
182        {
183            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
184        }
185
186        if ( !isReadOnly && !applicableAttributeOids.contains( oid ) )
187        {
188            applicableAttributeOids.add( oid );
189        }
190    }
191
192
193    /**
194     * Add a matchingRule's AttributeType the MRU applies to.
195     *
196     * @param attributeType A matchingRule's AttributeType the MRU applies to
197     */
198    public void addApplicableAttribute( AttributeType attributeType )
199    {
200        if ( locked )
201        {
202            throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
203        }
204
205        if ( !isReadOnly && !applicableAttributeOids.contains( attributeType.getOid() ) )
206        {
207            applicableAttributes.add( attributeType );
208            applicableAttributeOids.add( attributeType.getOid() );
209        }
210    }
211
212
213    /**
214     * @see Object#toString()
215     */
216    @Override
217    public String toString()
218    {
219        return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
220    }
221
222
223    /**
224     * Copy an MatchingRuleUse
225     */
226    @Override
227    public MatchingRuleUse copy()
228    {
229        MatchingRuleUse copy = new MatchingRuleUse( oid );
230
231        // Copy the SchemaObject common data
232        copy.copy( this );
233
234        // Clone the APPLY AttributeTypes
235        copy.applicableAttributeOids = new ArrayList<>();
236
237        // Copy the APPLIES oid list
238        for ( String oid : applicableAttributeOids )
239        {
240            copy.applicableAttributeOids.add( oid );
241        }
242
243        // Copy the APPLIES list (will be empty)
244        copy.applicableAttributes = new ArrayList<>();
245
246        return copy;
247    }
248
249
250    /**
251     * @see Object#equals(Object)
252     */
253    @Override
254    public boolean equals( Object o )
255    {
256        if ( !super.equals( o ) )
257        {
258            return false;
259        }
260
261        if ( !( o instanceof MatchingRuleUse ) )
262        {
263            return false;
264        }
265
266        @SuppressWarnings("unused")
267        MatchingRuleUse that = ( MatchingRuleUse ) o;
268
269        // TODO : complete the checks
270        return true;
271    }
272
273
274    /**
275     * {@inheritDoc}
276     */
277    @Override
278    public void clear()
279    {
280        // Clear the common elements
281        super.clear();
282
283        // Clear the references
284        applicableAttributes.clear();
285        applicableAttributeOids.clear();
286    }
287}