001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.message.databinding.impl;
020:
021: import org.apache.axis2.java.security.AccessController;
022: import org.apache.axis2.jaxws.ExceptionFactory;
023: import org.apache.axis2.jaxws.i18n.Messages;
024: import org.apache.axis2.jaxws.message.databinding.ClassFinder;
025: import org.apache.axis2.jaxws.utility.ClassUtils;
026: import org.apache.axis2.jaxws.utility.JavaUtils;
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029:
030: import java.io.File;
031: import java.io.IOException;
032: import java.net.URL;
033: import java.net.URLClassLoader;
034: import java.security.PrivilegedActionException;
035: import java.security.PrivilegedExceptionAction;
036: import java.util.ArrayList;
037: import java.util.Enumeration;
038: import java.util.jar.JarEntry;
039: import java.util.jar.JarFile;
040:
041: public class ClassFinderImpl implements ClassFinder {
042: private static final Log log = LogFactory
043: .getLog(ClassFinderImpl.class);
044:
045: /* (non-Javadoc)
046: * @see org.apache.axis2.jaxws.message.databinding.ClassFinder#getClassesFromJarFile(java.lang.String, java.lang.ClassLoader)
047: */
048: public ArrayList<Class> getClassesFromJarFile(String pkg,
049: ClassLoader cl) throws ClassNotFoundException {
050: try {
051: ArrayList<Class> classes = new ArrayList<Class>();
052: URLClassLoader ucl = (URLClassLoader) cl;
053: URL[] srcURL = ucl.getURLs();
054: String path = pkg.replace('.', '/');
055: //Read resources as URL from class loader.
056: for (URL url : srcURL) {
057: if ("file".equals(url.getProtocol())) {
058: File f = new File(url.getPath());
059: //If file is not of type directory then its a jar file
060: if (f.exists() && !f.isDirectory()) {
061: try {
062: JarFile jf = new JarFile(f);
063: Enumeration<JarEntry> entries = jf
064: .entries();
065: //read all entries in jar file
066: while (entries.hasMoreElements()) {
067: JarEntry je = entries.nextElement();
068: String clazzName = je.getName();
069: if (clazzName != null
070: && clazzName.endsWith(".class")) {
071: //Add to class list here.
072: clazzName = clazzName.substring(0,
073: clazzName.length() - 6);
074: clazzName = clazzName.replace('/',
075: '.').replace('\\', '.')
076: .replace(':', '.');
077: //We are only going to add the class that belong to the provided package.
078: if (clazzName.startsWith(pkg)) {
079: try {
080: Class clazz = forName(
081: clazzName,
082: false,
083: getContextClassLoader());
084: // Don't add any interfaces or JAXWS specific classes.
085: // Only classes that represent data and can be marshalled
086: // by JAXB should be added.
087: if (!clazz.isInterface()
088: && ClassUtils
089: .getDefaultPublicConstructor(clazz) != null
090: && !ClassUtils
091: .isJAXWSClass(clazz)) {
092: if (log
093: .isDebugEnabled()) {
094: log
095: .debug("Adding class: "
096: + clazzName);
097: }
098: classes.add(clazz);
099:
100: }
101: //catch Throwable as ClassLoader can throw an NoClassDefFoundError that
102: //does not extend Exception, so lets catch everything that extends Throwable
103: //rather than just Exception.
104: } catch (Throwable e) {
105: if (log.isDebugEnabled()) {
106: log
107: .debug("Tried to load class "
108: + clazzName
109: + " while constructing a JAXBContext. This class will be skipped. Processing Continues.");
110: log
111: .debug(" The reason that class could not be loaded:"
112: + e
113: .toString());
114: log
115: .debug(JavaUtils
116: .stackToString(e));
117: }
118: }
119: }
120: }
121: }
122: } catch (IOException e) {
123: throw new ClassNotFoundException(Messages
124: .getMessage("ClassUtilsErr4"));
125: }
126: }
127: }
128: }
129: return classes;
130: } catch (Exception e) {
131: throw new ClassNotFoundException(e.getMessage());
132: }
133:
134: }
135:
136: /**
137: * Return the class for this name
138: *
139: * @return Class
140: */
141: private static Class forName(final String className,
142: final boolean initialize, final ClassLoader classloader) {
143: // NOTE: This method must remain private because it uses AccessController
144: Class cl = null;
145: try {
146: cl = (Class) AccessController
147: .doPrivileged(new PrivilegedExceptionAction() {
148: public Object run()
149: throws ClassNotFoundException {
150: return Class.forName(className, initialize,
151: classloader);
152: }
153: });
154: } catch (PrivilegedActionException e) {
155: if (log.isDebugEnabled()) {
156: log.debug("Exception thrown from AccessController: "
157: + e);
158: }
159: throw ExceptionFactory.makeWebServiceException(e
160: .getException());
161: }
162:
163: return cl;
164: }
165:
166: /** @return ClassLoader */
167: private static ClassLoader getContextClassLoader() {
168: // NOTE: This method must remain private because it uses AccessController
169: ClassLoader cl = null;
170: try {
171: cl = (ClassLoader) AccessController
172: .doPrivileged(new PrivilegedExceptionAction() {
173: public Object run()
174: throws ClassNotFoundException {
175: return Thread.currentThread()
176: .getContextClassLoader();
177: }
178: });
179: } catch (PrivilegedActionException e) {
180: if (log.isDebugEnabled()) {
181: log.debug("Exception thrown from AccessController: "
182: + e);
183: }
184: throw ExceptionFactory.makeWebServiceException(e
185: .getException());
186: }
187:
188: return cl;
189: }
190: }
|