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.server.schema.bootstrap;
021    
022    
023    import java.util.Comparator;
024    
025    import javax.naming.NamingException;
026    
027    import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
028    import org.apache.directory.server.schema.registries.ComparatorRegistry;
029    import org.apache.directory.server.schema.registries.MatchingRuleRegistry;
030    import org.apache.directory.server.schema.registries.NormalizerRegistry;
031    import org.apache.directory.server.schema.registries.ObjectClassRegistry;
032    import org.apache.directory.server.schema.registries.Registries;
033    import org.apache.directory.server.schema.registries.SyntaxCheckerRegistry;
034    import org.apache.directory.server.schema.registries.SyntaxRegistry;
035    import org.apache.directory.shared.ldap.schema.AbstractAttributeType;
036    import org.apache.directory.shared.ldap.schema.AbstractMatchingRule;
037    import org.apache.directory.shared.ldap.schema.AbstractSchemaObject;
038    import org.apache.directory.shared.ldap.schema.AbstractSyntax;
039    import org.apache.directory.shared.ldap.schema.AttributeType;
040    import org.apache.directory.shared.ldap.schema.MatchingRule;
041    import org.apache.directory.shared.ldap.schema.Normalizer;
042    import org.apache.directory.shared.ldap.schema.ObjectClass;
043    import org.apache.directory.shared.ldap.schema.ObjectClassTypeEnum;
044    import org.apache.directory.shared.ldap.schema.Syntax;
045    import org.apache.directory.shared.ldap.schema.SyntaxChecker;
046    import org.apache.directory.shared.ldap.schema.UsageEnum;
047    
048    
049    /**
050     * An abstract producer implementation.
051     *
052     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
053     * @version $Rev: 736240 $
054     */
055    public abstract class AbstractBootstrapProducer implements BootstrapProducer
056    {
057        /** a reused empty String array */
058        protected static final String[] EMPTY = new String[0];
059        /** the producer type */
060        private final ProducerTypeEnum type;
061    
062    
063        /**
064         * Creates a producer of a specific type.
065         *
066         * @param type the producer type
067         */
068        protected AbstractBootstrapProducer(ProducerTypeEnum type)
069        {
070            this.type = type;
071        }
072    
073    
074        /**
075         * @see BootstrapProducer#getType()
076         */
077        public ProducerTypeEnum getType()
078        {
079            return type;
080        }
081    
082    
083        protected static BootstrapSyntax newSyntax( String oid, Registries registries )
084        {
085            return new BootstrapSyntax( oid, registries.getSyntaxCheckerRegistry() );
086        }
087    
088    
089        protected static BootstrapAttributeType newAttributeType( String oid, Registries registries )
090        {
091            return new BootstrapAttributeType( oid, registries );
092        }
093    
094    
095        protected static BootstrapObjectClass newObjectClass( String oid, Registries registries )
096        {
097            return new BootstrapObjectClass( oid, registries );
098        }
099    
100        
101        /**
102         * A mutable Syntax for the bootstrap phase that uses the
103         * syntaxCheckerRegistry to dynamically resolve syntax checkers.
104         */
105        public static class BootstrapSyntax extends AbstractSyntax
106        {
107            private static final long serialVersionUID = 1L;
108            final SyntaxCheckerRegistry registry;
109    
110    
111            public BootstrapSyntax(String oid, SyntaxCheckerRegistry registry)
112            {
113                super( oid );
114                this.registry = registry;
115            }
116            
117            
118            public void setSchema( String schema )
119            {
120                super.setSchema( schema );
121            }
122    
123    
124            public void setDescription( String description )
125            {
126                super.setDescription( description );
127            }
128    
129    
130            public void setHumanReadable( boolean isHumanReadable )
131            {
132                super.setHumanReadable( isHumanReadable );
133            }
134    
135    
136            public void setNames( String[] names )
137            {
138                super.setNames( names );
139            }
140    
141    
142            public SyntaxChecker getSyntaxChecker() throws NamingException
143            {
144                return registry.lookup( getOid() );
145            }
146    
147    
148            public boolean isObsolete()
149            {
150                return false;
151            }
152        }
153    
154        public static class BootstrapMatchingRule extends AbstractMatchingRule
155        {
156            private static final long serialVersionUID = 1L;
157            final SyntaxRegistry syntaxRegistry;
158            final NormalizerRegistry normalizerRegistry;
159            final ComparatorRegistry comparatorRegistry;
160            String syntaxOid;
161    
162    
163            public BootstrapMatchingRule(String oid, Registries registries)
164            {
165                super( oid );
166                this.syntaxRegistry = registries.getSyntaxRegistry();
167                this.normalizerRegistry = registries.getNormalizerRegistry();
168                this.comparatorRegistry = registries.getComparatorRegistry();
169            }
170    
171    
172            public void setNames( String[] names )
173            {
174                super.setNames( names );
175            }
176    
177    
178            public void setSchema( String schema )
179            {
180                super.setSchema( schema );
181            }
182    
183    
184            public void setSyntaxOid( String syntaxOid )
185            {
186                this.syntaxOid = syntaxOid;
187            }
188    
189    
190            public void setDescription( String description )
191            {
192                super.setDescription( description );
193            }
194    
195    
196            public void setObsolete( boolean isObsolete )
197            {
198                super.setObsolete( isObsolete );
199            }
200    
201    
202            // accessors
203    
204            public Syntax getSyntax() throws NamingException
205            {
206                return syntaxRegistry.lookup( syntaxOid );
207            }
208    
209    
210            public Comparator getComparator() throws NamingException
211            {
212                return comparatorRegistry.lookup( getOid() );
213            }
214    
215    
216            public Normalizer getNormalizer() throws NamingException
217            {
218                return normalizerRegistry.lookup( getOid() );
219            }
220        }
221    
222        /**
223         * A concrete mutable attributeType implementation for bootstrapping which
224         * uses registries for dynamically resolving dependent objects.
225         */
226        public static class BootstrapAttributeType extends AbstractAttributeType
227        {
228            private static final long serialVersionUID = 4050205236738471984L;
229    
230            private final SyntaxRegistry syntaxRegistry;
231            private final MatchingRuleRegistry matchingRuleRegistry;
232            private final AttributeTypeRegistry attributeTypeRegistry;
233            private String superiorId;
234            
235            /** The equality OID for this AttributeType */
236            private String equalityId;
237    
238            /** The MatchingRule associated with the equalityID */
239            private MatchingRule equalityMR;
240            
241            /** The substring OID for this AttributeType */
242            private String substrId;
243            
244            /** The MatchingRule associated with the substrID */
245            private MatchingRule substrMR;
246            
247            /** The ordering OID for this AttributeType */
248            private String orderingId;
249            
250            /** The MatchingRule associated with the orderingID */
251            private MatchingRule orderingMR;
252    
253            /** The syntax OID for this attributeType */
254            private String syntaxId;
255            
256            /** The Syntax associated with the syntaxID */
257            private Syntax syntax;
258    
259    
260            public BootstrapAttributeType(String oid, Registries registries)
261            {
262                super( oid );
263    
264                syntaxRegistry = registries.getSyntaxRegistry();
265                matchingRuleRegistry = registries.getMatchingRuleRegistry();
266                attributeTypeRegistry = registries.getAttributeTypeRegistry();
267            }
268    
269    
270            public void setSuperiorId( String superiorId )
271            {
272                this.superiorId = superiorId;
273            }
274    
275    
276            public void setSchema( String schema )
277            {
278                super.setSchema( schema );
279            }
280    
281    
282            public AttributeType getSuperior() throws NamingException
283            {
284                if ( superiorId == null )
285                {
286                    return null;
287                }
288    
289                return this.attributeTypeRegistry.lookup( superiorId );
290            }
291    
292    
293            public void setNames( String[] names )
294            {
295                super.setNames( names );
296            }
297    
298    
299            /**
300             * @return The MatchingRule associated with the AttributeType
301             */
302            public MatchingRule getEquality() throws NamingException
303            {
304                if ( equalityMR == null )
305                {
306                    if ( equalityId != null )
307                    {
308                        equalityMR = this.matchingRuleRegistry.lookup( equalityId );
309                    }
310                    else if ( superiorId != null )
311                    {
312                        equalityMR = getSuperior().getEquality();
313                    }
314                }
315    
316                return equalityMR;
317            }
318    
319    
320            public void setEqualityId( String equalityId )
321            {
322                this.equalityId = equalityId;
323            }
324    
325    
326            public MatchingRule getSubstr() throws NamingException
327            {
328                if ( substrMR == null )
329                {
330                    if ( substrId != null )
331                    {
332                        substrMR = matchingRuleRegistry.lookup( substrId );
333                    }
334                    else if ( superiorId != null )
335                    {
336                        substrMR = getSuperior().getSubstr();
337                    }
338                }
339    
340                return substrMR;
341            }
342    
343    
344            public boolean isAncestorOf( AttributeType attributeType ) throws NamingException
345            {
346                return false;
347            }
348    
349    
350            public boolean isDescendantOf( AttributeType attributeType ) throws NamingException
351            {
352                return false;
353            }
354    
355    
356            public void setSubstrId( String substrId )
357            {
358                this.substrId = substrId;
359            }
360    
361    
362            /**
363             * @return The Ordering Matching Rule associated with this AttributeType
364             */
365            public MatchingRule getOrdering() throws NamingException
366            {
367                if ( orderingMR == null )
368                {
369                    if ( orderingId != null )
370                    {
371                        orderingMR = matchingRuleRegistry.lookup( orderingId );
372                    }
373                    else if ( superiorId != null )
374                    {
375                        orderingMR = getSuperior().getOrdering();
376                    }
377                }
378    
379                return orderingMR;
380            }
381    
382    
383            public void setOrderingId( String orderingId )
384            {
385                this.orderingId = orderingId;
386            }
387    
388    
389            public void setSyntaxId( String syntaxId )
390            {
391                this.syntaxId = syntaxId;
392            }
393    
394    
395            /**
396             * @return The Syntax associated with the AttributeType
397             */
398            public Syntax getSyntax() throws NamingException
399            {
400                if ( syntax == null )
401                {
402                    if ( syntaxId != null )
403                    {
404                        syntax = syntaxRegistry.lookup( syntaxId );
405                    }
406                    else if ( superiorId != null )
407                    {
408                        syntax = getSuperior().getSyntax();
409                    }
410                }
411    
412                return syntax;
413            }
414    
415    
416            public void setSingleValue( boolean singleValue )
417            {
418                super.setSingleValue( singleValue );
419            }
420    
421    
422            public void setCollective( boolean collective )
423            {
424                super.setCollective( collective );
425            }
426    
427    
428            public void setCanUserModify( boolean canUserModify )
429            {
430                super.setCanUserModify( canUserModify );
431            }
432    
433    
434            public void setObsolete( boolean obsolete )
435            {
436                super.setObsolete( obsolete );
437            }
438    
439    
440            public void setDescription( String description )
441            {
442                super.setDescription( description );
443            }
444    
445    
446            public void setUsage( UsageEnum usage )
447            {
448                super.setUsage( usage );
449            }
450    
451    
452            public void setLength( int length )
453            {
454                super.setLength( length );
455            }
456        }
457    
458        /**
459         * A concrete mutable objectClass implementation for bootstrapping which
460         * uses registries for dynamically resolving dependent objects.
461         */
462        public static class BootstrapObjectClass extends AbstractSchemaObject implements ObjectClass
463        {
464            private static final long serialVersionUID = 1L;
465            private final ObjectClassRegistry objectClassRegistry;
466            private final AttributeTypeRegistry attributeTypeRegistry;
467    
468            private String[] superClassIds = EMPTY;
469            private ObjectClass[] superClasses;
470            private ObjectClassTypeEnum type = ObjectClassTypeEnum.STRUCTURAL;
471    
472            private String[] mayListIds = EMPTY;
473            private AttributeType[] mayList;
474    
475            private String[] mustListIds = EMPTY;
476            private AttributeType[] mustList;
477    
478    
479            /**
480             * Creates a mutable ObjectClass for the bootstrap process.
481             *
482             * @param oid the OID of the new objectClass
483             * @param registries the bootstrap registries to use for resolving dependent objects
484             */
485            public BootstrapObjectClass(String oid, Registries registries)
486            {
487                super( oid );
488    
489                objectClassRegistry = registries.getObjectClassRegistry();
490                attributeTypeRegistry = registries.getAttributeTypeRegistry();
491            }
492    
493    
494            // --------------------------------------------------------------------
495            // ObjectClass Accessors
496            // --------------------------------------------------------------------
497    
498            public ObjectClass[] getSuperClasses() throws NamingException
499            {
500                if ( superClasses == null )
501                {
502                    superClasses = new ObjectClass[superClassIds.length];
503                }
504    
505                for ( int ii = 0; ii < superClassIds.length; ii++ )
506                {
507                    superClasses[ii] = objectClassRegistry.lookup( superClassIds[ii] );
508                }
509    
510                return superClasses;
511            }
512    
513    
514            public void setSuperClassIds( String[] superClassIds )
515            {
516                this.superClassIds = superClassIds;
517            }
518    
519    
520            public ObjectClassTypeEnum getType()
521            {
522                return type;
523            }
524    
525            public boolean isStructural()
526            {
527                return type == ObjectClassTypeEnum.STRUCTURAL;
528            }
529    
530            public boolean isAbstract()
531            {
532                return type == ObjectClassTypeEnum.ABSTRACT;
533            }
534    
535            public boolean isAuxiliary()
536            {
537                return type == ObjectClassTypeEnum.AUXILIARY;
538            }
539    
540            public void setSchema( String schema )
541            {
542                super.setSchema( schema );
543            }
544    
545    
546            public void setType( ObjectClassTypeEnum type )
547            {
548                this.type = type;
549            }
550    
551    
552            public AttributeType[] getMustList() throws NamingException
553            {
554                if ( mustList == null )
555                {
556                    mustList = new AttributeType[mustListIds.length];
557                }
558    
559                for ( int ii = 0; ii < mustListIds.length; ii++ )
560                {
561                    mustList[ii] = attributeTypeRegistry.lookup( mustListIds[ii] );
562                }
563    
564                return mustList;
565            }
566    
567    
568            public void setMustListIds( String[] mustListIds )
569            {
570                this.mustListIds = mustListIds;
571            }
572    
573    
574            public AttributeType[] getMayList() throws NamingException
575            {
576                if ( mayList == null )
577                {
578                    mayList = new AttributeType[mayListIds.length];
579                }
580    
581                for ( int ii = 0; ii < mayListIds.length; ii++ )
582                {
583                    mayList[ii] = attributeTypeRegistry.lookup( mayListIds[ii] );
584                }
585    
586                return mayList;
587            }
588    
589    
590            public void setMayListIds( String[] mayListIds )
591            {
592                this.mayListIds = mayListIds;
593            }
594    
595    
596            // --------------------------------------------------------------------
597            // SchemaObject Mutators
598            // --------------------------------------------------------------------
599    
600            public void setObsolete( boolean obsolete )
601            {
602                super.setObsolete( obsolete );
603            }
604    
605    
606            public void setNames( String[] names )
607            {
608                super.setNames( names );
609            }
610    
611    
612            public void setDescription( String description )
613            {
614                super.setDescription( description );
615            }
616    
617        }
618    }