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.ArrayList;
024 import java.util.Collection;
025 import java.util.HashMap;
026 import java.util.HashSet;
027 import java.util.List;
028 import java.util.Map;
029 import java.util.Set;
030
031 import org.apache.directory.shared.i18n.I18n;
032 import org.apache.directory.shared.ldap.constants.MetaSchemaConstants;
033 import org.apache.directory.shared.ldap.constants.SchemaConstants;
034 import org.apache.directory.shared.ldap.entry.Entry;
035 import org.apache.directory.shared.ldap.entry.EntryAttribute;
036 import org.apache.directory.shared.ldap.entry.Value;
037 import org.apache.directory.shared.ldap.util.StringTools;
038 import org.slf4j.Logger;
039 import org.slf4j.LoggerFactory;
040
041
042 /**
043 * An abstract class with a utility method and setListener() implemented.
044 *
045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
046 * @version $Rev$
047 */
048 public abstract class AbstractSchemaLoader implements SchemaLoader
049 {
050 /** static class logger */
051 private static final Logger LOG = LoggerFactory.getLogger( AbstractSchemaLoader.class );
052
053 protected SchemaLoaderListener listener;
054
055 /**
056 * A map of all available schema names to schema objects. This map is
057 * populated when this class is created with all the schemas present in
058 * the LDIF based schema repository.
059 */
060 protected final Map<String, Schema> schemaMap = new HashMap<String, Schema>();
061
062
063 public void setListener( SchemaLoaderListener listener )
064 {
065 this.listener = listener;
066 }
067
068
069 protected final void notifyListenerOrRegistries( Schema schema, Registries registries )
070 {
071 if ( listener != null )
072 {
073 listener.schemaLoaded( schema );
074 }
075
076 if ( registries instanceof SchemaLoaderListener )
077 {
078 if ( registries != listener )
079 {
080 SchemaLoaderListener listener = ( SchemaLoaderListener ) registries;
081 listener.schemaLoaded( schema );
082 }
083 }
084 }
085
086
087 /**
088 * {@inheritDoc}
089 */
090 public final Collection<Schema> getAllEnabled() throws Exception
091 {
092 Collection<Schema> enabledSchemas = new ArrayList<Schema>();
093
094 for ( Schema schema : schemaMap.values() )
095 {
096 if ( schema.isEnabled() )
097 {
098 enabledSchemas.add( schema );
099 }
100 }
101
102 return enabledSchemas;
103 }
104
105
106 /**
107 * {@inheritDoc}
108 */
109 public final Collection<Schema> getAllSchemas() throws Exception
110 {
111 return schemaMap.values();
112 }
113
114
115 /**
116 * {@inheritDoc}
117 */
118 public Schema getSchema( String schemaName )
119 {
120 return schemaMap.get( StringTools.toLowerCase( schemaName ) );
121 }
122
123
124 /**
125 * {@inheritDoc}
126 */
127 public void addSchema( Schema schema )
128 {
129 schemaMap.put( schema.getSchemaName(), schema );
130 }
131
132
133 /**
134 * {@inheritDoc}
135 */
136 public void removeSchema( Schema schema )
137 {
138 schemaMap.remove( schema.getSchemaName() );
139 }
140
141
142 protected Schema getSchema( Entry entry ) throws Exception
143 {
144 EntryAttribute objectClasses = entry.get( SchemaConstants.OBJECT_CLASS_AT );
145 boolean isSchema = false;
146
147 for ( Value<?> value : objectClasses )
148 {
149 if ( MetaSchemaConstants.META_SCHEMA_OC.equalsIgnoreCase( value.getString() ) )
150 {
151 isSchema = true;
152 break;
153 }
154 }
155
156 if ( !isSchema )
157 {
158 return null;
159 }
160
161 String name;
162 String owner;
163 String[] dependencies = StringTools.EMPTY_STRINGS;
164 boolean isDisabled = false;
165
166 if ( entry == null )
167 {
168 throw new NullPointerException( I18n.err( I18n.ERR_04261 ) );
169 }
170
171 if ( entry.get( SchemaConstants.CN_AT ) == null )
172 {
173 throw new NullPointerException( I18n.err( I18n.ERR_04262 ) );
174 }
175
176 name = entry.get( SchemaConstants.CN_AT ).getString();
177
178 if ( entry.get( SchemaConstants.CREATORS_NAME_AT ) == null )
179 {
180 throw new NullPointerException( "entry must have a valid " + SchemaConstants.CREATORS_NAME_AT
181 + " attribute" );
182 }
183
184 owner = entry.get( SchemaConstants.CREATORS_NAME_AT ).getString();
185
186 if ( entry.get( MetaSchemaConstants.M_DISABLED_AT ) != null )
187 {
188 String value = entry.get( MetaSchemaConstants.M_DISABLED_AT ).getString();
189 value = value.toUpperCase();
190 isDisabled = value.equals( "TRUE" );
191 }
192
193 if ( entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT ) != null )
194 {
195 Set<String> depsSet = new HashSet<String>();
196 EntryAttribute depsAttr = entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT );
197
198 for ( Value<?> value : depsAttr )
199 {
200 depsSet.add( value.getString() );
201 }
202
203 dependencies = depsSet.toArray( StringTools.EMPTY_STRINGS );
204 }
205
206 return new DefaultSchema( name, owner, dependencies, isDisabled )
207 {
208 };
209 }
210
211
212 /**
213 * {@inheritDoc}
214 *
215 public List<Throwable> loadWithDependencies( Registries registries, boolean check, Schema... schemas ) throws Exception
216 {
217 // Relax the controls at first
218 List<Throwable> errors = new ArrayList<Throwable>();
219 boolean wasRelaxed = registries.isRelaxed();
220 registries.setRelaxed( true );
221
222 Map<String,Schema> notLoaded = new HashMap<String,Schema>();
223
224 for ( Schema schema : schemas )
225 {
226 if ( ! registries.isSchemaLoaded( schema.getSchemaName() ) )
227 {
228 notLoaded.put( schema.getSchemaName(), schema );
229 }
230 }
231
232 for ( Schema schema : notLoaded.values() )
233 {
234 Stack<String> beenthere = new Stack<String>();
235 loadDepsFirst( schema, beenthere, notLoaded, schema, registries );
236 }
237
238 // At the end, check the registries if required
239 if ( check )
240 {
241 errors = registries.checkRefInteg();
242 }
243
244 // Restore the Registries isRelaxed flag
245 registries.setRelaxed( wasRelaxed );
246
247 return errors;
248 }
249
250
251 /**
252 * Register the comparator contained in the given LdifEntry into the registries.
253 *
254 * @param registries The Registries
255 * @param entry The LdifEntry containing the comparator description
256 * @param schema The associated schema
257 * @throws Exception If the registering failed
258 *
259 protected LdapComparator<?> registerComparator( Registries registries, LdifEntry entry, Schema schema )
260 throws Exception
261 {
262 return registerComparator( registries, entry.getEntry(), schema );
263 }
264
265
266 /**
267 * Register the comparator contained in the given Entry into the registries.
268 *
269 * @param registries The Registries
270 * @param entry The Entry containing the comparator description
271 * @param schema The associated schema
272 * @throws Exception If the registering failed
273 *
274 protected LdapComparator<?> registerComparator( Registries registries, Entry entry, Schema schema )
275 throws Exception
276 {
277 LdapComparator<?> comparator =
278 factory.getLdapComparator( entry, registries, schema.getSchemaName() );
279 comparator.setOid( entry.get( MetaSchemaConstants.M_OID_AT ).getString() );
280
281 if ( registries.isRelaxed() )
282 {
283 if ( registries.acceptDisabled() )
284 {
285 registries.register( comparator );
286 }
287 else if ( schema.isEnabled() && comparator.isEnabled() )
288 {
289 registries.register( comparator );
290 }
291 }
292 else
293 {
294 if ( schema.isEnabled() && comparator.isEnabled() )
295 {
296 registries.register( comparator );
297 }
298 }
299
300 return comparator;
301 }
302
303
304 /**
305 * Register the SyntaxChecker contained in the given LdifEntry into the registries.
306 *
307 * @param registries The Registries
308 * @param entry The LdifEntry containing the SyntaxChecker description
309 * @param schema The associated schema
310 * @return the created SyntaxChecker instance
311 * @throws Exception If the registering failed
312 *
313 protected SyntaxChecker registerSyntaxChecker( Registries registries, LdifEntry entry, Schema schema)
314 throws Exception
315 {
316 SyntaxChecker syntaxChecker =
317 factory.getSyntaxChecker( entry.getEntry(), registries, schema.getSchemaName() );
318 syntaxChecker.setOid( entry.get( MetaSchemaConstants.M_OID_AT ).getString() );
319
320 if ( registries.isRelaxed() )
321 {
322 if ( registries.acceptDisabled() )
323 {
324 registries.register( syntaxChecker );
325 }
326 else if ( schema.isEnabled() && syntaxChecker.isEnabled() )
327 {
328 registries.register( syntaxChecker );
329 }
330 }
331 else
332 {
333 if ( schema.isEnabled() && syntaxChecker.isEnabled() )
334 {
335 registries.register( syntaxChecker );
336 }
337 }
338
339 return syntaxChecker;
340 }
341
342
343 /**
344 * Register the Normalizer contained in the given LdifEntry into the registries.
345 *
346 * @param registries The Registries
347 * @param entry The LdifEntry containing the Normalizer description
348 * @param schema The associated schema
349 * @return the created Normalizer instance
350 * @throws Exception If the registering failed
351 *
352 protected Normalizer registerNormalizer( Registries registries, LdifEntry entry, Schema schema)
353 throws Exception
354 {
355 Normalizer normalizer =
356 factory.getNormalizer( entry.getEntry(), registries, schema.getSchemaName() );
357
358 if ( registries.isRelaxed() )
359 {
360 if ( registries.acceptDisabled() )
361 {
362 registries.register( normalizer );
363 }
364 else if ( schema.isEnabled() && normalizer.isEnabled() )
365 {
366 registries.register( normalizer );
367 }
368 }
369 else
370 {
371 if ( schema.isEnabled() && normalizer.isEnabled() )
372 {
373 registries.register( normalizer );
374 }
375 }
376
377 return normalizer;
378 }
379
380
381 /**
382 * Register the MatchingRule contained in the given LdifEntry into the registries.
383 *
384 * @param registries The Registries
385 * @param entry The LdifEntry containing the MatchingRule description
386 * @param schema The associated schema
387 * @return the created MatchingRule instance
388 * @throws Exception If the registering failed
389 *
390 protected MatchingRule registerMatchingRule( Registries registries, LdifEntry entry, Schema schema)
391 throws Exception
392 {
393 MatchingRule matchingRule = factory.getMatchingRule(
394 entry.getEntry(), registries, schema.getSchemaName() );
395
396 if ( registries.isRelaxed() )
397 {
398 if ( registries.acceptDisabled() )
399 {
400 registries.register( matchingRule );
401 }
402 else if ( schema.isEnabled() && matchingRule.isEnabled() )
403 {
404 registries.register( matchingRule );
405 }
406 }
407 else
408 {
409 if ( schema.isEnabled() && matchingRule.isEnabled() )
410 {
411 registries.register( matchingRule );
412 }
413 }
414
415 return matchingRule;
416 }
417
418
419 /**
420 * Register the Syntax contained in the given LdifEntry into the registries.
421 *
422 * @param registries The Registries
423 * @param entry The LdifEntry containing the Syntax description
424 * @param schema The associated schema
425 * @return the created Syntax instance
426 * @throws Exception If the registering failed
427 *
428 protected LdapSyntax registerSyntax( Registries registries, LdifEntry entry, Schema schema)
429 throws Exception
430 {
431 LdapSyntax syntax = factory.getSyntax(
432 entry.getEntry(), registries, schema.getSchemaName() );
433
434 if ( registries.isRelaxed() )
435 {
436 if ( registries.acceptDisabled() )
437 {
438 registries.register( syntax );
439 }
440 else if ( schema.isEnabled() && syntax.isEnabled() )
441 {
442 registries.register( syntax );
443 }
444 }
445 else
446 {
447 if ( schema.isEnabled() && syntax.isEnabled() )
448 {
449 registries.register( syntax );
450 }
451 }
452
453 return syntax;
454 }
455
456
457 /**
458 * Register the AttributeType contained in the given LdifEntry into the registries.
459 *
460 * @param registries The Registries
461 * @param entry The LdifEntry containing the AttributeType description
462 * @param schema The associated schema
463 * @return the created AttributeType instance
464 * @throws Exception If the registering failed
465 *
466 protected AttributeType registerAttributeType( Registries registries, LdifEntry entry, Schema schema )
467 throws Exception
468 {
469 AttributeType attributeType = factory.getAttributeType( entry.getEntry(), registries, schema.getSchemaName() );
470
471 if ( registries.isRelaxed() )
472 {
473 if ( registries.acceptDisabled() )
474 {
475 registries.register( attributeType );
476 }
477 else if ( schema.isEnabled() && attributeType.isEnabled() )
478 {
479 registries.register( attributeType );
480 }
481 }
482 else
483 {
484 if ( schema.isEnabled() && attributeType.isEnabled() )
485 {
486 registries.register( attributeType );
487 }
488 }
489
490 return attributeType;
491 }
492
493
494 /**
495 * Register the MatchingRuleUse contained in the given LdifEntry into the registries.
496 *
497 * @param registries The Registries
498 * @param entry The LdifEntry containing the MatchingRuleUse description
499 * @param schema The associated schema
500 * @return the created MatchingRuleUse instance
501 * @throws Exception If the registering failed
502 *
503 protected MatchingRuleUse registerMatchingRuleUse( Registries registries, LdifEntry entry, Schema schema)
504 throws Exception
505 {
506 throw new NotImplementedException( "Need to implement factory " +
507 "method for creating a MatchingRuleUse" );
508 }
509
510
511 /**
512 * Register the NameForm contained in the given LdifEntry into the registries.
513 *
514 * @param registries The Registries
515 * @param entry The LdifEntry containing the NameForm description
516 * @param schema The associated schema
517 * @return the created NameForm instance
518 * @throws Exception If the registering failed
519 *
520 protected NameForm registerNameForm( Registries registries, LdifEntry entry, Schema schema)
521 throws Exception
522 {
523 throw new NotImplementedException( "Need to implement factory " +
524 "method for creating a NameForm" );
525 }
526
527
528 /**
529 * Register the DitContentRule contained in the given LdifEntry into the registries.
530 *
531 * @param registries The Registries
532 * @param entry The LdifEntry containing the DitContentRule description
533 * @param schema The associated schema
534 * @return the created DitContentRule instance
535 * @throws Exception If the registering failed
536 *
537 protected DITContentRule registerDitContentRule( Registries registries, LdifEntry entry, Schema schema)
538 throws Exception
539 {
540 throw new NotImplementedException( "Need to implement factory " +
541 "method for creating a DitContentRule" );
542 }
543
544
545 /**
546 * Register the DitStructureRule contained in the given LdifEntry into the registries.
547 *
548 * @param registries The Registries
549 * @param entry The LdifEntry containing the DitStructureRule description
550 * @param schema The associated schema
551 * @return the created DitStructureRule instance
552 * @throws Exception If the registering failed
553 *
554 protected DITStructureRule registerDitStructureRule( Registries registries, LdifEntry entry, Schema schema)
555 throws Exception
556 {
557 throw new NotImplementedException( "Need to implement factory " +
558 "method for creating a DitStructureRule" );
559 }
560
561
562 /**
563 * Register the ObjectClass contained in the given LdifEntry into the registries.
564 *
565 * @param registries The Registries
566 * @param entry The LdifEntry containing the ObjectClass description
567 * @param schema The associated schema
568 * @return the created ObjectClass instance
569 * @throws Exception If the registering failed
570 *
571 protected ObjectClass registerObjectClass( Registries registries, LdifEntry entry, Schema schema)
572 throws Exception
573 {
574 return registerObjectClass( registries, entry.getEntry(), schema );
575 }
576
577
578 /**
579 * Register the ObjectClass contained in the given LdifEntry into the registries.
580 *
581 * @param registries The Registries
582 * @param entry The Entry containing the ObjectClass description
583 * @param schema The associated schema
584 * @return the created ObjectClass instance
585 * @throws Exception If the registering failed
586 *
587 protected ObjectClass registerObjectClass( Registries registries, Entry entry, Schema schema)
588 throws Exception
589 {
590 ObjectClass objectClass = factory.getObjectClass( entry, registries, schema.getSchemaName() );
591
592 if ( registries.isRelaxed() )
593 {
594 if ( registries.acceptDisabled() )
595 {
596 registries.register( objectClass );
597 }
598 else if ( schema.isEnabled() && objectClass.isEnabled() )
599 {
600 registries.register( objectClass );
601 }
602 }
603 else
604 {
605 if ( schema.isEnabled() && objectClass.isEnabled() )
606 {
607 registries.register( objectClass );
608 }
609 }
610
611 return objectClass;
612 }
613
614
615 public EntityFactory getFactory()
616 {
617 return factory;
618 }
619 */
620
621 public Object getDao()
622 {
623 return null;
624 }
625
626
627 private Schema[] buildSchemaArray( String... schemaNames ) throws Exception
628 {
629 Schema[] schemas = new Schema[schemaNames.length];
630 int pos = 0;
631
632 for ( String schemaName : schemaNames )
633 {
634 schemas[pos++] = getSchema( schemaName );
635 }
636
637 return schemas;
638 }
639
640
641 /**
642 * {@inheritDoc}
643 */
644 public List<Entry> loadAttributeTypes( String... schemaNames ) throws Exception
645 {
646 if ( schemaNames == null )
647 {
648 return new ArrayList<Entry>();
649 }
650
651 return loadAttributeTypes( buildSchemaArray( schemaNames ) );
652 }
653
654
655 /**
656 * {@inheritDoc}
657 */
658 public List<Entry> loadComparators( String... schemaNames ) throws Exception
659 {
660 if ( schemaNames == null )
661 {
662 return new ArrayList<Entry>();
663 }
664
665 return loadComparators( buildSchemaArray( schemaNames ) );
666 }
667
668
669 /**
670 * {@inheritDoc}
671 */
672 public List<Entry> loadDitContentRules( String... schemaNames ) throws Exception
673 {
674 if ( schemaNames == null )
675 {
676 return new ArrayList<Entry>();
677 }
678
679 return loadDitContentRules( buildSchemaArray( schemaNames ) );
680 }
681
682
683 /**
684 * {@inheritDoc}
685 */
686 public List<Entry> loadDitStructureRules( String... schemaNames ) throws Exception
687 {
688 if ( schemaNames == null )
689 {
690 return new ArrayList<Entry>();
691 }
692
693 return loadDitStructureRules( buildSchemaArray( schemaNames ) );
694 }
695
696
697 /**
698 * {@inheritDoc}
699 */
700 public List<Entry> loadMatchingRules( String... schemaNames ) throws Exception
701 {
702 if ( schemaNames == null )
703 {
704 return new ArrayList<Entry>();
705 }
706
707 return loadMatchingRules( buildSchemaArray( schemaNames ) );
708 }
709
710
711 /**
712 * {@inheritDoc}
713 */
714 public List<Entry> loadMatchingRuleUses( String... schemaNames ) throws Exception
715 {
716 if ( schemaNames == null )
717 {
718 return new ArrayList<Entry>();
719 }
720
721 return loadMatchingRuleUses( buildSchemaArray( schemaNames ) );
722 }
723
724
725 /**
726 * {@inheritDoc}
727 */
728 public List<Entry> loadNameForms( String... schemaNames ) throws Exception
729 {
730 if ( schemaNames == null )
731 {
732 return new ArrayList<Entry>();
733 }
734
735 return loadNameForms( buildSchemaArray( schemaNames ) );
736 }
737
738
739 /**
740 * {@inheritDoc}
741 */
742 public List<Entry> loadNormalizers( String... schemaNames ) throws Exception
743 {
744 if ( schemaNames == null )
745 {
746 return new ArrayList<Entry>();
747 }
748
749 return loadNormalizers( buildSchemaArray( schemaNames ) );
750 }
751
752
753 /**
754 * {@inheritDoc}
755 */
756 public List<Entry> loadObjectClasses( String... schemaNames ) throws Exception
757 {
758 if ( schemaNames == null )
759 {
760 return new ArrayList<Entry>();
761 }
762
763 return loadObjectClasses( buildSchemaArray( schemaNames ) );
764 }
765
766
767 /**
768 * {@inheritDoc}
769 */
770 public List<Entry> loadSyntaxes( String... schemaNames ) throws Exception
771 {
772 if ( schemaNames == null )
773 {
774 return new ArrayList<Entry>();
775 }
776
777 return loadSyntaxes( buildSchemaArray( schemaNames ) );
778 }
779
780
781 /**
782 * {@inheritDoc}
783 */
784 public List<Entry> loadSyntaxCheckers( String... schemaNames ) throws Exception
785 {
786 if ( schemaNames == null )
787 {
788 return new ArrayList<Entry>();
789 }
790
791 return loadSyntaxCheckers( buildSchemaArray( schemaNames ) );
792 }
793 }