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.commons.discovery.resource.names;
018:
019: import java.io.BufferedReader;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.InputStreamReader;
023: import java.util.Vector;
024:
025: import org.apache.commons.discovery.Resource;
026: import org.apache.commons.discovery.ResourceDiscover;
027: import org.apache.commons.discovery.ResourceIterator;
028: import org.apache.commons.discovery.ResourceNameDiscover;
029: import org.apache.commons.discovery.ResourceNameIterator;
030: import org.apache.commons.discovery.log.DiscoveryLogFactory;
031: import org.apache.commons.discovery.resource.ClassLoaders;
032: import org.apache.commons.discovery.resource.DiscoverResources;
033: import org.apache.commons.logging.Log;
034:
035: /**
036: * Discover ALL files of a given name, and return resource names
037: * contained within the set of files:
038: * <ul>
039: * <li>one resource name per line,</li>
040: * <li>whitespace ignored,</li>
041: * <li>comments begin with '#'</li>
042: * </ul>
043: *
044: * Default discoverer is DiscoverClassLoaderResources,
045: * but it can be set to any other.
046: *
047: * @author Richard A. Sitze
048: * @author Costin Manolache
049: * @author James Strachan
050: */
051: public class DiscoverNamesInFile extends ResourceNameDiscoverImpl
052: implements ResourceNameDiscover {
053: private static Log log = DiscoveryLogFactory
054: .newLog(DiscoverNamesInFile.class);
055:
056: public static void setLog(Log _log) {
057: log = _log;
058: }
059:
060: private ResourceDiscover _discoverResources;
061:
062: private final String _prefix;
063: private final String _suffix;
064:
065: /**
066: * Construct a new resource discoverer
067: */
068: public DiscoverNamesInFile() {
069: _discoverResources = new DiscoverResources();
070: _prefix = null;
071: _suffix = null;
072: }
073:
074: /**
075: * Construct a new resource discoverer
076: */
077: public DiscoverNamesInFile(String prefix, String suffix) {
078: _discoverResources = new DiscoverResources();
079: _prefix = prefix;
080: _suffix = suffix;
081: }
082:
083: /**
084: * Construct a new resource discoverer
085: */
086: public DiscoverNamesInFile(ClassLoaders loaders) {
087: _discoverResources = new DiscoverResources(loaders);
088: _prefix = null;
089: _suffix = null;
090: }
091:
092: /**
093: * Construct a new resource discoverer
094: */
095: public DiscoverNamesInFile(ClassLoaders loaders, String prefix,
096: String suffix) {
097: _discoverResources = new DiscoverResources(loaders);
098: _prefix = prefix;
099: _suffix = suffix;
100: }
101:
102: /**
103: * Construct a new resource discoverer
104: */
105: public DiscoverNamesInFile(ResourceDiscover discoverer) {
106: _discoverResources = discoverer;
107: _prefix = null;
108: _suffix = null;
109: }
110:
111: /**
112: * Construct a new resource discoverer
113: */
114: public DiscoverNamesInFile(ResourceDiscover discoverer,
115: String prefix, String suffix) {
116: _discoverResources = discoverer;
117: _prefix = prefix;
118: _suffix = suffix;
119: }
120:
121: /**
122: * Specify set of class loaders to be used in searching.
123: */
124: public void setDiscoverer(ResourceDiscover discover) {
125: _discoverResources = discover;
126: }
127:
128: /**
129: * To be used by downstream elements..
130: */
131: public ResourceDiscover getDiscover() {
132: return _discoverResources;
133: }
134:
135: /**
136: * @return Enumeration of ServiceInfo
137: */
138: public ResourceNameIterator findResourceNames(
139: final String serviceName) {
140: String fileName;
141: if (_prefix != null && _prefix.length() > 0) {
142: fileName = _prefix + serviceName;
143: } else {
144: fileName = serviceName;
145: }
146:
147: if (_suffix != null && _suffix.length() > 0) {
148: fileName = fileName + _suffix;
149: }
150:
151: if (log.isDebugEnabled()) {
152: if (_prefix != null && _suffix != null) {
153: log.debug("find: serviceName='" + serviceName
154: + "' as '" + fileName + "'");
155: } else {
156: log.debug("find: serviceName = '" + fileName + "'");
157: }
158: }
159:
160: final ResourceIterator files = getDiscover().findResources(
161: fileName);
162:
163: return new ResourceNameIterator() {
164: private int idx = 0;
165: private Vector classNames = null;
166: private String resource = null;
167:
168: public boolean hasNext() {
169: if (resource == null) {
170: resource = getNextClassName();
171: }
172: return resource != null;
173: }
174:
175: public String nextResourceName() {
176: String element = resource;
177: resource = null;
178: return element;
179: }
180:
181: private String getNextClassName() {
182: if (classNames == null || idx >= classNames.size()) {
183: classNames = getNextClassNames();
184: idx = 0;
185: if (classNames == null) {
186: return null;
187: }
188: }
189:
190: String className = (String) classNames.get(idx++);
191:
192: if (log.isDebugEnabled())
193: log.debug("getNextClassResource: next class='"
194: + className + "'");
195:
196: return className;
197: }
198:
199: private Vector getNextClassNames() {
200: while (files.hasNext()) {
201: Vector results = readServices(files.nextResource());
202: if (results != null && results.size() > 0) {
203: return results;
204: }
205: }
206: return null;
207: }
208: };
209: }
210:
211: /**
212: * Read everything, no defering here..
213: * Ensure that files are closed before we leave.
214: */
215: private Vector readServices(final Resource info) {
216: Vector results = new Vector();
217:
218: InputStream is = info.getResourceAsStream();
219:
220: if (is != null) {
221: try {
222: try {
223: // This code is needed by EBCDIC and other
224: // strange systems. It's a fix for bugs
225: // reported in xerces
226: BufferedReader rd;
227: try {
228: rd = new BufferedReader(new InputStreamReader(
229: is, "UTF-8"));
230: } catch (java.io.UnsupportedEncodingException e) {
231: rd = new BufferedReader(new InputStreamReader(
232: is));
233: }
234:
235: try {
236: String serviceImplName;
237: while ((serviceImplName = rd.readLine()) != null) {
238: int idx = serviceImplName.indexOf('#');
239: if (idx >= 0) {
240: serviceImplName = serviceImplName
241: .substring(0, idx);
242: }
243: serviceImplName = serviceImplName.trim();
244:
245: if (serviceImplName.length() != 0) {
246: results.add(serviceImplName);
247: }
248: }
249: } finally {
250: rd.close();
251: }
252: } finally {
253: is.close();
254: }
255: } catch (IOException e) {
256: // ignore
257: }
258: }
259:
260: return results;
261: }
262: }
|