View Javadoc

1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.ldap.server.schema.bootstrap;
18  
19  
20  import org.apache.ldap.server.schema.OidRegistry;
21  import org.apache.ldap.server.schema.OidRegistryMonitor;
22  import org.apache.ldap.server.schema.OidRegistryMonitorAdapter;
23  
24  import javax.naming.NamingException;
25  import java.util.*;
26  
27  
28  /***
29   * Default OID registry implementation used to resolve a schema object OID 
30   * to a name and vice-versa.
31   * 
32   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
33   * @version $Rev: 159259 $
34   */
35  public class BootstrapOidRegistry implements OidRegistry
36  { 
37      /*** Maps OID to a name or a list of names if more than one name exists */
38      private Hashtable byOid = new Hashtable();
39      /*** Maps several names to an OID */
40      private Hashtable byName = new Hashtable();
41      /*** Default OidRegistryMonitor */
42      private OidRegistryMonitor monitor = new OidRegistryMonitorAdapter();
43      
44      
45      /***
46       * @see org.apache.ldap.server.schema.OidRegistry#getOid(java.lang.String)
47       */
48      public String getOid( String name ) throws NamingException
49      {
50          if ( name == null )
51          {
52              throw new NamingException( "name should not be null" );
53          }
54          /* If name is an OID than we return it back since inherently the
55           * OID is another name for the object referred to by OID and the
56           * caller does not know that the argument is an OID String.
57           */
58          if ( Character.isDigit( name.charAt( 0 ) ) )
59          {
60              monitor.getOidWithOid( name );
61              return name;
62          }
63  
64          // If name is mapped to a OID already return OID
65          if ( byName.containsKey( name ) )
66          {
67              String oid = ( String ) byName.get( name );
68              monitor.oidResolved( name, oid );
69              return oid;
70          }
71  
72          /*
73           * As a last resort we check if name is not normalized and if the
74           * normalized version used as a key returns an OID.  If the normalized
75           * name works add the normalized name as a key with its OID to the
76           * byName lookup.  BTW these normalized versions of the key are not
77           * returned on a getNameSet.
78           */
79           String lowerCase = name.trim().toLowerCase();
80           if ( ! name.equals( lowerCase )
81              && byName.containsKey( lowerCase ) )
82           {
83               String oid = ( String ) byName.get( lowerCase );
84               monitor.oidResolved( name, lowerCase, oid );
85  
86               // We expect to see this version of the key again so we add it
87               byName.put( name, oid );
88               return oid;
89           }
90  
91           NamingException fault = new NamingException ( "OID for name '"
92                   + name + "' was not " + "found within the OID registry" );
93           monitor.oidResolutionFailed( name, fault );
94           throw fault;
95      }
96  
97  
98      /***
99       * @see org.apache.ldap.server.schema.OidRegistry#hasOid(java.lang.String)
100      */
101     public boolean hasOid( String name )
102     {
103         return this.byName.containsKey( name ) || this.byOid.containsKey( name );
104     }
105 
106 
107     /***
108      * @see org.apache.ldap.server.schema.OidRegistry#getPrimaryName(java.lang.String)
109      */
110     public String getPrimaryName( String oid ) throws NamingException
111     {
112         Object value = byOid.get( oid );
113         
114         if ( null == value )
115         {
116             NamingException fault = new NamingException ( "OID '" + oid
117                     + "' was not found within the OID registry" );
118             monitor.oidDoesNotExist( oid, fault );
119             throw fault;
120         }
121         
122         if ( value instanceof String )
123         {
124             monitor.nameResolved( oid, ( String ) value );
125             return ( String ) value;
126         }
127         
128         String name = ( String ) ( ( List ) value ).get( 0 );
129         monitor.nameResolved( oid, name );
130         return name;
131     }
132 
133 
134     /***
135      * @see org.apache.ldap.server.schema.OidRegistry#getNameSet(java.lang.String)
136      */
137     public List getNameSet( String oid ) throws NamingException
138     {
139         Object value = byOid.get( oid );
140         
141         if ( null == value )
142         {
143             NamingException fault = new NamingException ( "OID '" + oid
144                     + "' was not found within the OID registry" );
145             monitor.oidDoesNotExist( oid, fault );
146             throw fault;
147         }
148         
149         if ( value instanceof String )
150         {
151             List list = Collections.singletonList( value );
152             monitor.namesResolved( oid, list );
153             return list;
154         }
155         
156         monitor.namesResolved( oid, ( List ) value );
157         return ( List ) value;
158     }
159 
160 
161     /***
162      * @see org.apache.ldap.server.schema.OidRegistry#list()
163      */
164     public Iterator list()
165     {
166         return Collections.unmodifiableSet( byOid.keySet() ).iterator();
167     }
168 
169 
170     /***
171      * @see org.apache.ldap.server.schema.OidRegistry#register(String, String)
172      */
173     public void register( String name, String oid )
174     {
175         if ( ! Character.isDigit( oid.charAt( 0 ) ) )
176         {
177             throw new RuntimeException( "Swap the parameter order: the oid " +
178                 "does not start with a digit!" );
179         }
180 
181         /*
182          * Add the entry for the given name as is and its lowercased version if
183          * the lower cased name is different from the given name name.  
184          */
185         String lowerCase = name.toLowerCase();
186         if ( ! lowerCase.equals( name ) )
187         {
188             byName.put( lowerCase, oid );
189         }
190         
191         // Put both the name and the oid as names
192         byName.put( name, oid );
193         byName.put( oid, oid );
194         
195         /*
196          * Update OID Map
197          * 
198          * 1). Check if we already have a value[s] stored
199          *      1a). Value is a single value and is a String
200          *          Replace value with list containing old and new values
201          *      1b). More than one value stored in a list
202          *          Add new value to the list
203          * 2). If we do not have a value then we just add it as a String
204          */
205         Object value = null;
206         if ( ! byOid.containsKey( oid ) )
207         {
208             value = name;
209         }
210         else 
211         {
212             ArrayList list = null;
213             value = byOid.get( oid );
214             
215             if ( value instanceof String )
216             {
217                 String existingName = ( String ) value;
218                 
219                 // if the existing name is already there we don't readd it
220                 if ( existingName.equalsIgnoreCase( name ) )
221                 {
222                     return;
223                 }
224                 
225                 list = new ArrayList();
226                 list.add( value );
227                 value = list;
228             }
229             else if ( value instanceof ArrayList )
230             {
231                 list = ( ArrayList ) value;
232                 
233                 for ( int ii = 0; ii < list.size(); ii++ )
234                 {
235                     // One form or another of the name already exists in list
236                     if ( ! name.equalsIgnoreCase( ( String ) list.get( ii ) ) )
237                     {
238                         return;
239                     }
240                 }
241                 
242                 list.add( name );
243             }
244         }
245 
246         byOid.put( oid, value );
247         monitor.registered( name, oid );
248     }
249     
250     
251     /***
252      * Gets the monitor.
253      * 
254      * @return the monitor
255      */
256     OidRegistryMonitor getMonitor()
257     {
258         return monitor;
259     }
260 
261     
262     /***
263      * Sets the monitor.
264      * 
265      * @param monitor monitor to set.
266      */
267     void setMonitor( OidRegistryMonitor monitor )
268     {
269         this.monitor = monitor;
270     }
271 }
272