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.registries;
021    
022    
023    import java.util.Iterator;
024    import java.util.Map;
025    import java.util.concurrent.ConcurrentHashMap;
026    
027    import javax.naming.NamingException;
028    
029    import org.apache.directory.shared.asn1.primitives.OID;
030    import org.apache.directory.shared.ldap.schema.Syntax;
031    import org.slf4j.Logger;
032    import org.slf4j.LoggerFactory;
033    
034    
035    /**
036     * A SyntaxRegistry service available during server startup when other resources
037     * like a syntax backing store is unavailable.
038     *
039     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
040     * @version $Rev: 778529 $
041     */
042    public class DefaultSyntaxRegistry implements SyntaxRegistry
043    {
044        /** static class logger */
045        private static final Logger LOG = LoggerFactory.getLogger( DefaultSyntaxRegistry.class );
046        
047        /** Speedup for DEBUG mode */
048        private static final boolean IS_DEBUG = LOG.isDebugEnabled();
049        
050        /** a map of entries using an OID for the key and a Syntax for the value */
051        private final Map<String,Syntax> byOidSyntax;
052        
053        /** the OID oidRegistry this oidRegistry uses to register new syntax OIDs */
054        private final OidRegistry oidRegistry;
055    
056    
057        // ------------------------------------------------------------------------
058        // C O N S T R U C T O R S
059        // ------------------------------------------------------------------------
060    
061        /**
062         * Creates a DefaultSyntaxRegistry.
063         *
064         * @param registry used by this registry for OID to name resolution of
065         * dependencies and to automatically register and unregister it's aliases and OIDs
066         */
067        public DefaultSyntaxRegistry( OidRegistry registry )
068        {
069            this.oidRegistry = registry;
070            byOidSyntax = new ConcurrentHashMap<String,Syntax>();
071        }
072    
073    
074        // ------------------------------------------------------------------------
075        // SyntaxRegistry interface methods
076        // ------------------------------------------------------------------------
077        /**
078         * {@inheritDoc}
079         */
080        public Syntax lookup( String id ) throws NamingException
081        {
082            id = oidRegistry.getOid( id );
083            Syntax syntax = byOidSyntax.get( id );
084    
085            if ( syntax != null )
086            {
087                if ( IS_DEBUG )
088                {
089                    LOG.debug( "looked up using id '{}' : {}", id, syntax );
090                }
091                
092                return syntax;
093            }
094    
095            String msg = "Unknown syntax OID " + id;
096            LOG.error( msg );
097            throw new NamingException( msg );
098        }
099    
100    
101        /**
102         * {@inheritDoc}
103         */
104        public void register( Syntax syntax ) throws NamingException
105        {
106            String oid = syntax.getOid();
107            
108            if ( byOidSyntax.containsKey( oid ) )
109            {
110                String msg = "syntax " + syntax + " w/ OID " + oid
111                    + " has already been registered!";
112                LOG.warn( msg );
113                throw new NamingException( msg );
114            }
115    
116            // Register the new Syntax's oid/name relation into the global oidRegistry
117            if ( syntax.getName() != null )
118            {
119                oidRegistry.register( syntax.getName(), oid );
120            }
121    
122            // Also register the oid/oid relation
123            oidRegistry.register( oid, oid );
124            byOidSyntax.put( oid, syntax );
125            
126            if ( IS_DEBUG )
127            {
128                LOG.debug( "registered syntax: {}", syntax );
129            }
130        }
131    
132    
133        /**
134         * {@inheritDoc}
135         */
136        public boolean hasSyntax( String id )
137        {
138            try
139            {
140                String oid = oidRegistry.getOid( id );
141                
142                if ( oid != null )
143                {
144                    return byOidSyntax.containsKey( oid );
145                }
146                
147                return false;
148            }
149            catch ( NamingException e )
150            {
151                return false;
152            }
153        }
154    
155    
156        /**
157         * {@inheritDoc}
158         */
159        public String getSchemaName( String id ) throws NamingException
160        {
161            if ( ! OID.isOID( id ) )
162            {
163                String msg = "Looks like the arg is not a numeric OID";
164                LOG.warn( msg );
165                throw new NamingException( msg );
166            }
167    
168            String oid = oidRegistry.getOid( id );
169            Syntax syntax = byOidSyntax.get( oid );
170           
171            if ( syntax != null )
172            {
173                return syntax.getSchema();
174            }
175    
176            String msg = "OID " + oid + " not found in oid to Syntax map!";
177            LOG.error( msg );
178            throw new NamingException( msg );
179        }
180    
181    
182        /**
183         * {@inheritDoc}
184         */
185        public Iterator<Syntax> iterator()
186        {
187            return byOidSyntax.values().iterator();
188        }
189    
190    
191        /**
192         * {@inheritDoc}
193         */
194        public void unregister( String numericOid ) throws NamingException
195        {
196            if ( !OID.isOID(numericOid ) )
197            {
198                String msg = "Looks like the arg " + numericOid + " is not a numeric OID";
199                LOG.error( msg );
200                throw new NamingException( msg );
201            }
202    
203            byOidSyntax.remove( numericOid );
204        }
205    }