001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v2.naming;
024:
025: import java.net.*;
026: import javax.naming.*;
027: import com.mchange.v2.log.MLevel;
028: import com.mchange.v2.log.MLog;
029: import com.mchange.v2.log.MLogger;
030: import javax.naming.spi.ObjectFactory;
031: import java.util.Hashtable;
032:
033: public final class ReferenceableUtils {
034: final static MLogger logger = MLog
035: .getLogger(ReferenceableUtils.class);
036:
037: /* don't worry -- References can have duplicate RefAddrs (I think!) */
038: final static String REFADDR_VERSION = "version";
039: final static String REFADDR_CLASSNAME = "classname";
040: final static String REFADDR_FACTORY = "factory";
041: final static String REFADDR_FACTORY_CLASS_LOCATION = "factoryClassLocation";
042: final static String REFADDR_SIZE = "size";
043:
044: final static int CURRENT_REF_VERSION = 1;
045:
046: /**
047: * A null string value in a Reference sometimes goes to the literal
048: * "null". Sigh. We convert this string to a Java null.
049: */
050: public static String literalNullToNull(String s) {
051: if (s == null || "null".equals(s))
052: return null;
053: else
054: return s;
055: }
056:
057: public static Object referenceToObject(Reference ref, Name name,
058: Context nameCtx, Hashtable env) throws NamingException {
059: try {
060: String fClassName = ref.getFactoryClassName();
061: String fClassLocation = ref.getFactoryClassLocation();
062:
063: ClassLoader cl;
064: if (fClassLocation == null)
065: cl = ClassLoader.getSystemClassLoader();
066: else {
067: URL u = new URL(fClassLocation);
068: cl = new URLClassLoader(new URL[] { u }, ClassLoader
069: .getSystemClassLoader());
070: }
071:
072: Class fClass = Class.forName(fClassName, true, cl);
073: ObjectFactory of = (ObjectFactory) fClass.newInstance();
074: return of.getObjectInstance(ref, name, nameCtx, env);
075: } catch (Exception e) {
076: if (Debug.DEBUG) {
077: //e.printStackTrace();
078: if (logger.isLoggable(MLevel.FINE))
079: logger
080: .log(
081: MLevel.FINE,
082: "Could not resolve Reference to Object!",
083: e);
084: }
085: NamingException ne = new NamingException(
086: "Could not resolve Reference to Object!");
087: ne.setRootCause(e);
088: throw ne;
089: }
090: }
091:
092: /**
093: * @deprecated nesting references seemed useful until I realized that
094: * references are Serializable and can be stored in a BinaryRefAddr.
095: * Oops.
096: */
097: public static void appendToReference(Reference appendTo,
098: Reference orig) throws NamingException {
099: int len = orig.size();
100: appendTo.add(new StringRefAddr(REFADDR_VERSION, String
101: .valueOf(CURRENT_REF_VERSION)));
102: appendTo.add(new StringRefAddr(REFADDR_CLASSNAME, orig
103: .getClassName()));
104: appendTo.add(new StringRefAddr(REFADDR_FACTORY, orig
105: .getFactoryClassName()));
106: appendTo.add(new StringRefAddr(REFADDR_FACTORY_CLASS_LOCATION,
107: orig.getFactoryClassLocation()));
108: appendTo.add(new StringRefAddr(REFADDR_SIZE, String
109: .valueOf(len)));
110: for (int i = 0; i < len; ++i)
111: appendTo.add(orig.get(i));
112: }
113:
114: /**
115: * @deprecated nesting references seemed useful until I realized that
116: * references are Serializable and can be stored in a BinaryRefAddr.
117: * Oops.
118: */
119: public static ExtractRec extractNestedReference(
120: Reference extractFrom, int index) throws NamingException {
121: try {
122: int version = Integer.parseInt((String) extractFrom.get(
123: index++).getContent());
124: if (version == 1) {
125: String className = (String) extractFrom.get(index++)
126: .getContent();
127: String factoryClassName = (String) extractFrom.get(
128: index++).getContent();
129: String factoryClassLocation = (String) extractFrom.get(
130: index++).getContent();
131:
132: Reference outRef = new Reference(className,
133: factoryClassName, factoryClassLocation);
134: int size = Integer.parseInt((String) extractFrom.get(
135: index++).getContent());
136: for (int i = 0; i < size; ++i)
137: outRef.add(extractFrom.get(index++));
138: return new ExtractRec(outRef, index);
139: } else
140: throw new NamingException(
141: "Bad version of nested reference!!!");
142: } catch (NumberFormatException e) {
143: if (Debug.DEBUG) {
144: //e.printStackTrace();
145: if (logger.isLoggable(MLevel.FINE))
146: logger
147: .log(
148: MLevel.FINE,
149: "Version or size nested reference was not a number!!!",
150: e);
151: }
152: throw new NamingException(
153: "Version or size nested reference was not a number!!!");
154: }
155: }
156:
157: /**
158: * @deprecated nesting references seemed useful until I realized that
159: * references are Serializable and can be stored in a BinaryRefAddr.
160: * Oops.
161: */
162: public static class ExtractRec {
163: public Reference ref;
164:
165: /**
166: * return the first RefAddr index that the function HAS NOT read to
167: * extract the reference.
168: */
169: public int index;
170:
171: private ExtractRec(Reference ref, int index) {
172: this .ref = ref;
173: this .index = index;
174: }
175: }
176:
177: private ReferenceableUtils() {
178: }
179: }
|