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.ArrayList;
024    import java.util.Iterator;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.concurrent.ConcurrentHashMap;
028    
029    import javax.naming.NamingException;
030    
031    import org.apache.directory.shared.asn1.primitives.OID;
032    import org.apache.directory.shared.ldap.schema.Normalizer;
033    import org.apache.directory.shared.ldap.schema.parsers.NormalizerDescription;
034    
035    import org.slf4j.Logger;
036    import org.slf4j.LoggerFactory;
037    
038    
039    /**
040     * The POJO implementation for the NormalizerRegistry service.
041     *
042     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043     * @version $Rev: 780471 $
044     */
045    public class DefaultNormalizerRegistry implements NormalizerRegistry
046    {
047        /** static class logger */
048        private static final Logger LOG = LoggerFactory.getLogger( DefaultNormalizerRegistry.class );
049        
050        /** A speedup for debug */
051        private static final boolean DEBUG = LOG.isDebugEnabled();
052        
053        /** a map of Normalizers looked up by OID */
054        private final Map<String,Normalizer> byOidNormalizer;
055        
056        /** maps an OID to a normalizerDescription */
057        private final Map<String,NormalizerDescription> oidToDescription;
058    
059    
060        // ------------------------------------------------------------------------
061        // C O N S T R U C T O R S
062        // ------------------------------------------------------------------------
063    
064    
065        /**
066         * Creates a new default DefaultNormalizerRegistry.
067         */
068        public DefaultNormalizerRegistry()
069        {
070            byOidNormalizer = new ConcurrentHashMap<String, Normalizer>();
071            oidToDescription = new ConcurrentHashMap<String, NormalizerDescription>();
072        }
073    
074    
075        // ------------------------------------------------------------------------
076        // Service Methods
077        // ------------------------------------------------------------------------
078        /**
079         * {@inheritDoc}
080         */
081        public void register( NormalizerDescription description, Normalizer normalizer ) throws NamingException
082        {
083            String oid = description.getNumericOid();
084            
085            if ( byOidNormalizer.containsKey( oid ) )
086            {
087                String msg = "Normalizer already registered for OID " + oid;
088                LOG.warn( msg );
089                throw new NamingException( msg );
090            }
091    
092            oidToDescription.put( oid, description );
093            byOidNormalizer.put( oid, normalizer );
094            
095            if ( DEBUG )
096            {
097                LOG.debug( "registered normalizer with oid: {}", oid );
098            }
099        }
100    
101    
102        /**
103         * {@inheritDoc}
104         */
105        public Normalizer lookup( String oid ) throws NamingException
106        {
107            if ( !byOidNormalizer.containsKey( oid ) )
108            {
109                String msg = "Normalizer for OID " + oid + " does not exist!";
110                LOG.debug( msg );
111                throw new NamingException( msg );
112            }
113    
114            Normalizer normalizer = byOidNormalizer.get( oid );
115            
116            if ( DEBUG )
117            {
118                LOG.debug( "registered normalizer with oid: {}", oid );
119            }
120            
121            return normalizer;
122        }
123    
124    
125        /**
126         * {@inheritDoc}
127         */
128        public boolean hasNormalizer( String oid )
129        {
130            return byOidNormalizer.containsKey( oid );
131        }
132    
133    
134        /**
135         * {@inheritDoc}
136         */
137        public String getSchemaName( String oid ) throws NamingException
138        {
139            if ( !OID.isOID( oid ) )
140            {
141                String msg = "OID " + oid + " is not a numeric OID";
142                LOG.error( msg );
143                throw new NamingException( msg );
144            }
145    
146            NormalizerDescription description = oidToDescription.get( oid );
147            
148            if ( description != null )
149            {
150                return getSchema( description );
151            }
152    
153            String msg = "OID " + oid + " not found in oid to schema name map!";
154            LOG.error( msg );
155            throw new NamingException( msg );
156        }
157    
158    
159        private static String getSchema( NormalizerDescription desc )
160        {
161            List<String> values = desc.getExtensions().get( "X-SCHEMA" );
162            
163            if ( ( values == null ) || ( values.size() == 0 ) )
164            {
165                return "other";
166            }
167            
168            return values.get( 0 );
169        }
170        
171    
172        /**
173         * {@inheritDoc}
174         */
175        public Iterator<String> iterator()
176        {
177            return byOidNormalizer.keySet().iterator();
178        }
179    
180    
181        /**
182         * {@inheritDoc}
183         */
184        public void unregister( String oid ) throws NamingException
185        {
186            if ( !OID.isOID( oid ) )
187            {
188                String msg = "OID " + oid + " is not a numeric OID";
189                LOG.error( msg );
190                throw new NamingException( msg );
191            }
192    
193            byOidNormalizer.remove( oid );
194            oidToDescription.remove( oid );
195        }
196        
197        
198        /**
199         * {@inheritDoc}
200         */
201        public void unregisterSchemaElements( String schemaName )
202        {
203            List<String> oids = new ArrayList<String>( byOidNormalizer.keySet() );
204            
205            for ( String oid : oids )
206            {
207                NormalizerDescription description = oidToDescription.get( oid );
208                String schemaNameForOid = getSchema( description );
209                
210                if ( schemaNameForOid.equalsIgnoreCase( schemaName ) )
211                {
212                    byOidNormalizer.remove( oid );
213                    oidToDescription.remove( oid );
214                }
215            }
216        }
217    
218    
219        /**
220         * {@inheritDoc}
221         */
222        public void renameSchema( String originalSchemaName, String newSchemaName )
223        {
224            List<String> oids = new ArrayList<String>( byOidNormalizer.keySet() );
225            
226            for ( String oid : oids )
227            {
228                NormalizerDescription description = oidToDescription.get( oid );
229                String schemaNameForOid = getSchema( description );
230                
231                if ( schemaNameForOid.equalsIgnoreCase( originalSchemaName ) )
232                {
233                    List<String> schemaExt = description.getExtensions().get( "X-SCHEMA" );
234                    schemaExt.clear();
235                    schemaExt.add( newSchemaName );
236                }
237            }
238        }
239    
240    
241        /**
242         * {@inheritDoc}
243         */
244        public Iterator<NormalizerDescription> normalizerDescriptionIterator()
245        {
246            return oidToDescription.values().iterator();
247        }
248    }