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     */
020    package org.apache.directory.shared.ldap.schema;
021    
022    
023    import java.util.ArrayList;
024    import java.util.List;
025    
026    import javax.naming.NamingException;
027    
028    import org.apache.directory.shared.ldap.schema.registries.AttributeTypeRegistry;
029    import org.apache.directory.shared.ldap.schema.registries.Registries;
030    
031    
032    /**
033     * Represents an LDAP MatchingRuleUseDescription defined in RFC 2252.
034     * <p>
035     * According to ldapbis [MODELS]:
036     * </p>
037     * 
038     * <pre>
039     *  Values of the matchingRuleUse list the attributes which are suitable
040     *  for use with an extensible matching rule.
041     *  
042     *    Matching rule use descriptions are written according to the following
043     *    ABNF:
044     * 
045     *      MatchingRuleUseDescription = LPAREN WSP
046     *          numericoid                ; object identifier
047     *          [ SP &quot;NAME&quot; SP qdescrs ]  ; short names (descriptors)
048     *          [ SP &quot;DESC&quot; SP qdstring ] ; description
049     *          [ SP &quot;OBSOLETE&quot; ]         ; not active
050     *          SP &quot;APPLIES&quot; SP oids      ; attribute types
051     *          extensions WSP RPAREN     ; extensions
052     *  
053     *    where:
054     *      [numericoid] is the object identifier of the matching rule
055     *          associated with this matching rule use description;
056     *      NAME [qdescrs] are short names (descriptors) identifying this
057     *          matching rule use;
058     *      DESC [qdstring] is a short descriptive string;
059     *      OBSOLETE indicates this matching rule use is not active;
060     *      APPLIES provides a list of attribute types the matching rule applies
061     *          to; and
062     *      [extensions] describe extensions.
063     * 
064     *  The matchingRule within the MatchingRuleUse definition can be used by an
065     *  extensible match assertion if the assertion is based on the attributes 
066     *  listed within the MatchingRuleUse definition.  If an extensible match 
067     *  assertion is based on attributes other than those listed within the 
068     *  MatchingRuleUse definition then the assertion is deemed undefined.
069     *  
070     *  Also according to 3.3.20 of [SYNTAXES] (ldapbis working group):
071     *  
072     *  A value of the Matching Rule Use Description syntax indicates the
073     *  attribute types to which a matching rule may be applied in an
074     *  extensibleMatch search filter [PROT].  The LDAP-specific encoding of
075     *  a value of this syntax is defined by the &lt;MatchingRuleUseDescription&gt;
076     *  rule in [MODELS] above.
077     * </pre>
078     * 
079     * @see <a
080     *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
081     *      [MODELS]</a>
082     * @see <a
083     *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-syntaxes-09.txt">ldapbis
084     *      [SYNTAXES]</a>
085     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
086     * @version $Rev: 896579 $
087     */
088    public class MatchingRuleUse extends AbstractSchemaObject
089    {
090        /** The serialVersionUID */
091        private static final long serialVersionUID = 1L;
092    
093        /** The list of attributes types OID the matching rule applies to */
094        private List<String> applicableAttributeOids;
095    
096        /** The list of attributes types the matching rule applies to */
097        private List<AttributeType> applicableAttributes;
098    
099    
100        /**
101         * Creates a new instance of MatchingRuleUseDescription
102         */
103        public MatchingRuleUse( String oid )
104        {
105            super( SchemaObjectType.MATCHING_RULE_USE, oid );
106    
107            applicableAttributeOids = new ArrayList<String>();
108            applicableAttributes = new ArrayList<AttributeType>();
109        }
110    
111    
112        /**
113         * Inject the MatchingRuleUse into the registries, updating the references to
114         * other SchemaObject
115         *
116         * @param registries The Registries
117         * @exception If the addition failed
118         */
119        public void addToRegistries( Registries registries ) throws NamingException
120        {
121            if ( registries != null )
122            {
123                AttributeTypeRegistry atRegistry = registries.getAttributeTypeRegistry();
124    
125                if ( applicableAttributeOids != null )
126                {
127                    applicableAttributes = new ArrayList<AttributeType>( applicableAttributeOids.size() );
128    
129                    for ( String oid : applicableAttributeOids )
130                    {
131                        applicableAttributes.add( atRegistry.lookup( oid ) );
132                    }
133                }
134            }
135        }
136    
137    
138        /**
139         * @return The matchingRule's list of AttributeType OIDs the MRU applies to
140         */
141        public List<String> getApplicableAttributeOids()
142        {
143            return applicableAttributeOids;
144        }
145    
146    
147        /**
148         * @return The matchingRule's list of AttributeType OIDs the MRU applies to
149         */
150        public List<AttributeType> getApplicableAttributes()
151        {
152            return applicableAttributes;
153        }
154    
155    
156        /**
157         * Set the matchingRule's AttributeType OIDs the MRU applies to.
158         *
159         * @param applicableAttributes The AttributeType OIDs list
160         */
161        public void setApplicableAttributeOids( List<String> applicableAttributeOids )
162        {
163            if ( !isReadOnly )
164            {
165                this.applicableAttributeOids = applicableAttributeOids;
166            }
167        }
168    
169    
170        /**
171         * Set the matchingRule's AttributeType the MRU applies to.
172         *
173         * @param applicableAttributes The AttributeType list
174         */
175        public void setApplicableAttributes( List<AttributeType> applicableAttributes )
176        {
177            if ( !isReadOnly )
178            {
179                this.applicableAttributes = applicableAttributes;
180    
181                // update the OIDS now
182                applicableAttributeOids.clear();
183    
184                for ( AttributeType at : applicableAttributes )
185                {
186                    applicableAttributeOids.add( at.getOid() );
187                }
188            }
189        }
190    
191    
192        /**
193         * Add a matchingRule's AttributeType OIDs the MRU applies to.
194         *
195         * @param oid A matchingRule's AttributeType OIDs the MRU applies to
196         */
197        public void addApplicableAttributeOids( String oid )
198        {
199            if ( !isReadOnly )
200            {
201                if ( !applicableAttributeOids.contains( oid ) )
202                {
203                    applicableAttributeOids.add( oid );
204                }
205            }
206        }
207    
208    
209        /**
210         * Add a matchingRule's AttributeType the MRU applies to.
211         *
212         * @param oid A matchingRule's AttributeType the MRU applies to
213         */
214        public void addApplicableAttribute( AttributeType attributeType )
215        {
216            if ( !isReadOnly )
217            {
218                if ( !applicableAttributeOids.contains( attributeType.getOid() ) )
219                {
220                    applicableAttributes.add( attributeType );
221                    applicableAttributeOids.add( attributeType.getOid() );
222                }
223            }
224        }
225    
226    
227        /**
228         * @see Object#toString()
229         */
230        public String toString()
231        {
232            return objectType + " " + DescriptionUtils.getDescription( this );
233        }
234    
235    
236        /**
237         * Copy an MatchingRuleUse
238         */
239        public MatchingRuleUse copy()
240        {
241            MatchingRuleUse copy = new MatchingRuleUse( oid );
242    
243            // Copy the SchemaObject common data
244            copy.copy( this );
245    
246            // Clone the APPLY AttributeTypes
247            copy.applicableAttributeOids = new ArrayList<String>();
248    
249            // Copy the APPLIES oid list
250            for ( String oid : applicableAttributeOids )
251            {
252                copy.applicableAttributeOids.add( oid );
253            }
254    
255            // Copy the APPLIES list (will be empty)
256            copy.applicableAttributes = new ArrayList<AttributeType>();
257    
258            return copy;
259        }
260    
261    
262        /**
263         * @see Object#equals(Object)
264         */
265        public boolean equals( Object o )
266        {
267            if ( !super.equals( o ) )
268            {
269                return false;
270            }
271    
272            if ( !( o instanceof MatchingRuleUse ) )
273            {
274                return false;
275            }
276    
277            MatchingRuleUse that = ( MatchingRuleUse ) o;
278    
279            // TODO : complete the checks
280            return true;
281        }
282    
283    
284        /**
285         * {@inheritDoc}
286         */
287        public void clear()
288        {
289            // Clear the common elements
290            super.clear();
291    
292            // Clear the references
293            applicableAttributes.clear();
294            applicableAttributeOids.clear();
295        }
296    }