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 java.io.UnsupportedEncodingException; 024 025import org.apache.directory.shared.i18n.I18n; 026import org.apache.directory.shared.ldap.model.entry.BinaryValue; 027import org.apache.directory.shared.ldap.model.exception.LdapException; 028import org.apache.directory.shared.ldap.model.schema.AttributeType; 029import org.apache.directory.shared.ldap.model.schema.MatchingRule; 030import org.apache.directory.shared.ldap.model.schema.Normalizer; 031import org.apache.directory.shared.ldap.model.schema.SchemaManager; 032import org.apache.directory.shared.util.Hex; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036 037/** 038 * A Dn Name component Normalizer which uses the bootstrap registries to find 039 * the appropriate normalizer for the attribute of the name component with which 040 * to normalize the name component value. 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 */ 044public class ConcreteNameComponentNormalizer implements NameComponentNormalizer 045{ 046 /** The LoggerFactory used by this Interceptor */ 047 private static final Logger LOG = LoggerFactory.getLogger( ConcreteNameComponentNormalizer.class ); 048 049 /** the schemaManager used to dynamically resolve Normalizers */ 050 private final SchemaManager schemaManager; 051 052 053 /** 054 * Creates a Dn Name component Normalizer which uses the bootstrap 055 * registries to find the appropriate normalizer for the attribute of the 056 * name component with which to normalize the name component value. 057 * 058 * @param schemaManager the schemaManager used to dynamically resolve Normalizers 059 */ 060 public ConcreteNameComponentNormalizer( SchemaManager schemaManager ) 061 { 062 this.schemaManager = schemaManager; 063 } 064 065 066 private String unescape( String value ) 067 { 068 char[] newVal = new char[value.length()]; 069 int escaped = 0; 070 char high = 0; 071 char low = 0; 072 int pos = 0; 073 074 for ( char c:value.toCharArray() ) 075 { 076 switch ( escaped ) 077 { 078 case 0 : 079 if ( c == '\\' ) 080 { 081 escaped = 1; 082 } 083 else 084 { 085 newVal[pos++] = c; 086 } 087 088 break; 089 090 case 1 : 091 escaped++; 092 high = c; 093 break; 094 095 case 2 : 096 escaped=0; 097 low = c; 098 newVal[pos++] = (char) Hex.getHexValue(high, low); 099 100 } 101 } 102 103 return new String( newVal, 0, pos ); 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 public Object normalizeByName( String name, String value ) throws LdapException 110 { 111 AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( name ); 112 113 if ( attributeType.getSyntax().isHumanReadable() ) 114 { 115 return lookup( name ).normalize( value ); 116 } 117 else 118 { 119 try 120 { 121 String unescaped = unescape( value ); 122 byte[] valBytes = unescaped.getBytes( "UTF-8" ); 123 124 return lookup( name ).normalize( new BinaryValue( valBytes ) ); 125 } 126 catch ( UnsupportedEncodingException uee ) 127 { 128 String message = I18n.err( I18n.ERR_04222 ); 129 LOG.error( message ); 130 throw new LdapException( message, uee ); 131 } 132 } 133 134 } 135 136 137 /** 138 * {@inheritDoc} 139 */ 140 public Object normalizeByName( String name, byte[] value ) throws LdapException 141 { 142 AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( name ); 143 144 if ( !attributeType.getSyntax().isHumanReadable() ) 145 { 146 return lookup( name ).normalize( new BinaryValue( value ) ); 147 } 148 else 149 { 150 try 151 { 152 String valStr = new String( value, "UTF-8" ); 153 return lookup( name ).normalize( valStr ); 154 } 155 catch ( UnsupportedEncodingException uee ) 156 { 157 String message = I18n.err( I18n.ERR_04223 ); 158 LOG.error( message ); 159 throw new LdapException( message, uee ); 160 } 161 } 162 } 163 164 165 /** 166 * {@inheritDoc} 167 */ 168 public Object normalizeByOid( String oid, String value ) throws LdapException 169 { 170 return lookup( oid ).normalize( value ); 171 } 172 173 174 /** 175 * {@inheritDoc} 176 */ 177 public Object normalizeByOid( String oid, byte[] value ) throws LdapException 178 { 179 return lookup( oid ).normalize( new BinaryValue( value ) ); 180 } 181 182 183 /** 184 * Looks up the Normalizer to use for a name component using the attributeId 185 * for the name component. First the attribute is resolved, then its 186 * equality matching rule is looked up. The normalizer of that matching 187 * rule is returned. 188 * 189 * @param id the name or oid of the attribute in the name component to 190 * normalize the value of 191 * @return the Normalizer to use for normalizing the value of the attribute 192 * @throws LdapException if there are failures resolving the Normalizer 193 */ 194 private Normalizer lookup( String id ) throws LdapException 195 { 196 AttributeType type = schemaManager.lookupAttributeTypeRegistry( id ); 197 MatchingRule mrule = type.getEquality(); 198 199 if ( mrule == null ) 200 { 201 return new NoOpNormalizer( id ); 202 } 203 204 return mrule.getNormalizer(); 205 } 206 207 208 /** 209 * @see NameComponentNormalizer#isDefined(String) 210 */ 211 public boolean isDefined( String id ) 212 { 213 return schemaManager.getAttributeTypeRegistry().contains( id ); 214 } 215 216 217 public String normalizeName( String attributeName ) throws LdapException 218 { 219 return schemaManager.getAttributeTypeRegistry().getOidByName( attributeName ); 220 } 221}