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.catalina.tribes.io;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.ObjectInputStream;
023: import java.io.ObjectStreamClass;
024:
025: /**
026: * Custom subclass of <code>ObjectInputStream</code> that loads from the
027: * class loader for this web application. This allows classes defined only
028: * with the web application to be found correctly.
029: *
030: * @author Craig R. McClanahan
031: * @author Bip Thelin
032: * @author Filip Hanik
033: * @version $Revision: 467173 $, $Date: 2006-10-24 01:12:17 +0200 (mar., 24 oct. 2006) $
034: */
035:
036: public final class ReplicationStream extends ObjectInputStream {
037:
038: /**
039: * The class loader we will use to resolve classes.
040: */
041: private ClassLoader[] classLoaders = null;
042:
043: /**
044: * Construct a new instance of CustomObjectInputStream
045: *
046: * @param stream The input stream we will read from
047: * @param classLoader The class loader used to instantiate objects
048: *
049: * @exception IOException if an input/output error occurs
050: */
051: public ReplicationStream(InputStream stream,
052: ClassLoader[] classLoaders) throws IOException {
053:
054: super (stream);
055: this .classLoaders = classLoaders;
056: }
057:
058: /**
059: * Load the local class equivalent of the specified stream class
060: * description, by using the class loader assigned to this Context.
061: *
062: * @param classDesc Class description from the input stream
063: *
064: * @exception ClassNotFoundException if this class cannot be found
065: * @exception IOException if an input/output error occurs
066: */
067: public Class resolveClass(ObjectStreamClass classDesc)
068: throws ClassNotFoundException, IOException {
069: String name = classDesc.getName();
070: boolean tryRepFirst = name
071: .startsWith("org.apache.catalina.tribes");
072: try {
073: try {
074: if (tryRepFirst)
075: return findReplicationClass(name);
076: else
077: return findExternalClass(name);
078: } catch (Exception x) {
079: if (tryRepFirst)
080: return findExternalClass(name);
081: else
082: return findReplicationClass(name);
083: }
084: } catch (ClassNotFoundException e) {
085: return super .resolveClass(classDesc);
086: }
087: }
088:
089: public Class findReplicationClass(String name)
090: throws ClassNotFoundException, IOException {
091: Class clazz = Class.forName(name, false, getClass()
092: .getClassLoader());
093: return clazz;
094: }
095:
096: public Class findExternalClass(String name)
097: throws ClassNotFoundException {
098: ClassNotFoundException cnfe = null;
099: for (int i = 0; i < classLoaders.length; i++) {
100: try {
101: Class clazz = Class.forName(name, false,
102: classLoaders[i]);
103: return clazz;
104: } catch (ClassNotFoundException x) {
105: cnfe = x;
106: }
107: }
108: if (cnfe != null)
109: throw cnfe;
110: else
111: throw new ClassNotFoundException(name);
112: }
113:
114: public void close() throws IOException {
115: this.classLoaders = null;
116: super.close();
117: }
118:
119: }
|