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 */
020package org.apache.directory.shared.ldap.model.schema.normalizers;
021
022
023import org.apache.directory.shared.i18n.I18n;
024import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
025import org.apache.directory.shared.ldap.model.entry.StringValue;
026import org.apache.directory.shared.ldap.model.entry.Value;
027import org.apache.directory.shared.ldap.model.exception.LdapException;
028import org.apache.directory.shared.ldap.model.name.Dn;
029import org.apache.directory.shared.ldap.model.schema.Normalizer;
030import org.apache.directory.shared.ldap.model.schema.SchemaManager;
031import org.apache.directory.shared.util.Strings;
032
033
034/**
035 * A noirmalizer for UniqueMember
036 * 
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 */
039@SuppressWarnings("serial")
040public class UniqueMemberNormalizer extends Normalizer
041{
042    /** A reference to the schema manager used to normalize the Dn */
043    private SchemaManager schemaManager;
044    
045    
046    public UniqueMemberNormalizer()
047    {
048        super( SchemaConstants.UNIQUE_MEMBER_MATCH_MR_OID );
049    }
050    
051
052    public Value<?> normalize( Value<?> value ) throws LdapException
053    {
054        String nameAndUid = value.getString();
055            
056        if ( nameAndUid.length() == 0 )
057        {
058            return null;
059        }
060        
061        // Let's see if we have an UID part
062        int sharpPos = nameAndUid.lastIndexOf( '#' );
063        
064        if ( sharpPos != -1 )
065        {
066            // Now, check that we don't have another '#'
067            if ( nameAndUid.indexOf( '#' ) != sharpPos )
068            {
069                // Yes, we have one : this is not allowed, it should have been
070                // escaped.
071                return null;
072            }
073            
074            // This is an UID if the '#' is immediately
075            // followed by a BitString, except if the '#' is
076            // on the last position
077            String uid = nameAndUid.substring( sharpPos + 1 );
078            
079            if ( sharpPos > 0 )
080            {
081                Dn dn = new Dn( schemaManager, nameAndUid.substring( 0, sharpPos ) );
082                
083                return new StringValue( dn.getNormName() + '#' + uid );
084            }
085            else
086            {
087                throw new IllegalStateException( I18n.err( I18n.ERR_04226, value.getClass() ) );
088            }
089        }
090        else
091        {
092            // No UID, the strValue is a Dn
093            // Return the normalized Dn
094            return new StringValue( new Dn( nameAndUid ).getNormName() );
095        }
096    }
097
098
099    public String normalize( String value ) throws LdapException
100    {
101        if ( Strings.isEmpty(value) )
102        {
103            return null;
104        }
105        
106        // Let's see if we have an UID part
107        int sharpPos = value.lastIndexOf( '#' );
108        
109        if ( sharpPos != -1 )
110        {
111            // Now, check that we don't have another '#'
112            if ( value.indexOf( '#' ) != sharpPos )
113            {
114                // Yes, we have one : this is not allowed, it should have been
115                // escaped.
116                return null;
117            }
118            
119            // This is an UID if the '#' is immediatly
120            // followed by a BitString, except if the '#' is
121            // on the last position
122            String uid = value.substring( sharpPos + 1 );
123            
124            if ( sharpPos > 0 )
125            {
126                Dn dn = new Dn( schemaManager, value.substring( 0, sharpPos ) );
127                
128                return dn.getNormName() + '#' + uid;
129            }
130            else
131            {
132                throw new IllegalStateException( I18n.err( I18n.ERR_04226, value.getClass() ) );
133            }
134        }
135        else
136        {
137            // No UID, the strValue is a Dn
138            // Return the normalized Dn
139            return new Dn( schemaManager, value ).getNormName();
140        }
141    }
142
143
144    /**
145     * {@inheritDoc}
146     */
147    public void setSchemaManager( SchemaManager schemaManager )
148    {
149        this.schemaManager = schemaManager;
150    }
151}