1. /*
  2. * ====================================================================
  3. *
  4. * The Apache Software License, Version 1.1
  5. *
  6. * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
  7. * reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in
  18. * the documentation and/or other materials provided with the
  19. * distribution.
  20. *
  21. * 3. The end-user documentation included with the redistribution, if
  22. * any, must include the following acknowlegement:
  23. * "This product includes software developed by the
  24. * Apache Software Foundation (http://www.apache.org/)."
  25. * Alternately, this acknowlegement may appear in the software itself,
  26. * if and wherever such third-party acknowlegements normally appear.
  27. *
  28. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  29. * Foundation" must not be used to endorse or promote products derived
  30. * from this software without prior written permission. For written
  31. * permission, please contact apache@apache.org.
  32. *
  33. * 5. Products derived from this software may not be called "Apache"
  34. * nor may "Apache" appear in their names without prior written
  35. * permission of the Apache Group.
  36. *
  37. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  38. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  39. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  41. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  42. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  43. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  44. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  45. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  46. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  47. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  48. * SUCH DAMAGE.
  49. * ====================================================================
  50. *
  51. * This software consists of voluntary contributions made by many
  52. * individuals on behalf of the Apache Software Foundation. For more
  53. * information on the Apache Software Foundation, please see
  54. * <http://www.apache.org/>.
  55. *
  56. */
  57. package org.apache.commons.discovery.resource.names;
  58. import java.io.BufferedReader;
  59. import java.io.IOException;
  60. import java.io.InputStream;
  61. import java.io.InputStreamReader;
  62. import java.util.Vector;
  63. import org.apache.commons.discovery.Resource;
  64. import org.apache.commons.discovery.ResourceDiscover;
  65. import org.apache.commons.discovery.ResourceIterator;
  66. import org.apache.commons.discovery.ResourceNameDiscover;
  67. import org.apache.commons.discovery.ResourceNameIterator;
  68. import org.apache.commons.discovery.log.DiscoveryLogFactory;
  69. import org.apache.commons.discovery.resource.ClassLoaders;
  70. import org.apache.commons.discovery.resource.DiscoverResources;
  71. import org.apache.commons.logging.Log;
  72. /**
  73. * Discover ALL files of a given name, and return resource names
  74. * contained within the set of files:
  75. * <ul>
  76. * <li>one resource name per line,</li>
  77. * <li>whitespace ignored,</li>
  78. * <li>comments begin with '#'</li>
  79. * </ul>
  80. *
  81. * Default discoverer is DiscoverClassLoaderResources,
  82. * but it can be set to any other.
  83. *
  84. * @author Richard A. Sitze
  85. * @author Costin Manolache
  86. * @author James Strachan
  87. */
  88. public class DiscoverNamesInFile
  89. extends ResourceNameDiscoverImpl
  90. implements ResourceNameDiscover
  91. {
  92. private static Log log = DiscoveryLogFactory.newLog(DiscoverNamesInFile.class);
  93. public static void setLog(Log _log) {
  94. log = _log;
  95. }
  96. private ResourceDiscover discoverResources;
  97. /**
  98. * Construct a new resource discoverer
  99. */
  100. public DiscoverNamesInFile() {
  101. discoverResources = new DiscoverResources();
  102. }
  103. /**
  104. * Construct a new resource discoverer
  105. */
  106. public DiscoverNamesInFile(ClassLoaders loaders) {
  107. discoverResources = new DiscoverResources(loaders);
  108. }
  109. /**
  110. * Construct a new resource discoverer
  111. */
  112. public DiscoverNamesInFile(ResourceDiscover discoverer) {
  113. this.discoverResources = discoverer;
  114. }
  115. /**
  116. * Specify set of class loaders to be used in searching.
  117. */
  118. public void setDiscoverer(ResourceDiscover discover) {
  119. this.discoverResources = discover;
  120. }
  121. /**
  122. * To be used by downstream elements..
  123. */
  124. public ResourceDiscover getDiscover() {
  125. return discoverResources;
  126. }
  127. /**
  128. * @return Enumeration of ServiceInfo
  129. */
  130. public ResourceNameIterator findResourceNames(final String fileName) {
  131. if (log.isDebugEnabled())
  132. log.debug("find: fileName='" + fileName + "'");
  133. return new ResourceNameIterator() {
  134. private ResourceIterator files =
  135. getDiscover().findResources(fileName);
  136. private int idx = 0;
  137. private Vector classNames = null;
  138. private String resource = null;
  139. public boolean hasNext() {
  140. if (resource == null) {
  141. resource = getNextClassName();
  142. }
  143. return resource != null;
  144. }
  145. public String nextResourceName() {
  146. String element = resource;
  147. resource = null;
  148. return element;
  149. }
  150. private String getNextClassName() {
  151. if (classNames == null || idx >= classNames.size()) {
  152. classNames = getNextClassNames();
  153. idx = 0;
  154. if (classNames == null) {
  155. return null;
  156. }
  157. }
  158. String className = (String)classNames.get(idx++);
  159. if (log.isDebugEnabled())
  160. log.debug("getNextClassResource: next class='" + className + "'");
  161. return className;
  162. }
  163. private Vector getNextClassNames() {
  164. while (files.hasNext()) {
  165. Vector results = readServices(files.nextResource());
  166. if (results != null && results.size() > 0) {
  167. return results;
  168. }
  169. }
  170. return null;
  171. }
  172. };
  173. }
  174. /**
  175. * Read everything, no defering here..
  176. * Ensure that files are closed before we leave.
  177. */
  178. private Vector readServices(final Resource info) {
  179. Vector results = new Vector();
  180. InputStream is = info.getResourceAsStream();
  181. if( is != null ) {
  182. try {
  183. try {
  184. // This code is needed by EBCDIC and other
  185. // strange systems. It's a fix for bugs
  186. // reported in xerces
  187. BufferedReader rd;
  188. try {
  189. rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  190. } catch (java.io.UnsupportedEncodingException e) {
  191. rd = new BufferedReader(new InputStreamReader(is));
  192. }
  193. try {
  194. String serviceImplName;
  195. while( (serviceImplName = rd.readLine()) != null) {
  196. int idx = serviceImplName.indexOf('#');
  197. if (idx >= 0) {
  198. serviceImplName = serviceImplName.substring(0, idx);
  199. }
  200. serviceImplName = serviceImplName.trim();
  201. if (serviceImplName.length() != 0) {
  202. results.add(serviceImplName);
  203. }
  204. }
  205. } finally {
  206. rd.close();
  207. }
  208. } finally {
  209. is.close();
  210. }
  211. } catch (IOException e) {
  212. // ignore
  213. }
  214. }
  215. return results;
  216. }
  217. }