|
Java example source code file (Obj.java)
The Obj.java Java example source code
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.jndi.ldap;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.spi.DirectoryManager;
import javax.naming.spi.DirStateFactory;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;
import java.util.StringTokenizer;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
import java.lang.reflect.Proxy;
import java.lang.reflect.Modifier;
/**
* Class containing static methods and constants for dealing with
* encoding/decoding JNDI References and Serialized Objects
* in LDAP.
* @author Vincent Ryan
* @author Rosanna Lee
*/
final class Obj {
private Obj () {}; // Make sure no one can create one
// package private; used by Connection
static VersionHelper helper = VersionHelper.getVersionHelper();
// LDAP attributes used to support Java objects.
static final String[] JAVA_ATTRIBUTES = {
"objectClass",
"javaSerializedData",
"javaClassName",
"javaFactory",
"javaCodeBase",
"javaReferenceAddress",
"javaClassNames",
"javaRemoteLocation" // Deprecated
};
static final int OBJECT_CLASS = 0;
static final int SERIALIZED_DATA = 1;
static final int CLASSNAME = 2;
static final int FACTORY = 3;
static final int CODEBASE = 4;
static final int REF_ADDR = 5;
static final int TYPENAME = 6;
/**
* @deprecated
*/
@Deprecated
private static final int REMOTE_LOC = 7;
// LDAP object classes to support Java objects
static final String[] JAVA_OBJECT_CLASSES = {
"javaContainer",
"javaObject",
"javaNamingReference",
"javaSerializedObject",
"javaMarshalledObject",
};
static final String[] JAVA_OBJECT_CLASSES_LOWER = {
"javacontainer",
"javaobject",
"javanamingreference",
"javaserializedobject",
"javamarshalledobject",
};
static final int STRUCTURAL = 0; // structural object class
static final int BASE_OBJECT = 1; // auxiliary java object class
static final int REF_OBJECT = 2; // auxiliary reference object class
static final int SER_OBJECT = 3; // auxiliary serialized object class
static final int MAR_OBJECT = 4; // auxiliary marshalled object class
/**
* Encode an object in LDAP attributes.
* Supports binding Referenceable or Reference, Serializable,
* and DirContext.
*
* If the object supports the Referenceable interface then encode
* the reference to the object. See encodeReference() for details.
*<p>
* If the object is serializable, it is stored as follows:
* javaClassName
* value: Object.getClass();
* javaSerializedData
* value: serialized form of Object (in binary form).
* javaTypeName
* value: getTypeNames(Object.getClass());
*/
private static Attributes encodeObject(char separator,
Object obj, Attributes attrs,
Attribute objectClass, boolean cloned)
throws NamingException {
boolean structural =
(objectClass.size() == 0 ||
(objectClass.size() == 1 && objectClass.contains("top")));
if (structural) {
objectClass.add(JAVA_OBJECT_CLASSES[STRUCTURAL]);
}
// References
if (obj instanceof Referenceable) {
objectClass.add(JAVA_OBJECT_CLASSES[BASE_OBJECT]);
objectClass.add(JAVA_OBJECT_CLASSES[REF_OBJECT]);
if (!cloned) {
attrs = (Attributes)attrs.clone();
}
attrs.put(objectClass);
return (encodeReference(separator,
((Referenceable)obj).getReference(),
attrs, obj));
} else if (obj instanceof Reference) {
objectClass.add(JAVA_OBJECT_CLASSES[BASE_OBJECT]);
objectClass.add(JAVA_OBJECT_CLASSES[REF_OBJECT]);
if (!cloned) {
attrs = (Attributes)attrs.clone();
}
attrs.put(objectClass);
return (encodeReference(separator, (Reference)obj, attrs, null));
// Serializable Object
} else if (obj instanceof java.io.Serializable) {
objectClass.add(JAVA_OBJECT_CLASSES[BASE_OBJECT]);
if (!(objectClass.contains(JAVA_OBJECT_CLASSES[MAR_OBJECT]) ||
objectClass.contains(JAVA_OBJECT_CLASSES_LOWER[MAR_OBJECT]))) {
objectClass.add(JAVA_OBJECT_CLASSES[SER_OBJECT]);
}
if (!cloned) {
attrs = (Attributes)attrs.clone();
}
attrs.put(objectClass);
attrs.put(new BasicAttribute(JAVA_ATTRIBUTES[SERIALIZED_DATA],
serializeObject(obj)));
if (attrs.get(JAVA_ATTRIBUTES[CLASSNAME]) == null) {
attrs.put(JAVA_ATTRIBUTES[CLASSNAME],
obj.getClass().getName());
}
if (attrs.get(JAVA_ATTRIBUTES[TYPENAME]) == null) {
Attribute tAttr =
LdapCtxFactory.createTypeNameAttr(obj.getClass());
if (tAttr != null) {
attrs.put(tAttr);
}
}
// DirContext Object
} else if (obj instanceof DirContext) {
// do nothing
} else {
throw new IllegalArgumentException(
"can only bind Referenceable, Serializable, DirContext");
}
// System.err.println(attrs);
return attrs;
}
/**
* Each value in javaCodebase contains a list of space-separated
* URLs. Each value is independent; we can pick any of the values
* so we just use the first one.
* @return an array of URL strings for the codebase
*/
private static String[] getCodebases(Attribute codebaseAttr) throws
NamingException {
if (codebaseAttr == null) {
return null;
} else {
StringTokenizer parser =
new StringTokenizer((String)codebaseAttr.get());
Vector<String> vec = new Vector<>(10);
while (parser.hasMoreTokens()) {
vec.addElement(parser.nextToken());
}
String[] answer = new String[vec.size()];
for (int i = 0; i < answer.length; i++) {
answer[i] = vec.elementAt(i);
}
return answer;
}
}
/*
* Decode an object from LDAP attribute(s).
* The object may be a Reference, or a Serialized object.
*
* See encodeObject() and encodeReference() for details on formats
* expected.
*/
static Object decodeObject(Attributes attrs)
throws NamingException {
Attribute attr;
// Get codebase, which is used in all 3 cases.
String[] codebases = getCodebases(attrs.get(JAVA_ATTRIBUTES[CODEBASE]));
try {
if ((attr = attrs.get(JAVA_ATTRIBUTES[SERIALIZED_DATA])) != null) {
ClassLoader cl = helper.getURLClassLoader(codebases);
return deserializeObject((byte[])attr.get(), cl);
} else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) {
// For backward compatibility only
return decodeRmiObject(
(String)attrs.get(JAVA_ATTRIBUTES[CLASSNAME]).get(),
(String)attr.get(), codebases);
}
attr = attrs.get(JAVA_ATTRIBUTES[OBJECT_CLASS]);
if (attr != null &&
(attr.contains(JAVA_OBJECT_CLASSES[REF_OBJECT]) ||
attr.contains(JAVA_OBJECT_CLASSES_LOWER[REF_OBJECT]))) {
return decodeReference(attrs, codebases);
}
return null;
} catch (IOException e) {
NamingException ne = new NamingException();
ne.setRootCause(e);
throw ne;
}
}
/**
* Convert a Reference object into several LDAP attributes.
*
* A Reference is stored as into the following attributes:
* javaClassName
* value: Reference.getClassName();
* javaFactory
* value: Reference.getFactoryClassName();
* javaCodeBase
* value: Reference.getFactoryClassLocation();
* javaReferenceAddress
* value: #0#typeA#valA
* value: #1#typeB#valB
* value: #2#typeC##[serialized RefAddr C]
* value: #3#typeD#valD
*
* where
* - the first character denotes the separator
* - the number following the first separator denotes the position
* of the RefAddr within the Reference
* - "typeA" is RefAddr.getType()
* - ## denotes that the Base64-encoded form of the non-StringRefAddr
* is to follow; otherwise the value that follows is
* StringRefAddr.getContents()
*
* The default separator is the hash character (#).
* May provide property for this in future.
*/
private static Attributes encodeReference(char separator,
Reference ref, Attributes attrs, Object orig)
throws NamingException {
if (ref == null)
return attrs;
String s;
if ((s = ref.getClassName()) != null) {
attrs.put(new BasicAttribute(JAVA_ATTRIBUTES[CLASSNAME], s));
}
if ((s = ref.getFactoryClassName()) != null) {
attrs.put(new BasicAttribute(JAVA_ATTRIBUTES[FACTORY], s));
}
if ((s = ref.getFactoryClassLocation()) != null) {
attrs.put(new BasicAttribute(JAVA_ATTRIBUTES[CODEBASE], s));
}
// Get original object's types if caller has not explicitly
// specified other type names
if (orig != null && attrs.get(JAVA_ATTRIBUTES[TYPENAME]) != null) {
Attribute tAttr =
LdapCtxFactory.createTypeNameAttr(orig.getClass());
if (tAttr != null) {
attrs.put(tAttr);
}
}
int count = ref.size();
if (count > 0) {
Attribute refAttr = new BasicAttribute(JAVA_ATTRIBUTES[REF_ADDR]);
RefAddr refAddr;
BASE64Encoder encoder = null;
for (int i = 0; i < count; i++) {
refAddr = ref.get(i);
if (refAddr instanceof StringRefAddr) {
refAttr.add(""+ separator + i +
separator + refAddr.getType() +
separator + refAddr.getContent());
} else {
if (encoder == null)
encoder = new BASE64Encoder();
refAttr.add(""+ separator + i +
separator + refAddr.getType() +
separator + separator +
encoder.encodeBuffer(serializeObject(refAddr)));
}
}
attrs.put(refAttr);
}
return attrs;
}
/*
* A RMI object is stored in the directory as
* javaClassName
* value: Object.getClass();
* javaRemoteLocation
* value: URL of RMI object (accessed through the RMI Registry)
* javaCodebase:
* value: URL of codebase of where to find classes for object
*
* Return the RMI Location URL itself. This will be turned into
* an RMI object when getObjectInstance() is called on it.
* %%% Ignore codebase for now. Depend on RMI registry to send code.-RL
* @deprecated For backward compatibility only
*/
private static Object decodeRmiObject(String className,
String rmiName, String[] codebases) throws NamingException {
return new Reference(className, new StringRefAddr("URL", rmiName));
}
/*
* Restore a Reference object from several LDAP attributes
*/
private static Reference decodeReference(Attributes attrs,
String[] codebases) throws NamingException, IOException {
Attribute attr;
String className;
String factory = null;
if ((attr = attrs.get(JAVA_ATTRIBUTES[CLASSNAME])) != null) {
className = (String)attr.get();
} else {
throw new InvalidAttributesException(JAVA_ATTRIBUTES[CLASSNAME] +
" attribute is required");
}
if ((attr = attrs.get(JAVA_ATTRIBUTES[FACTORY])) != null) {
factory = (String)attr.get();
}
Reference ref = new Reference(className, factory,
(codebases != null? codebases[0] : null));
/*
* string encoding of a RefAddr is either:
*
* #posn#<type>#
* or
* #posn#<type>##
Other Java examples (source code examples)Here is a short list of links related to this Java Obj.java source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.