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.registries; 021 022 023import java.util.Collections; 024import java.util.HashMap; 025import java.util.Iterator; 026import java.util.List; 027import java.util.Map; 028 029import org.apache.commons.lang.ArrayUtils; 030import org.apache.directory.shared.asn1.util.Oid; 031import org.apache.directory.shared.i18n.I18n; 032import org.apache.directory.shared.ldap.model.exception.LdapException; 033import org.apache.directory.shared.ldap.model.schema.SchemaObject; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037 038/** 039 * Object identifier registry. It stores the OIDs for AT, OC, MR, LS, MRU, DSR, DCR and NF. 040 * An OID is unique, and associated with a SO. 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 */ 044public class OidRegistry<T extends SchemaObject> implements Iterable<T> 045{ 046 /** static class logger */ 047 private static final Logger LOG = LoggerFactory.getLogger( OidRegistry.class ); 048 049 /** Speedup for DEBUG mode */ 050 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 051 052 /** Maps OID to a type of SchemaObject */ 053 private Map<String, T> byOid = new HashMap<String, T>(); 054 055 056 /** 057 * Tells if the given OID is present on this registry 058 * 059 * @param oid The OID to lookup 060 * @return true if the OID already exists 061 */ 062 public boolean contains( String oid ) 063 { 064 return byOid.containsKey( oid ); 065 } 066 067 068 /** 069 * Gets the primary name associated with an OID. The primary name is the 070 * first name specified for the OID. 071 * 072 * @param oid the object identifier 073 * @return the primary name 074 * @throws LdapException if oid does not exist 075 */ 076 public String getPrimaryName( String oid ) throws LdapException 077 { 078 SchemaObject schemaObject = byOid.get( oid ); 079 080 if ( schemaObject != null ) 081 { 082 return schemaObject.getName(); 083 } 084 else 085 { 086 String msg = I18n.err( I18n.ERR_04286, oid ); 087 LOG.error( msg ); 088 throw new LdapException( msg ); 089 } 090 } 091 092 093 /** 094 * Gets the SchemaObject associated with an OID. 095 * 096 * @param oid the object identifier 097 * @return the associated SchemaObject 098 * @throws LdapException if oid does not exist 099 */ 100 public T getSchemaObject( String oid ) throws LdapException 101 { 102 T schemaObject = byOid.get( oid ); 103 104 if ( schemaObject != null ) 105 { 106 return schemaObject; 107 } 108 else 109 { 110 String msg = I18n.err( I18n.ERR_04287, oid ); 111 LOG.error( msg ); 112 throw new LdapException( msg ); 113 } 114 } 115 116 117 /** 118 * Gets the names associated with an OID. An OID is unique however it may 119 * have many names used to refer to it. A good example is the cn and 120 * commonName attribute names for OID 2.5.4.3. Within a server one name 121 * within the set must be chosen as the primary name. This is used to 122 * name certain things within the server internally. If there is more than 123 * one name then the first name is taken to be the primary. 124 * 125 * @param oid the OID for which we return the set of common names 126 * @return a sorted set of names 127 * @throws org.apache.directory.shared.ldap.model.exception.LdapException if oid does not exist 128 */ 129 public List<String> getNameSet( String oid ) throws LdapException 130 { 131 SchemaObject schemaObject = byOid.get( oid ); 132 133 if ( null == schemaObject ) 134 { 135 String msg = I18n.err( I18n.ERR_04288, oid ); 136 LOG.error( msg ); 137 throw new LdapException( msg ); 138 } 139 140 List<String> names = schemaObject.getNames(); 141 142 if ( IS_DEBUG ) 143 { 144 LOG.debug( "looked up names '{}' for OID '{}'", ArrayUtils.toString( names ), oid ); 145 } 146 147 return names; 148 } 149 150 151 /** 152 * Lists all the OIDs within the registry. This may be a really big list. 153 * 154 * @return all the OIDs registered 155 */ 156 public Iterator<String> iteratorOids() 157 { 158 return Collections.unmodifiableSet( byOid.keySet() ).iterator(); 159 } 160 161 162 /** 163 * Lists all the SchemaObjects within the registry. This may be a really big list. 164 * 165 * @return all the SchemaObject registered 166 */ 167 public Iterator<T> iterator() 168 { 169 return byOid.values().iterator(); 170 } 171 172 173 /** 174 * Adds an OID name pair to the registry. 175 * 176 * @param schemaObject The SchemaObject the oid belongs to 177 */ 178 public void register( T schemaObject ) throws LdapException 179 { 180 if ( schemaObject == null ) 181 { 182 String message = I18n.err( I18n.ERR_04289 ); 183 184 LOG.debug( message ); 185 throw new LdapException( message ); 186 } 187 188 String oid = schemaObject.getOid(); 189 190 if ( !Oid.isOid( oid ) ) 191 { 192 String message = I18n.err( I18n.ERR_04290 ); 193 194 LOG.debug( message ); 195 throw new LdapException( message ); 196 } 197 198 /* 199 * Update OID Map if it does not already exist 200 */ 201 if ( byOid.containsKey( oid ) ) 202 { 203 String message = I18n.err( I18n.ERR_04291, oid ); 204 LOG.info( message ); 205 return; 206 } 207 else 208 { 209 byOid.put( oid, schemaObject ); 210 211 if ( IS_DEBUG ) 212 { 213 LOG.debug( "registed SchemaObject '" + schemaObject + "' with OID: " + oid ); 214 } 215 } 216 } 217 218 219 /** 220 * Store the given SchemaObject into the OidRegistry. Available only to 221 * the current package. A weak form (no check is done) of the register 222 * method, define for clone methods. 223 * 224 * @param schemaObject The SchemaObject to inject into the OidRegistry 225 */ 226 /* No qualifier */void put( T schemaObject ) 227 { 228 byOid.put( schemaObject.getOid(), schemaObject ); 229 } 230 231 232 /** 233 * Removes an oid from this registry. 234 * 235 * @param oid the numeric identifier for the object 236 * @throws LdapException if the identifier is not numeric 237 */ 238 public void unregister( String oid ) throws LdapException 239 { 240 // Removes the <OID, names> from the byOID map 241 SchemaObject removed = byOid.remove( oid ); 242 243 if ( IS_DEBUG ) 244 { 245 LOG.debug( "Unregisted SchemaObject '{}' with OID: {}", removed, oid ); 246 } 247 } 248 249 250 /** 251 * Copy the OidRegistry, without the contained values 252 * 253 * @return A new OidRegistry instance 254 */ 255 public OidRegistry<T> copy() 256 { 257 OidRegistry<T> copy = new OidRegistry<T>(); 258 259 // Clone the map 260 copy.byOid = new HashMap<String, T>(); 261 262 return copy; 263 } 264 265 266 /** 267 * @return The number of stored OIDs 268 */ 269 public int size() 270 { 271 return byOid.size(); 272 } 273 274 275 public void clear() 276 { 277 // remove all the OID 278 byOid.clear(); 279 } 280 281 282 /** 283 * @see Object#toString() 284 */ 285 public String toString() 286 { 287 StringBuilder sb = new StringBuilder(); 288 289 if ( byOid != null ) 290 { 291 boolean isFirst = true; 292 293 for ( String oid : byOid.keySet() ) 294 { 295 if ( isFirst ) 296 { 297 isFirst = false; 298 } 299 else 300 { 301 sb.append( ", " ); 302 } 303 304 sb.append( "<" ); 305 306 SchemaObject schemaObject = byOid.get( oid ); 307 308 if ( schemaObject != null ) 309 { 310 sb.append( schemaObject.getObjectType() ); 311 sb.append( ", " ); 312 sb.append( schemaObject.getOid() ); 313 sb.append( ", " ); 314 sb.append( schemaObject.getName() ); 315 } 316 317 sb.append( ">" ); 318 } 319 } 320 321 return sb.toString(); 322 } 323}