View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.schema;
21  
22  import java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  import java.util.ArrayList;
25  import java.util.Comparator;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Set;
29  
30  import javax.naming.NamingException;
31  
32  import org.apache.directory.server.constants.MetaSchemaConstants;
33  import org.apache.directory.server.core.entry.DefaultServerAttribute;
34  import org.apache.directory.server.core.entry.ServerAttribute;
35  import org.apache.directory.server.core.entry.ServerEntry;
36  import org.apache.directory.server.schema.bootstrap.Schema;
37  import org.apache.directory.server.schema.registries.Registries;
38  import org.apache.directory.shared.ldap.constants.SchemaConstants;
39  import org.apache.directory.shared.ldap.entry.EntryAttribute;
40  import org.apache.directory.shared.ldap.entry.Value;
41  import org.apache.directory.shared.ldap.exception.LdapNamingException;
42  import org.apache.directory.shared.ldap.message.ResultCodeEnum;
43  import org.apache.directory.shared.ldap.schema.AttributeType;
44  import org.apache.directory.shared.ldap.schema.MatchingRule;
45  import org.apache.directory.shared.ldap.schema.MutableSchemaObject;
46  import org.apache.directory.shared.ldap.schema.Normalizer;
47  import org.apache.directory.shared.ldap.schema.ObjectClass;
48  import org.apache.directory.shared.ldap.schema.ObjectClassTypeEnum;
49  import org.apache.directory.shared.ldap.schema.Syntax;
50  import org.apache.directory.shared.ldap.schema.UsageEnum;
51  import org.apache.directory.shared.ldap.schema.syntax.ComparatorDescription;
52  import org.apache.directory.shared.ldap.schema.syntax.NormalizerDescription;
53  import org.apache.directory.shared.ldap.schema.syntax.SyntaxChecker;
54  import org.apache.directory.shared.ldap.schema.syntax.SyntaxCheckerDescription;
55  import org.apache.directory.shared.ldap.util.Base64;
56  
57  
58  /**
59   * Showing how it's done ...
60   *
61   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
62   * @version $Rev$
63   */
64  public class SchemaEntityFactory
65  {
66      /** Used for looking up the setRegistries(Registries) method */
67      private final static Class<?>[] parameterTypes = new Class[] { Registries.class };
68      
69      /** Used for looking up the setSyntaxOid(String) method */
70      private final static Class<?>[] setOidParameterTypes = new Class[] { String.class };
71      
72      private static final String[] EMPTY = new String[0];
73      
74      /** Used for dependency injection of Registries via setter into schema objects */
75      private final Registries bootstrapRegistries;
76      /** A special ClassLoader that loads a class from the bytecode attribute */
77      private final AttributeClassLoader classLoader;
78      private final AttributeType oidAT;
79      private final AttributeType byteCodeAT;
80      
81      
82      public SchemaEntityFactory( Registries bootstrapRegistries ) throws NamingException
83      {
84          this.bootstrapRegistries = bootstrapRegistries;
85          this.classLoader = new AttributeClassLoader();
86          this.oidAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_OID_AT );
87          this.byteCodeAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_BYTECODE_AT );
88      }
89  
90      
91      public Schema getSchema( ServerEntry entry ) throws NamingException
92      {
93          String name;
94          String owner;
95          String[] dependencies = EMPTY;
96          boolean isDisabled = false;
97          
98          if ( entry == null )
99          {
100             throw new NullPointerException( "entry cannot be null" );
101         }
102         
103         if ( entry.get( SchemaConstants.CN_AT ) == null )
104         {
105             throw new NullPointerException( "entry must have a valid cn attribute" );
106         }
107         
108         name = entry.get( SchemaConstants.CN_AT ).getString();
109         
110         if ( entry.get( SchemaConstants.CREATORS_NAME_AT ) == null )
111         {
112             throw new NullPointerException( "entry must have a valid " 
113                 + SchemaConstants.CREATORS_NAME_AT + " attribute" );
114         }
115         
116         owner = entry.get( SchemaConstants.CREATORS_NAME_AT ).getString();
117         
118         if ( entry.get( MetaSchemaConstants.M_DISABLED_AT ) != null )
119         {
120             String value = entry.get( MetaSchemaConstants.M_DISABLED_AT ).getString();
121             value = value.toUpperCase();
122             isDisabled = value.equals( "TRUE" );
123         }
124         
125         if ( entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT ) != null )
126         {
127             Set<String> depsSet = new HashSet<String>();
128             EntryAttribute depsAttr = entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT );
129             
130             for ( Value<?> value:depsAttr )
131             {
132                 depsSet.add( (String)value.get() );
133             }
134 
135             dependencies = depsSet.toArray( EMPTY );
136         }
137         
138         return new AbstractSchema( name, owner, dependencies, isDisabled ){};
139     }
140     
141     
142     private SyntaxChecker getSyntaxChecker( String syntaxOid, String className, EntryAttribute bytecode, Registries targetRegistries )
143         throws NamingException
144     {
145         Class<?> clazz = null;
146         SyntaxChecker syntaxChecker = null;
147         
148         try
149         {
150             if ( bytecode == null )
151             {
152                 clazz = Class.forName( className );
153             }
154             else
155             {
156                 classLoader.setAttribute( bytecode );
157                 clazz = classLoader.loadClass( className );
158             }
159         }
160         catch ( ClassNotFoundException e )
161         {
162             LdapNamingException ne = new LdapNamingException( 
163                 "Normalizer class "+ className + " was not found", ResultCodeEnum.OTHER );
164             ne.setRootCause( e );
165             throw ne;
166         }
167         
168         try
169         {
170             syntaxChecker = ( SyntaxChecker ) clazz.newInstance();
171         }
172         catch ( InstantiationException e )
173         {
174             LdapNamingException ne = new LdapNamingException( "Failed to instantiate SyntaxChecker class "+ className 
175                 + ".\nCheck that a default constructor exists for the class.", ResultCodeEnum.OTHER );
176             ne.setRootCause( e );
177             throw ne;
178         }
179         catch ( IllegalAccessException e )
180         {
181             LdapNamingException ne = new LdapNamingException( "Failed to instantiate SyntaxChecker class "+ className 
182                 + ".\nCheck that a **PUBLIC** accessible default constructor exists for the class.", 
183                 ResultCodeEnum.OTHER );
184             ne.setRootCause( e );
185             throw ne;
186         }
187 
188         // try now before returning to check if we can inject a Registries object
189         injectRegistries( syntaxChecker, targetRegistries );
190         injectOid( syntaxOid, syntaxChecker );
191         return syntaxChecker;
192     }
193     
194     
195     /**
196      * Retrieve and load a syntaxChecker class from the DIT.
197      * 
198      * @param entry the entry to load the syntaxChecker from
199      * @return the loaded SyntaxChecker
200      * @throws NamingException if anything fails during loading
201      */
202     public SyntaxChecker getSyntaxChecker( ServerEntry entry, Registries targetRegistries ) throws NamingException
203     {
204         if ( entry == null )
205         {
206             throw new NullPointerException( "entry cannot be null" );
207         }
208         
209         if ( entry.get( MetaSchemaConstants.M_FQCN_AT ) == null )
210         {
211             throw new NullPointerException( "entry must have a valid "
212                 + MetaSchemaConstants.M_FQCN_AT + " attribute" );
213         }
214 
215         String className = ( String ) entry.get( MetaSchemaConstants.M_FQCN_AT ).get().get();
216         String syntaxOid = ( String ) entry.get( oidAT ).get().get();
217         return getSyntaxChecker( syntaxOid, className, entry.get( byteCodeAT ), 
218             targetRegistries );
219     }
220     
221     
222     public SyntaxChecker getSyntaxChecker( SyntaxCheckerDescription syntaxCheckerDescription, 
223         Registries targetRegistries ) throws NamingException
224     {
225         ServerAttribute attr = null;
226         
227         if ( syntaxCheckerDescription.getBytecode() != null )
228         {
229             byte[] bytecode = Base64.decode( syntaxCheckerDescription.getBytecode().toCharArray() );
230             AttributeType byteCodeAT = targetRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_BYTECODE_AT );
231             attr = new DefaultServerAttribute( byteCodeAT, bytecode );
232         }
233         
234         return getSyntaxChecker( syntaxCheckerDescription.getNumericOid(), 
235             syntaxCheckerDescription.getFqcn(), attr, targetRegistries );
236     }
237     
238     
239     private Comparator getComparator( String className, EntryAttribute bytecode, Registries targetRegistries ) 
240         throws NamingException
241     {
242         Comparator comparator = null;
243         Class<?> clazz = null;
244         
245         if ( bytecode == null ) 
246         {
247             try
248             {
249                 clazz = Class.forName( className );
250             }
251             catch ( ClassNotFoundException e )
252             {
253                 LdapNamingException ne = new LdapNamingException( "Comparator class "+ className + " was not found",
254                     ResultCodeEnum.OTHER );
255                 ne.setRootCause( e );
256                 throw ne;
257             }
258         }
259         else
260         {
261             classLoader.setAttribute( bytecode );
262             
263             try
264             {
265                 clazz = classLoader.loadClass( className );
266             }
267             catch ( ClassNotFoundException e )
268             {
269                 LdapNamingException ne = new LdapNamingException( "Comparator class "+ className + " was not found",
270                     ResultCodeEnum.OTHER );
271                 ne.setRootCause( e );
272                 throw ne;
273             }
274         }
275         
276         try
277         {
278             comparator = ( Comparator ) clazz.newInstance();
279         }
280         catch ( InstantiationException e )
281         {
282             NamingException ne = new NamingException( "Failed to instantiate comparator class "+ className 
283                 + ".\nCheck that a default constructor exists for the class." );
284             ne.setRootCause( e );
285             throw ne;
286         }
287         catch ( IllegalAccessException e )
288         {
289             NamingException ne = new NamingException( "Failed to instantiate comparator class "+ className 
290                 + ".\nCheck that a **PUBLIC** accessible default constructor exists for the class." );
291             ne.setRootCause( e );
292             throw ne;
293         }
294         
295         injectRegistries( comparator, targetRegistries );
296         return comparator;
297     }
298     
299     
300     public Comparator getComparator( ComparatorDescription comparatorDescription, Registries targetRegistries ) 
301         throws NamingException
302     {
303         ServerAttribute attr = null;
304         
305         if ( comparatorDescription.getBytecode() != null )
306         { 
307             byte[] bytecode = Base64.decode( comparatorDescription.getBytecode().toCharArray() );
308             AttributeType byteCodeAT = targetRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_BYTECODE_AT );
309             attr = new DefaultServerAttribute( byteCodeAT, bytecode );
310         }
311         
312         return getComparator( comparatorDescription.getFqcn(), attr, targetRegistries );
313     }
314     
315     
316     /**
317      * Retrieve and load a Comparator class from the DIT.
318      * 
319      * @param entry the entry to load the Comparator from
320      * @return the loaded Comparator
321      * @throws NamingException if anything fails during loading
322      */
323     public Comparator getComparator( ServerEntry entry, Registries targetRegistries ) throws NamingException
324     {
325         if ( entry == null )
326         {
327             throw new NullPointerException( "entry cannot be null" );
328         }
329         
330         if ( entry.get( MetaSchemaConstants.M_FQCN_AT ) == null )
331         {
332             throw new NullPointerException( "entry must have a valid " 
333                 + MetaSchemaConstants.M_FQCN_AT + " attribute" );
334         }
335         
336         String className = ( String ) entry.get( MetaSchemaConstants.M_FQCN_AT ).get().get();
337         return getComparator( className, entry.get( MetaSchemaConstants.M_BYTECODE_AT ), targetRegistries );
338     }
339     
340     
341     private Normalizer getNormalizer( String className, EntryAttribute bytecode, Registries targetRegistries ) 
342         throws NamingException
343     {
344         Class<?> clazz = null;
345         Normalizer normalizer = null;
346         
347         try
348         {
349             if ( bytecode == null )
350             {
351                 clazz = Class.forName( className );
352             }
353             else
354             {
355                 classLoader.setAttribute( bytecode );
356                 clazz = classLoader.loadClass( className );
357             }
358         }
359         catch ( ClassNotFoundException e )
360         {
361             LdapNamingException ne = new LdapNamingException( 
362                 "Normalizer class "+ className + " was not found", ResultCodeEnum.OTHER );
363             ne.setRootCause( e );
364             throw ne;
365         }
366         
367         try
368         {
369             normalizer = ( Normalizer ) clazz.newInstance();
370         }
371         catch ( InstantiationException e )
372         {
373             LdapNamingException ne = new LdapNamingException( "Failed to instantiate normalizer class "+ className 
374                 + ".\nCheck that a default constructor exists for the class.", ResultCodeEnum.OTHER );
375             ne.setRootCause( e );
376             throw ne;
377         }
378         catch ( IllegalAccessException e )
379         {
380             LdapNamingException ne = new LdapNamingException( "Failed to instantiate normalizer class "+ className 
381                 + ".\nCheck that a **PUBLIC** accessible default constructor exists for the class.", 
382                 ResultCodeEnum.OTHER );
383             ne.setRootCause( e );
384             throw ne;
385         }
386 
387         // try now before returning to check if we can inject a Registries object
388         injectRegistries( normalizer, targetRegistries );
389         return normalizer;
390     }
391 
392     
393     public Normalizer getNormalizer( NormalizerDescription normalizerDescription, Registries targetRegistries )
394         throws NamingException
395     {
396         ServerAttribute attr = null;
397         
398         if ( normalizerDescription.getBytecode() != null )
399         {
400             byte[] bytecode = Base64.decode( normalizerDescription.getBytecode().toCharArray() );
401             AttributeType byteCodeAT = targetRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_BYTECODE_AT );
402             attr = new DefaultServerAttribute( byteCodeAT, bytecode );
403         }
404         
405         return getNormalizer( normalizerDescription.getFqcn(), attr, targetRegistries );
406     }
407     
408     
409     /**
410      * Retrieve and load a Normalizer class from the DIT.
411      * 
412      * @param entry the entry to load the Normalizer from
413      * @return the loaded Normalizer
414      * @throws NamingException if anything fails during loading
415      */
416     public Normalizer getNormalizer( ServerEntry entry, Registries targetRegistries ) throws NamingException
417     {
418         if ( entry == null )
419         {
420             throw new NullPointerException( "entry cannot be null" );
421         }
422         
423         if ( entry.get( MetaSchemaConstants.M_FQCN_AT ) == null )
424         {
425             throw new NullPointerException( "entry must have a valid " 
426                 + MetaSchemaConstants.M_FQCN_AT + " attribute" );
427         }
428         
429         String className = ( String ) entry.get( MetaSchemaConstants.M_FQCN_AT ).get().get();
430         return getNormalizer( className, entry.get( MetaSchemaConstants.M_BYTECODE_AT ), targetRegistries );
431     }
432     
433     
434     /**
435      * Uses reflection to see if a setRegistries( Registries ) method exists on the
436      * object's class.  If so then the registries are dependency injected into the 
437      * new schema object.
438      * 
439      * @param obj a schema object to have a Registries dependency injected.
440      */
441     private void injectRegistries( Object obj, Registries targetRegistries ) throws NamingException
442     {
443         String className = obj.getClass().getName();
444         
445         try
446         {
447             Method method = obj.getClass().getMethod( "setRegistries", parameterTypes );
448             
449             if ( method == null )
450             {
451                 return;
452             }
453             
454             Object[] args = new Object[] { this.bootstrapRegistries };
455             method.invoke( obj, args );
456         }
457         catch ( SecurityException e )
458         {
459             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
460                 + " could not have the Registries dependency injected." );
461             ne.setRootCause( e );
462             throw ne;
463         }
464         catch ( NoSuchMethodException e )
465         {
466             // this is ok since not every object may have setRegistries()
467         }
468         catch ( IllegalArgumentException e )
469         {
470             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
471                 + " could not have the Registries dependency injected." );
472             ne.setRootCause( e );
473             throw ne;
474         }
475         catch ( IllegalAccessException e )
476         {
477             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
478                 + " could not have the Registries dependency injected." );
479             ne.setRootCause( e );
480             throw ne;
481         }
482         catch ( InvocationTargetException e )
483         {
484             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
485                 + " could not have the Registries dependency injected." );
486             ne.setRootCause( e );
487             throw ne;
488         }
489     }
490 
491 
492     /**
493      * Uses reflection to see if a setSyntaxOid( String ) method exists 
494      * on the object's class.  If so then the oid dependency is injected into the 
495      * new SyntaxChecker.
496      * 
497      * @param obj a schema object to have a oid dependency injected.
498      */
499     private void injectOid( String syntaxOid, SyntaxChecker checker ) throws NamingException
500     {
501         String className = checker.getClass().getName();
502         
503         try
504         {
505             Method method = checker.getClass().getMethod( "setSyntaxOid", setOidParameterTypes );
506             
507             if ( method == null )
508             {
509                 return;
510             }
511             
512             Object[] args = new Object[] { syntaxOid};
513             method.invoke( checker, args );
514         }
515         catch ( SecurityException e )
516         {
517             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
518                 + " could not have the oid dependency injected." );
519             ne.setRootCause( e );
520             throw ne;
521         }
522         catch ( NoSuchMethodException e )
523         {
524             // this is ok since not every object may have setSyntaxOid()
525         }
526         catch ( IllegalArgumentException e )
527         {
528             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
529                 + " could not have the oid dependency injected." );
530             ne.setRootCause( e );
531             throw ne;
532         }
533         catch ( IllegalAccessException e )
534         {
535             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
536                 + " could not have the oid dependency injected." );
537             ne.setRootCause( e );
538             throw ne;
539         }
540         catch ( InvocationTargetException e )
541         {
542             NamingException ne = new NamingException( "SyntaxChecker class "+ className 
543                 + " could not have the oid dependency injected." );
544             ne.setRootCause( e );
545             throw ne;
546         }
547     }
548 
549 
550     public Syntax getSyntax( ServerEntry entry, Registries targetRegistries, String schema ) throws NamingException
551     {
552         String oid = entry.get( MetaSchemaConstants.M_OID_AT ).getString();
553         SyntaxImpl syntax = new SyntaxImpl( oid, targetRegistries.getSyntaxCheckerRegistry() );
554         syntax.setSchema( schema );
555         
556         if ( entry.get( MetaSchemaConstants.X_HUMAN_READABLE_AT ) != null )
557         {
558             String val = entry.get( MetaSchemaConstants.X_HUMAN_READABLE_AT ).getString();
559             syntax.setHumanReadable( val.toUpperCase().equals( "TRUE" ) );
560         }
561         
562         if ( entry.get( MetaSchemaConstants.M_DESCRIPTION_AT ) != null )
563         {
564             syntax.setDescription( entry.get( MetaSchemaConstants.M_DESCRIPTION_AT ).getString() ); 
565         }
566         
567         return syntax;
568     }
569 
570     
571     public MatchingRule getMatchingRule( ServerEntry entry, Registries targetRegistries, String schema ) throws NamingException
572     {
573         String oid = entry.get( MetaSchemaConstants.M_OID_AT ).getString();
574         String syntaxOid = entry.get( MetaSchemaConstants.M_SYNTAX_AT ).getString();
575         MatchingRuleImpl mr = new MatchingRuleImpl( oid, syntaxOid, targetRegistries );
576         mr.setSchema( schema );
577         setSchemaObjectProperties( mr, entry );
578         return mr;
579     }
580     
581     
582     private String[] getStrings( EntryAttribute attr ) throws NamingException
583     {
584         if ( attr == null )
585         {
586             return EMPTY;
587         }
588         
589         String[] strings = new String[attr.size()];
590         
591         int pos = 0;
592         
593         for ( Value<?> value:attr )
594         {
595             strings[pos++] = (String)value.get();
596         }
597         
598         return strings;
599     }
600     
601     
602     public ObjectClass getObjectClass( ServerEntry entry, Registries targetRegistries, String schema ) throws NamingException
603     {
604         String oid = entry.get( MetaSchemaConstants.M_OID_AT ).getString();
605         ObjectClassImpl oc = new ObjectClassImpl( oid, targetRegistries );
606         oc.setSchema( schema );
607         
608         if ( entry.get( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT ) != null )
609         {
610             oc.setSuperClassOids( getStrings( entry.get( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT ) ) );
611         }
612         
613         if ( entry.get( MetaSchemaConstants.M_MAY_AT ) != null )
614         {
615             oc.setMayListOids( getStrings( entry.get( MetaSchemaConstants.M_MAY_AT ) ) );
616         }
617         
618         if ( entry.get( MetaSchemaConstants.M_MUST_AT ) != null )
619         {
620             oc.setMustListOids( getStrings( entry.get( MetaSchemaConstants.M_MUST_AT ) ) );
621         }
622         
623         if ( entry.get( MetaSchemaConstants.M_TYPE_OBJECT_CLASS_AT ) != null )
624         {
625             String type = entry.get( MetaSchemaConstants.M_TYPE_OBJECT_CLASS_AT ).getString();
626             oc.setType( ObjectClassTypeEnum.getClassType( type ) );
627         }
628         else
629         {
630             oc.setType( ObjectClassTypeEnum.STRUCTURAL );
631         }
632         
633         setSchemaObjectProperties( oc, entry );
634         
635         return oc;
636     }
637     
638     
639     public AttributeType getAttributeType( ServerEntry entry, Registries targetRegistries, String schema ) throws NamingException
640     {
641         String oid = entry.get( MetaSchemaConstants.M_OID_AT ).getString();
642         AttributeTypeImpl at = new AttributeTypeImpl( oid, targetRegistries );
643         at.setSchema( schema );
644         setSchemaObjectProperties( at, entry );
645         
646         if ( entry.get( MetaSchemaConstants.M_SYNTAX_AT ) != null )
647         {
648             at.setSyntaxOid( entry.get( MetaSchemaConstants.M_SYNTAX_AT ).getString() );
649         }
650         
651         if ( entry.get( MetaSchemaConstants.M_EQUALITY_AT ) != null )
652         {
653             at.setEqualityOid( entry.get( MetaSchemaConstants.M_EQUALITY_AT ).getString() );
654         }
655         
656         if ( entry.get( MetaSchemaConstants.M_ORDERING_AT ) != null )
657         {
658             at.setOrderingOid( entry.get( MetaSchemaConstants.M_ORDERING_AT ).getString() );
659         }
660         
661         if ( entry.get( MetaSchemaConstants.M_SUBSTR_AT ) != null )
662         {
663             at.setSubstrOid( entry.get( MetaSchemaConstants.M_SUBSTR_AT ).getString() );
664         }
665         
666         if ( entry.get( MetaSchemaConstants.M_SUP_ATTRIBUTE_TYPE_AT ) != null )
667         {
668             at.setSuperiorOid( entry.get( MetaSchemaConstants.M_SUP_ATTRIBUTE_TYPE_AT ).getString() );
669         }
670         
671         if ( entry.get( MetaSchemaConstants.M_COLLECTIVE_AT ) != null )
672         {
673             String val = entry.get( MetaSchemaConstants.M_COLLECTIVE_AT ).getString();
674             at.setCollective( val.equalsIgnoreCase( "TRUE" ) );
675         }
676         
677         if ( entry.get( MetaSchemaConstants.M_SINGLE_VALUE_AT ) != null )
678         {
679             String val = entry.get( MetaSchemaConstants.M_SINGLE_VALUE_AT ).getString();
680             at.setSingleValue( val.equalsIgnoreCase( "TRUE" ) );
681         }
682         
683         if ( entry.get( MetaSchemaConstants.M_NO_USER_MODIFICATION_AT ) != null )
684         {
685             String val = entry.get( MetaSchemaConstants.M_NO_USER_MODIFICATION_AT ).getString();
686             at.setCanUserModify( ! val.equalsIgnoreCase( "TRUE" ) );
687         }
688         
689         if ( entry.get( MetaSchemaConstants.M_USAGE_AT ) != null )
690         {
691             at.setUsage( UsageEnum.getUsage( entry.get( MetaSchemaConstants.M_USAGE_AT ).getString() ) );
692         }
693         
694         return at;
695     }
696     
697 
698     private void setSchemaObjectProperties( MutableSchemaObject mso, ServerEntry entry ) throws NamingException
699     {
700         if ( entry.get( MetaSchemaConstants.M_OBSOLETE_AT ) != null )
701         {
702             String val = entry.get( MetaSchemaConstants.M_OBSOLETE_AT ).getString();
703             mso.setObsolete( val.equalsIgnoreCase( "TRUE" ) );
704         }
705         
706         if ( entry.get( MetaSchemaConstants.M_DESCRIPTION_AT ) != null )
707         {
708             mso.setDescription( entry.get( MetaSchemaConstants.M_DESCRIPTION_AT ).getString() ); 
709         }
710 
711         EntryAttribute names = entry.get( MetaSchemaConstants.M_NAME_AT );
712         
713         if ( names != null )
714         {
715             List<String> values = new ArrayList<String>();
716             
717             for ( Value<?> name:names )
718             {
719                 values.add( (String)name.get() );
720             }
721             
722             mso.setNames( values.toArray( EMPTY ) );
723         }
724     }
725 }