KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ldap > server > schema > bootstrap > BootstrapSchemaLoader


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.common.schema.*;
21 import org.apache.ldap.server.jndi.ServerDirObjectFactory;
22 import org.apache.ldap.server.jndi.ServerDirStateFactory;
23 import org.apache.ldap.server.schema.*;
24
25 import javax.naming.NamingException JavaDoc;
26 import java.util.*;
27
28
29 /**
30  * Class which handles bootstrap schema class file loading.
31  *
32  * @author <a HREF="mailto:dev@directory.apache.org">Apache Directory Project</a>
33  * @version $Rev: 169198 $
34  */

35 public class BootstrapSchemaLoader
36 {
37     /** stores schemas of producers for callback access */
38     private ThreadLocal JavaDoc schemas;
39     /** stores registries associated with producers for callback access */
40     private ThreadLocal JavaDoc registries;
41     /** the callback that just calls register() */
42     private final ProducerCallback cb = new ProducerCallback()
43     {
44         public void schemaObjectProduced( BootstrapProducer producer,
45                                           String JavaDoc registryKey,
46                                           Object JavaDoc schemaObject )
47             throws NamingException JavaDoc
48         {
49             register( producer.getType(), registryKey, schemaObject );
50         }
51     };
52
53
54     /**
55      * Creates a BootstrapSchema loader.
56      */

57     public BootstrapSchemaLoader()
58     {
59         schemas = new ThreadLocal JavaDoc();
60         registries = new ThreadLocal JavaDoc();
61     }
62
63
64
65     /**
66      * Loads a set of schemas by loading and running all producers for each
67      * dependent schema first.
68      *
69      * @param schemaClasses the full qualified class names of the schema classes
70      * @param registries the registries to fill with producer created objects
71      * @throws NamingException if there are any failures during this process
72      */

73     public final void load( String JavaDoc[] schemaClasses, BootstrapRegistries registries )
74         throws NamingException JavaDoc
75     {
76         BootstrapSchema[] schemas = new BootstrapSchema[schemaClasses.length];
77         HashMap loaded = new HashMap();
78         HashMap notLoaded = new HashMap();
79
80
81         for ( int ii = 0; ii < schemas.length; ii++ )
82         {
83             try
84             {
85                 Class JavaDoc schemaClass = Class.forName( schemaClasses[ii] );
86                 schemas[ii] = ( BootstrapSchema ) schemaClass.newInstance();
87                 notLoaded.put( schemas[ii].getSchemaName(), schemas[ii] );
88             }
89             catch ( Exception JavaDoc e )
90             {
91                 String JavaDoc msg = "problem loading/creating " + schemaClasses[ii];
92                 NamingException JavaDoc ne = new NamingException JavaDoc( msg );
93                 ne.setRootCause( e );
94                 throw ne;
95             }
96         }
97
98         // kick it off by loading system which will never depend on anything
99
BootstrapSchema schema = ( BootstrapSchema ) notLoaded.get( "system" );
100         load( schema, registries );
101         notLoaded.remove( "system" );
102         loaded.put( schema.getSchemaName(), schema );
103
104         Iterator list = notLoaded.values().iterator();
105         while ( list.hasNext() )
106         {
107             schema = ( BootstrapSchema ) list.next();
108             loadDepsFirst( new Stack(), notLoaded, schema, registries );
109             list = notLoaded.values().iterator();
110         }
111     }
112
113
114     /**
115      * Recursive method which loads schema's with their dependent schemas first
116      * and tracks what schemas it has seen so the recursion does not go out of
117      * control with depenency cycle detection.
118      *
119      * @param beenthere stack of schema names we have visited and have yet to load
120      * @param notLoaded hash of schemas keyed by name which have yet to be loaded
121      * @param schema the current schema we are attempting to load
122      * @param registries the set of registries to use while loading
123      * @throws NamingException if there is a cycle detected and/or another
124      * failure results while loading, producing and or registering schema objects
125      */

126     public final void loadDepsFirst( Stack beenthere, HashMap notLoaded,
127                                      BootstrapSchema schema,
128                                      BootstrapRegistries registries )
129         throws NamingException JavaDoc
130     {
131         beenthere.push( schema.getSchemaName() );
132         String JavaDoc[] deps = schema.getDependencies();
133
134         // if no deps then load this guy and return
135
if ( deps == null || deps.length == 0 )
136         {
137             load( schema, registries );
138             notLoaded.remove( schema.getSchemaName() );
139             beenthere.pop();
140             return;
141         }
142
143         /*
144          * We got deps and need to load them before this schema. We go through
145          * all deps loading them with their deps first if they have not been
146          * loaded.
147          */

148         for ( int ii = 0; ii < deps.length; ii++ )
149         {
150             if ( ! notLoaded.containsKey( deps[ii] ) )
151             {
152                 continue;
153             }
154
155             BootstrapSchema dep = ( BootstrapSchema ) notLoaded.get( deps[ii] );
156
157             if ( beenthere.contains( dep.getSchemaName() ) )
158             {
159                 // push again so we show the cycle in output
160
beenthere.push( dep.getSchemaName() );
161                 throw new NamingException JavaDoc( "schema dependency cycle detected: "
162                     + beenthere );
163             }
164
165             loadDepsFirst( beenthere, notLoaded, dep, registries );
166         }
167
168         // We have loaded all our deps so we can load this schema
169
load( schema, registries );
170         notLoaded.remove( schema.getSchemaName() );
171         beenthere.pop();
172     }
173
174
175     /**
176      * Loads a schema by loading and running all producers for te schema.
177      *
178      * @param schema the schema to load
179      * @param registries the registries to fill with producer created objects
180      * @throws NamingException if there are any failures during this process
181      */

182     public final void load( BootstrapSchema schema, BootstrapRegistries registries )
183         throws NamingException JavaDoc
184     {
185         this.registries.set( registries );
186         this.schemas.set( schema );
187
188         List producers = ProducerTypeEnum.list();
189         for ( int ii = 0; ii < producers.size(); ii++ )
190         {
191             ProducerTypeEnum producerType = ( ProducerTypeEnum ) producers.get( ii );
192             BootstrapProducer producer = getProducer( schema, producerType.getName() );
193             producer.produce( registries, cb );
194         }
195     }
196
197
198     // ------------------------------------------------------------------------
199
// Utility Methods
200
// ------------------------------------------------------------------------
201

202
203     /**
204      * Registers objects
205      *
206      * @param type the type of the producer which determines the type of object produced
207      * @param id the primary key identifying the created object in a registry
208      * @param schemaObject the object being registered
209      * @throws NamingException if there are problems when registering the object
210      * in any of the registries
211      */

212     private void register( ProducerTypeEnum type, String JavaDoc id,
213                            Object JavaDoc schemaObject ) throws NamingException JavaDoc
214     {
215         BootstrapSchema schema = ( BootstrapSchema ) this.schemas.get();
216         BootstrapRegistries registries = ( BootstrapRegistries ) this.registries.get();
217
218         switch( type.getValue() )
219         {
220             case( ProducerTypeEnum.NORMALIZER_PRODUCER_VAL ):
221                 Normalizer normalizer = ( Normalizer ) schemaObject;
222                 NormalizerRegistry normalizerRegistry;
223                 normalizerRegistry = registries.getNormalizerRegistry();
224                 normalizerRegistry.register( schema.getSchemaName(), id, normalizer );
225                 break;
226             case( ProducerTypeEnum.COMPARATOR_PRODUCER_VAL ):
227                 Comparator comparator = ( Comparator ) schemaObject;
228                 ComparatorRegistry comparatorRegistry;
229                 comparatorRegistry = registries.getComparatorRegistry();
230                 comparatorRegistry.register( schema.getSchemaName(), id, comparator );
231                 break;
232             case( ProducerTypeEnum.SYNTAX_CHECKER_PRODUCER_VAL ):
233                 SyntaxChecker syntaxChecker = ( SyntaxChecker ) schemaObject;
234                 SyntaxCheckerRegistry syntaxCheckerRegistry;
235                 syntaxCheckerRegistry = registries.getSyntaxCheckerRegistry();
236                 syntaxCheckerRegistry.register( schema.getSchemaName(), id, syntaxChecker );
237                 break;
238             case( ProducerTypeEnum.SYNTAX_PRODUCER_VAL ):
239                 Syntax syntax = ( Syntax ) schemaObject;
240                 SyntaxRegistry syntaxRegistry = registries.getSyntaxRegistry();
241                 syntaxRegistry.register( schema.getSchemaName(), syntax );
242                 break;
243             case( ProducerTypeEnum.MATCHING_RULE_PRODUCER_VAL ):
244                 MatchingRule matchingRule = ( MatchingRule ) schemaObject;
245                 MatchingRuleRegistry matchingRuleRegistry;
246                 matchingRuleRegistry = registries.getMatchingRuleRegistry();
247                 matchingRuleRegistry.register( schema.getSchemaName(), matchingRule );
248                 break;
249             case( ProducerTypeEnum.ATTRIBUTE_TYPE_PRODUCER_VAL ):
250                 AttributeType attributeType = ( AttributeType ) schemaObject;
251                 AttributeTypeRegistry attributeTypeRegistry;
252                 attributeTypeRegistry = registries.getAttributeTypeRegistry();
253                 attributeTypeRegistry.register( schema.getSchemaName(), attributeType );
254                 break;
255             case( ProducerTypeEnum.OBJECT_CLASS_PRODUCER_VAL ):
256                 ObjectClass objectClass = ( ObjectClass ) schemaObject;
257                 ObjectClassRegistry objectClassRegistry;
258                 objectClassRegistry = registries.getObjectClassRegistry();
259                 objectClassRegistry.register( schema.getSchemaName(), objectClass );
260                 break;
261             case( ProducerTypeEnum.MATCHING_RULE_USE_PRODUCER_VAL ):
262                 MatchingRuleUse matchingRuleUse = ( MatchingRuleUse ) schemaObject;
263                 MatchingRuleUseRegistry matchingRuleUseRegistry;
264                 matchingRuleUseRegistry = registries.getMatchingRuleUseRegistry();
265                 matchingRuleUseRegistry.register( schema.getSchemaName(), matchingRuleUse );
266                 break;
267             case( ProducerTypeEnum.DIT_CONTENT_RULE_PRODUCER_VAL ):
268                 DITContentRule ditContentRule = ( DITContentRule ) schemaObject;
269                 DITContentRuleRegistry ditContentRuleRegistry;
270                 ditContentRuleRegistry = registries.getDitContentRuleRegistry();
271                 ditContentRuleRegistry.register( schema.getSchemaName(), ditContentRule );
272                 break;
273             case( ProducerTypeEnum.NAME_FORM_PRODUCER_VAL ):
274                 NameForm nameForm = ( NameForm ) schemaObject;
275                 NameFormRegistry nameFormRegistry;
276                 nameFormRegistry = registries.getNameFormRegistry();
277                 nameFormRegistry.register( schema.getSchemaName(), nameForm );
278                 break;
279             case( ProducerTypeEnum.DIT_STRUCTURE_RULE_PRODUCER_VAL ):
280                 DITStructureRule ditStructureRule = ( DITStructureRule ) schemaObject;
281                 DITStructureRuleRegistry ditStructureRuleRegistry;
282                 ditStructureRuleRegistry = registries.getDitStructureRuleRegistry();
283                 ditStructureRuleRegistry.register( schema.getSchemaName(), ditStructureRule );
284                 break;
285             case( ProducerTypeEnum.STATE_FACTORY_PRODUCER_VAL ):
286                 ServerDirStateFactory stateFactory = ( ServerDirStateFactory ) schemaObject;
287                 StateFactoryRegistry stateFactoryRegistry;
288                 stateFactoryRegistry = registries.getStateFactoryRegistry();
289                 stateFactoryRegistry.register( stateFactory );
290                 break;
291             case( ProducerTypeEnum.OBJECT_FACTORY_PRODUCER_VAL ):
292                 ServerDirObjectFactory objectFactory = ( ServerDirObjectFactory ) schemaObject;
293                 ObjectFactoryRegistry objectFactoryRegistry;
294                 objectFactoryRegistry = registries.getObjectFactoryRegistry();
295                 objectFactoryRegistry.register( objectFactory );
296                 break;
297             default:
298                 throw new IllegalStateException JavaDoc( "ProducerTypeEnum is broke!" );
299         }
300     }
301
302
303     /**
304      * Attempts first to try to load the target class for the Producer,
305      * then tries for the default if the target load fails.
306      *
307      * @param schema the bootstrap schema
308      * @param producerBase the producer's base name
309      * @throws NamingException if there are failures loading classes
310      */

311     private BootstrapProducer getProducer( BootstrapSchema schema, String JavaDoc producerBase )
312         throws NamingException JavaDoc
313     {
314         Class JavaDoc clazz = null;
315         boolean failedTargetLoad = false;
316         String JavaDoc defaultClassName;
317         String JavaDoc targetClassName = schema.getBaseClassName() + producerBase;
318
319         try
320         {
321             clazz = Class.forName( targetClassName );
322         }
323         catch ( ClassNotFoundException JavaDoc e )
324         {
325             failedTargetLoad = true;
326             // @todo instead of trace report target class load failure to monitor
327
e.printStackTrace();
328         }
329
330         if ( failedTargetLoad )
331         {
332             defaultClassName = schema.getDefaultBaseClassName() + producerBase;
333
334             try
335             {
336                 clazz = Class.forName( defaultClassName );
337             }
338             catch ( ClassNotFoundException JavaDoc e )
339             {
340                 NamingException JavaDoc ne = new NamingException JavaDoc( "Failed to load " +
341                     producerBase + " for " + schema.getSchemaName()
342                     + " schema using following classes: " + targetClassName
343                     + ", " + defaultClassName );
344                 ne.setRootCause( e );
345                 throw ne;
346             }
347         }
348
349         try
350         {
351             return ( BootstrapProducer ) clazz.newInstance();
352         }
353         catch ( IllegalAccessException JavaDoc e )
354         {
355             NamingException JavaDoc ne = new NamingException JavaDoc( "Failed to create " + clazz );
356             ne.setRootCause( e );
357             throw ne;
358         }
359         catch ( InstantiationException JavaDoc e )
360         {
361             NamingException JavaDoc ne = new NamingException JavaDoc( "Failed to create " + clazz );
362             ne.setRootCause( e );
363             throw ne;
364         }
365     }
366 }
367
Popular Tags