Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/LdapAttribute.java
41161 views
/*1* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jndi.ldap;2627import java.io.IOException;28import java.util.Hashtable;29import java.util.Vector;30import javax.naming.*;31import javax.naming.directory.*;3233/**34* This subclass is used by LDAP to implement the schema calls.35* Basically, it keeps track of which context it is an attribute of36* so it can get the schema for that context.37*38* @author Jon Ruiz39*/40final class LdapAttribute extends BasicAttribute {4142static final long serialVersionUID = -4288716561020779584L;4344private transient DirContext baseCtx = null;45private Name rdn = new CompositeName();4647// these two are used to reconstruct the baseCtx if this attribute has48// been serialized (49private String baseCtxURL;50private Hashtable<String, ? super String> baseCtxEnv;5152@SuppressWarnings("unchecked") // clone()53public Object clone() {54LdapAttribute attr = new LdapAttribute(this.attrID, baseCtx, rdn);55attr.values = (Vector<Object>)values.clone();56return attr;57}5859/**60* Adds a new value to this attribute.61*62* @param attrVal The value to be added. If null, a null value is added to63* the attribute.64* @return true Always returns true.65*/66public boolean add(Object attrVal) {67// LDAP attributes don't contain duplicate values so there's no need68// to check if the value already exists before adding it.69values.addElement(attrVal);70return true;71}7273/**74* Constructs a new instance of an attribute.75*76* @param id The attribute's id. It cannot be null.77*/78LdapAttribute(String id) {79super(id);80}8182/**83* Constructs a new instance of an attribute.84*85* @param id The attribute's id. It cannot be null.86* @param baseCtx the baseCtx object of this attribute87* @param rdn the RDN of the entry (relative to baseCtx)88*/89private LdapAttribute(String id, DirContext baseCtx, Name rdn) {90super(id);91this.baseCtx = baseCtx;92this.rdn = rdn;93}9495/**96* Sets the baseCtx and rdn used to find the attribute's schema97* Used by LdapCtx.setParents().98*/99void setParent(DirContext baseCtx, Name rdn) {100this.baseCtx = baseCtx;101this.rdn = rdn;102}103104/**105* returns the ctx this attribute came from. This call allows106* LDAPAttribute to be serializable. 'baseCtx' is transient so if107* it is null, the `baseCtxURL` is used to reconstruct the context108* to which calls are made.109*/110private DirContext getBaseCtx() throws NamingException {111if(baseCtx == null) {112if (baseCtxEnv == null) {113baseCtxEnv = new Hashtable<String, String>(3);114}115baseCtxEnv.put(Context.INITIAL_CONTEXT_FACTORY,116"com.sun.jndi.ldap.LdapCtxFactory");117baseCtxEnv.put(Context.PROVIDER_URL,baseCtxURL);118baseCtx = (new InitialDirContext(baseCtxEnv));119}120return baseCtx;121}122123/**124* This is called when the object is serialized. It is125* overridden so that the appropriate class variables can be set126* to re-construct the baseCtx when deserialized. Setting these127* variables is costly, so it is only done if the object128* is actually serialized.129*/130private void writeObject(java.io.ObjectOutputStream out)131throws IOException {132133// setup internal state134this.setBaseCtxInfo();135136// let the ObjectOutputStream do the real work of serialization137out.defaultWriteObject();138}139140/**141* sets the information needed to reconstruct the baseCtx if142* we are serialized. This must be called _before_ the object is143* serialized!!!144*/145@SuppressWarnings("unchecked") // clone()146private void setBaseCtxInfo() {147Hashtable<String, Object> realEnv = null;148Hashtable<String, Object> secureEnv = null;149150if (baseCtx != null) {151realEnv = ((LdapCtx)baseCtx).envprops;152this.baseCtxURL = ((LdapCtx)baseCtx).getURL();153}154155if(realEnv != null && realEnv.size() > 0 ) {156// remove any security credentials - otherwise the serialized form157// would store them in the clear158for (String key : realEnv.keySet()){159if (key.indexOf("security") != -1 ) {160161//if we need to remove props, we must do it to a clone162//of the environment. cloning is expensive, so we only do163//it if we have to.164if(secureEnv == null) {165secureEnv = (Hashtable<String, Object>)realEnv.clone();166}167secureEnv.remove(key);168}169}170}171172// set baseCtxEnv depending on whether we removed props or not173this.baseCtxEnv = (secureEnv == null ? realEnv : secureEnv);174}175176/**177* Retrieves the syntax definition associated with this attribute.178* @return This attribute's syntax definition.179*/180public DirContext getAttributeSyntaxDefinition() throws NamingException {181// get the syntax id from the attribute def182DirContext schema = getBaseCtx().getSchema(rdn);183DirContext attrDef = (DirContext)schema.lookup(184LdapSchemaParser.ATTRIBUTE_DEFINITION_NAME + "/" + getID());185186Attribute syntaxAttr = attrDef.getAttributes("").get("SYNTAX");187188if(syntaxAttr == null || syntaxAttr.size() == 0) {189throw new NameNotFoundException(190getID() + " does not have a syntax associated with it");191}192193String syntaxName = (String)syntaxAttr.get();194195// look in the schema tree for the syntax definition196return (DirContext)schema.lookup(197LdapSchemaParser.SYNTAX_DEFINITION_NAME + "/" + syntaxName);198}199200/**201* Retrieves this attribute's schema definition.202*203* @return This attribute's schema definition.204*/205public DirContext getAttributeDefinition() throws NamingException {206DirContext schema = getBaseCtx().getSchema(rdn);207208return (DirContext)schema.lookup(209LdapSchemaParser.ATTRIBUTE_DEFINITION_NAME + "/" + getID());210}211}212213214