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