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: package org.apache.pluto.util;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021:
022: import java.io.IOException;
023: import java.net.URL;
024: import java.util.ArrayList;
025: import java.util.Enumeration;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.Properties;
029: import java.util.StringTokenizer;
030:
031: public class ClasspathScanner {
032:
033: private static final Log LOG = LogFactory
034: .getLog(ClasspathScanner.class);
035:
036: /**
037: * Retrieve a lit of all urls matching the specified
038: * path.
039: *
040: * @param path
041: * @return
042: * @throws IOException
043: */
044: public static List scan(String path) throws IOException {
045: List list = scan(path, ClasspathScanner.class.getClassLoader());
046: list.addAll(scan(path, Thread.currentThread()
047: .getContextClassLoader()));
048: list.add(ClasspathScanner.class.getResource(path));
049:
050: if (LOG.isInfoEnabled()) {
051: LOG.info("Found " + list.size() + " resources for path '"
052: + path + "'.");
053: }
054:
055: return list;
056: }
057:
058: /**
059: * Retrieve a list of all urls massing the specified path
060: * for the specified classloader.
061: *
062: * @param path
063: * @param loader
064: * @return
065: * @throws IOException
066: */
067: public static List scan(String path, ClassLoader loader)
068: throws IOException {
069: ArrayList list = new ArrayList();
070: if (loader == null) {
071: return list;
072: }
073:
074: Enumeration enumeration = loader.getResources(path);
075: while (enumeration.hasMoreElements()) {
076: list.add(enumeration.nextElement());
077: }
078: return list;
079: }
080:
081: /**
082: * Mechanism for finding all implementations of the specified
083: * interface. This method is used for resolving low level
084: * implementations of interfaces needed by static and/or non
085: * services. These implementations are not bound to their
086: * container, but instead, are bound to the global application
087: * environment.
088: *
089: * @param implemented interface implemnted by configured impls
090: * @return list of classes
091: * @throws java.io.IOException if an error occurs during classpath scanning.
092: */
093: public static List findConfiguredImplementations(Class implemented)
094: throws IOException {
095: List classes = new ArrayList();
096: List resources = scan("/META-INF/pluto.properties");
097: Iterator i = resources.iterator();
098:
099: Properties p = new Properties();
100: while (i.hasNext()) {
101: URL url = (URL) i.next();
102: p.load(url.openStream());
103: String impl = p.getProperty(implemented.getName());
104: if (impl != null) {
105: StringTokenizer st = new StringTokenizer(impl, ",",
106: false);
107: while (st.hasMoreTokens()) {
108: String token = st.nextToken().trim();
109: if (token.length() > 0) {
110: try {
111: classes.add(Class.forName(token));
112: } catch (ClassNotFoundException cnfe) {
113: LOG
114: .warn("Unable to find configured implementation "
115: + impl
116: + " of interface "
117: + implemented.getName());
118: }
119: }
120: }
121: }
122: p.clear();
123: }
124: return classes;
125: }
126: }
|