001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.jndi.provider.ldap;
019:
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.HashSet;
023: import java.util.List;
024:
025: import javax.naming.NameNotFoundException;
026: import javax.naming.NamingEnumeration;
027: import javax.naming.NamingException;
028: import javax.naming.directory.Attribute;
029: import javax.naming.directory.BasicAttribute;
030: import javax.naming.directory.DirContext;
031:
032: import org.apache.harmony.jndi.internal.nls.Messages;
033: import org.apache.harmony.jndi.provider.ldap.asn1.ASN1Decodable;
034: import org.apache.harmony.jndi.provider.ldap.asn1.ASN1Encodable;
035: import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
036:
037: /**
038: * This class add supports to <code>getAttributeDefinition()</code> and
039: * <code>getAttributeSyntaxDefinition()</code> methods.
040: *
041: */
042: public class LdapAttribute extends BasicAttribute implements
043: ASN1Decodable, ASN1Encodable {
044:
045: private static final long serialVersionUID = -6492847268062616321L;
046:
047: /**
048: * TODO: when to initialize it?
049: */
050: private DirContext attributeDefinition = null;
051:
052: /**
053: * TODO: when to initialize it?
054: */
055: private DirContext attributeSyntaxDefinition = null;
056:
057: /**
058: * whether the value of attribute is binary
059: */
060: private boolean isBinary;
061:
062: private LdapContextImpl context = null;
063:
064: private static HashSet<String> BINARY_ATTRIBUTE = new HashSet<String>();
065: static {
066: BINARY_ATTRIBUTE.add("photo");
067: BINARY_ATTRIBUTE.add("personalSignature");
068: BINARY_ATTRIBUTE.add("audio");
069: BINARY_ATTRIBUTE.add("jpegPhoto");
070: BINARY_ATTRIBUTE.add("javaSerializedData");
071: BINARY_ATTRIBUTE.add("thumbnailPhoto");
072: BINARY_ATTRIBUTE.add("thumbnailLogo");
073: BINARY_ATTRIBUTE.add("userPassword");
074: BINARY_ATTRIBUTE.add("userCertificate");
075: BINARY_ATTRIBUTE.add("cACertificate");
076: BINARY_ATTRIBUTE.add("authorityRevocationList");
077: BINARY_ATTRIBUTE.add("certificateRevocationList");
078: BINARY_ATTRIBUTE.add("crossCertificatePair");
079: BINARY_ATTRIBUTE.add("x500UniqueIdentifier");
080: }
081:
082: /**
083: * constructor for decode
084: *
085: */
086: public LdapAttribute() {
087: super ("", false); //$NON-NLS-1$
088: }
089:
090: public LdapAttribute(String id, LdapContextImpl ctx) {
091: super (id, false);
092: isBinary = isBinary(id);
093: context = ctx;
094: }
095:
096: void setContext(LdapContextImpl ctx) {
097: context = ctx;
098: }
099:
100: /**
101: * Constructs instance from already existing <code>Attribute</code>
102: *
103: * @param attr
104: * may never be <code>null</code>
105: * @throws NamingException
106: */
107: public LdapAttribute(Attribute attr, LdapContextImpl ctx)
108: throws NamingException {
109: super (attr.getID(), attr.isOrdered());
110: isBinary = isBinary(getID());
111: NamingEnumeration<?> enu = attr.getAll();
112: while (enu.hasMore()) {
113: Object value = enu.next();
114: add(value);
115: }
116:
117: attributeDefinition = null;
118: attributeSyntaxDefinition = null;
119: context = ctx;
120: }
121:
122: @SuppressWarnings("unchecked")
123: public void decodeValues(Object[] vs) {
124: byte[] type = (byte[]) vs[0];
125: attrID = Utils.getString(type);
126: isBinary = isBinary(attrID);
127: Collection<byte[]> list = (Collection<byte[]>) vs[1];
128: // FIXME: deal with java.naming.ldap.attributes.binary
129: if (!isBinary) {
130: for (byte[] bs : list) {
131: add(Utils.getString(bs));
132: }
133: } else {
134: for (byte[] bs : list) {
135: add(bs);
136: }
137: }
138:
139: }
140:
141: public void encodeValues(Object[] vs) {
142: vs[0] = Utils.getBytes(attrID);
143:
144: List<Object> list = new ArrayList<Object>(this .values.size());
145:
146: for (Object object : this .values) {
147: if (!isBinary && object instanceof String) {
148: String str = (String) object;
149: object = Utils.getBytes(str);
150: }
151:
152: list.add(object);
153: }
154: vs[1] = list;
155: }
156:
157: @Override
158: public DirContext getAttributeDefinition() throws NamingException {
159: if (attributeDefinition != null) {
160: return attributeDefinition;
161: }
162: attributeDefinition = context
163: .getSchemaAttributeDefinition(getID());
164: return attributeDefinition;
165: }
166:
167: @Override
168: public DirContext getAttributeSyntaxDefinition()
169: throws NamingException {
170: if (attributeSyntaxDefinition != null) {
171: return attributeSyntaxDefinition;
172: }
173: // get the syntax id from the attribute def
174: DirContext schema = context.getSchema("");
175: DirContext attrDef = (DirContext) schema
176: .lookup(LdapSchemaContextImpl.ATTRIBUTE_DEFINITION
177: + "/" + getID());
178:
179: Attribute syntaxAttr = attrDef.getAttributes("").get("syntax");
180:
181: if (syntaxAttr == null || syntaxAttr.size() == 0) {
182: throw new NameNotFoundException(Messages.getString(
183: "jndi.90", getID()));
184: }
185:
186: String syntaxName = (String) syntaxAttr.get();
187:
188: // look in the schema tree for the syntax definition
189: return (DirContext) schema
190: .lookup(LdapSchemaContextImpl.SYNTAX_DEFINITION + "/"
191: + syntaxName);
192:
193: }
194:
195: private static boolean isBinary(String name) {
196: return BINARY_ATTRIBUTE.contains(name)
197: || name.endsWith(";binary");
198: }
199: }
|