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.registries;
021    
022    
023    import java.util.Collections;
024    import java.util.HashMap;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Map;
028    
029    import org.apache.directory.shared.asn1.primitives.OID;
030    import org.apache.directory.shared.i18n.I18n;
031    import org.apache.directory.shared.ldap.exception.LdapException;
032    import org.apache.directory.shared.ldap.schema.SchemaObject;
033    import org.apache.directory.shared.ldap.util.ArrayUtils;
034    import org.slf4j.Logger;
035    import org.slf4j.LoggerFactory;
036    
037    
038    /**
039     * Object identifier registry. It stores the OIDs for AT, OC, MR, LS, MRU, DSR, DCR and NF.
040     * An OID is unique, and associated with a SO.
041     *
042     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043     * @version $Rev: 923524 $
044     */
045    public class OidRegistry implements Iterable<SchemaObject>
046    {
047        /** static class logger */
048        private static final Logger LOG = LoggerFactory.getLogger( OidRegistry.class );
049    
050        /** Speedup for DEBUG mode */
051        private static final boolean IS_DEBUG = LOG.isDebugEnabled();
052    
053        /** Maps OID to a SchemaObject */
054        private Map<String, SchemaObject> byOid = new HashMap<String, SchemaObject>();
055    
056    
057        /**
058         * Tells if the given OID is present on this registry
059         * 
060         * @param oid The OID to lookup
061         * @return true if the OID alreadyexists
062         */
063        public boolean contains( String oid )
064        {
065            return byOid.containsKey( oid );
066        }
067    
068    
069        /**
070         * Gets the primary name associated with an OID.  The primary name is the
071         * first name specified for the OID.
072         * 
073         * @param oid the object identifier
074         * @return the primary name
075         * @throws LdapException if oid does not exist
076         */
077        public String getPrimaryName( String oid ) throws LdapException
078        {
079            SchemaObject schemaObject = byOid.get( oid );
080    
081            if ( schemaObject != null )
082            {
083                return schemaObject.getName();
084            }
085            else
086            {
087                String msg = I18n.err( I18n.ERR_04286, oid );
088                LOG.error( msg );
089                throw new LdapException( msg );
090            }
091        }
092    
093    
094        /**
095         * Gets the SchemaObject associated with an OID. 
096         * 
097         * @param oid the object identifier
098         * @return the associated SchemaObject
099         * @throws LdapException if oid does not exist
100         */
101        public SchemaObject getSchemaObject( String oid ) throws LdapException
102        {
103            SchemaObject schemaObject = byOid.get( oid );
104    
105            if ( schemaObject != null )
106            {
107                return schemaObject;
108            }
109            else
110            {
111                String msg = I18n.err( I18n.ERR_04287, oid );
112                LOG.error( msg );
113                throw new LdapException( msg );
114            }
115        }
116    
117    
118        /**
119         * Gets the names associated with an OID.  An OID is unique however it may 
120         * have many names used to refer to it.  A good example is the cn and
121         * commonName attribute names for OID 2.5.4.3.  Within a server one name 
122         * within the set must be chosen as the primary name.  This is used to
123         * name certain things within the server internally.  If there is more than
124         * one name then the first name is taken to be the primary.
125         * 
126         * @param oid the OID for which we return the set of common names
127         * @return a sorted set of names
128         * @throws LdapException if oid does not exist
129         */
130        public List<String> getNameSet( String oid ) throws LdapException
131        {
132            SchemaObject schemaObject = byOid.get( oid );
133    
134            if ( null == schemaObject )
135            {
136                String msg = I18n.err( I18n.ERR_04288, oid );
137                LOG.error( msg );
138                throw new LdapException( msg );
139            }
140    
141            List<String> names = schemaObject.getNames();
142    
143            if ( IS_DEBUG )
144            {
145                LOG.debug( "looked up names '{}' for OID '{}'", ArrayUtils.toString( names ), oid );
146            }
147    
148            return names;
149        }
150    
151    
152        /**
153         * Lists all the OIDs within the registry.  This may be a really big list.
154         * 
155         * @return all the OIDs registered
156         */
157        public Iterator<String> iteratorOids()
158        {
159            return Collections.unmodifiableSet( byOid.keySet() ).iterator();
160        }
161    
162    
163        /**
164         * Lists all the SchemaObjects within the registry.  This may be a really big list.
165         * 
166         * @return all the SchemaObject registered
167         */
168        public Iterator<SchemaObject> iterator()
169        {
170            return byOid.values().iterator();
171        }
172    
173    
174        /**
175         * Adds an OID name pair to the registry.
176         * 
177         * @param type The SchemaObjectType the oid belongs to
178         * @param oid the OID to add or associate a new name with
179         */
180        public void register( SchemaObject schemaObject ) throws LdapException
181        {
182            if ( schemaObject == null )
183            {
184                String message = I18n.err( I18n.ERR_04289 );
185    
186                LOG.debug( message );
187                throw new LdapException( message );
188            }
189    
190            String oid = schemaObject.getOid();
191    
192            if ( !OID.isOID( oid ) )
193            {
194                String message = I18n.err( I18n.ERR_04290 );
195    
196                LOG.debug( message );
197                throw new LdapException( message );
198            }
199    
200            /*
201             * Update OID Map if it does not already exist
202             */
203            if ( byOid.containsKey( oid ) )
204            {
205                String message = I18n.err( I18n.ERR_04291, oid );
206                LOG.info( message );
207                return;
208            }
209            else
210            {
211                byOid.put( oid, schemaObject );
212    
213                if ( IS_DEBUG )
214                {
215                    LOG.debug( "registed SchemaObject '" + schemaObject + "' with OID: " + oid );
216                }
217            }
218        }
219    
220    
221        /**
222         * Store the given SchemaObject into the OidRegistry. Available only to 
223         * the current package. A weak form (no check is done) of the register 
224         * method, define for clone methods.
225         *
226         * @param schemaObject The SchemaObject to inject into the OidRegistry
227         */
228        /* No qualifier */void put( SchemaObject schemaObject )
229        {
230            byOid.put( schemaObject.getOid(), schemaObject );
231        }
232    
233    
234        /**
235         * Removes an oid from this registry.
236         *
237         * @param oid the numeric identifier for the object
238         * @throws LdapException if the identifier is not numeric
239         */
240        public void unregister( String oid ) throws LdapException
241        {
242            // Removes the <OID, names> from the byOID map
243            SchemaObject removed = byOid.remove( oid );
244    
245            if ( IS_DEBUG )
246            {
247                LOG.debug( "Unregisted SchemaObject '{}' with OID: {}", removed, oid );
248            }
249        }
250    
251    
252        /**
253         * Copy the OidRegistry, without the contained values
254         * 
255         * @return A new OidRegistry instance
256         */
257        public OidRegistry copy()
258        {
259            OidRegistry copy = new OidRegistry();
260    
261            // Clone the map
262            copy.byOid = new HashMap<String, SchemaObject>();
263    
264            return copy;
265        }
266    
267    
268        /**
269         * @return The number of stored OIDs
270         */
271        public int size()
272        {
273            return byOid.size();
274        }
275    
276    
277        public void clear()
278        {
279            // remove all the OID
280            byOid.clear();
281        }
282    
283    
284        /**
285         * @see Object#toString()
286         */
287        public String toString()
288        {
289            StringBuilder sb = new StringBuilder();
290    
291            if ( byOid != null )
292            {
293                boolean isFirst = true;
294    
295                for ( String oid : byOid.keySet() )
296                {
297                    if ( isFirst )
298                    {
299                        isFirst = false;
300                    }
301                    else
302                    {
303                        sb.append( ", " );
304                    }
305    
306                    sb.append( "<" );
307    
308                    SchemaObject schemaObject = byOid.get( oid );
309    
310                    if ( schemaObject != null )
311                    {
312                        sb.append( schemaObject.getObjectType() );
313                        sb.append( ", " );
314                        sb.append( schemaObject.getOid() );
315                        sb.append( ", " );
316                        sb.append( schemaObject.getName() );
317                    }
318    
319                    sb.append( ">" );
320                }
321            }
322    
323            return sb.toString();
324        }
325    }