/core/src/main/java/org/apache/abdera/util/Discover.java

https://gitlab.com/praveen235/javaproject · Java · 268 lines · 232 code · 33 blank · 3 comment · 42 complexity · 63295fa156ed71bd57870b1e6731c70b MD5 · raw file

  1. package org.apache.abdera.util;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.net.URL;
  7. import java.util.ArrayList;
  8. import java.util.Collections;
  9. import java.util.Enumeration;
  10. import java.util.Iterator;
  11. import java.util.List;
  12. @SuppressWarnings("unchecked")
  13. public final class Discover {
  14. private Discover() {
  15. }
  16. public static <T> T locate(String id, String defaultImpl, Object... args) {
  17. return (T)locate(id, defaultImpl, getLoader(), args);
  18. }
  19. public static <T> T locate(String id, String defaultImpl, ClassLoader loader, Object... args) {
  20. try {
  21. T instance = null;
  22. Iterable<T> items = locate(id, loader, args);
  23. for (T i : items) {
  24. instance = i;
  25. break;
  26. }
  27. if (instance == null) {
  28. instance = (T)load(loader, defaultImpl, false, args);
  29. }
  30. return instance;
  31. } catch (Throwable t) {
  32. throw new RuntimeException(t);
  33. }
  34. }
  35. private static ClassLoader getLoader() {
  36. return Thread.currentThread().getContextClassLoader();
  37. }
  38. public static <T> Iterable<T> locate(String id, ClassLoader cl, Object... args) {
  39. return locate(id, false, cl, args);
  40. }
  41. public static <T> Iterable<T> locate(String id, boolean classesonly, ClassLoader cl, Object... args) {
  42. return locate(id, new DefaultLoader<T>(id, classesonly, args, cl));
  43. }
  44. public static <T> Iterable<T> locate(String id, Object... args) {
  45. return locate(id, false, args);
  46. }
  47. public static <T> Iterable<T> locate(String id, boolean classesonly) {
  48. return locate(id, new DefaultLoader<T>(id, classesonly, null));
  49. }
  50. public static <T> Iterable<T> locate(String id, boolean classesonly, Object... args) {
  51. return locate(id, new DefaultLoader<T>(id, classesonly, args));
  52. }
  53. public static <T> Iterable<T> locate(String id, Iterable<T> loader) {
  54. List<T> impls = Collections.synchronizedList(new ArrayList<T>());
  55. try {
  56. for (T instance : loader) {
  57. if (instance != null)
  58. impls.add(instance);
  59. }
  60. } catch (Throwable t) {
  61. t.printStackTrace();
  62. }
  63. return impls;
  64. }
  65. public static class DefaultLoader<T> implements Iterable<T> {
  66. protected final ClassLoader loader;
  67. protected final String id;
  68. protected final Iterator<T> iterator;
  69. protected final Object[] args;
  70. public DefaultLoader(String id, boolean classesonly, Object[] args) {
  71. this(id, classesonly, args, getLoader());
  72. }
  73. public DefaultLoader(String id, boolean classesonly, Object[] args, ClassLoader loader) {
  74. this.loader = loader != null ? loader : getLoader();
  75. this.id = id;
  76. this.iterator = init(classesonly);
  77. this.args = args;
  78. }
  79. private Iterator<T> init(boolean classesonly) {
  80. try {
  81. List<Iterator<T>> list = new ArrayList<Iterator<T>>();
  82. Enumeration<URL> e = locateResources("META-INF/services/" + id, //$NON-NLS-1$
  83. loader,
  84. Discover.class);
  85. while (e.hasMoreElements()) {
  86. Iterator<T> i =
  87. new DefaultLoaderIterator<T>(loader, e.nextElement().openStream(), classesonly, args);
  88. list.add(i);
  89. }
  90. return new MultiIterator<T>(list);
  91. } catch (Throwable t) {
  92. throw new RuntimeException(t);
  93. }
  94. }
  95. public Iterator<T> iterator() {
  96. return iterator;
  97. }
  98. }
  99. public static class DefaultLoaderIterator<T> extends LineReaderLoaderIterator<T> {
  100. public DefaultLoaderIterator(ClassLoader cl, InputStream in, boolean classesonly, Object[] args) {
  101. super(cl, in, classesonly, args);
  102. }
  103. public T next() {
  104. try {
  105. if (!hasNext())
  106. return null;
  107. return create(read(), args);
  108. } catch (Throwable t) {
  109. return null;
  110. }
  111. }
  112. protected T create(String spec, Object[] args) {
  113. try {
  114. return (T)load(cl, spec, classesonly, args);
  115. } catch (RuntimeException e) {
  116. throw e;
  117. } catch (Throwable t) {
  118. throw new RuntimeException(t);
  119. }
  120. }
  121. }
  122. private static <T> T load(ClassLoader loader, String spec, boolean classesonly, Object[] args) throws Exception {
  123. if (classesonly) {
  124. return (T)getClass(loader, spec);
  125. } else {
  126. Class<T> _class = getClass(loader, spec);
  127. Class<?>[] types = new Class<?>[args != null ? args.length : 0];
  128. if (args != null) {
  129. for (int n = 0; n < args.length; n++) {
  130. types[n] = args[n].getClass();
  131. }
  132. return _class.getConstructor(types).newInstance(args);
  133. } else {
  134. return _class.newInstance();
  135. }
  136. }
  137. }
  138. private static <T> Class<T> getClass(ClassLoader loader, String spec) {
  139. Class<T> c = null;
  140. try {
  141. c = (Class<T>)loader.loadClass(spec);
  142. } catch (ClassNotFoundException e) {
  143. try {
  144. // try loading the class from the Discover class loader
  145. // if the loader failed.
  146. c = (Class<T>)Discover.class.getClassLoader().loadClass(spec);
  147. } catch (ClassNotFoundException e1) {
  148. // throw the original exception
  149. throw new RuntimeException(e);
  150. }
  151. }
  152. return c;
  153. }
  154. public static abstract class LineReaderLoaderIterator<T> extends LoaderIterator<T> {
  155. private BufferedReader buf = null;
  156. private String line = null;
  157. protected final Object[] args;
  158. protected final boolean classesonly;
  159. protected LineReaderLoaderIterator(ClassLoader cl, InputStream in, boolean classesonly, Object[] args) {
  160. super(cl);
  161. this.args = args;
  162. this.classesonly = classesonly;
  163. try {
  164. InputStreamReader reader = new InputStreamReader(in, "UTF-8");
  165. buf = new BufferedReader(reader);
  166. line = readNext();
  167. } catch (Throwable t) {
  168. throw new RuntimeException(t);
  169. }
  170. }
  171. public boolean hasNext() {
  172. return line != null;
  173. }
  174. protected String readNext() {
  175. try {
  176. String line = null;
  177. while ((line = buf.readLine()) != null) {
  178. line = line.trim();
  179. if (!line.startsWith("#"))break; //$NON-NLS-1$
  180. }
  181. return line;
  182. } catch (Throwable t) {
  183. throw new RuntimeException(t);
  184. }
  185. }
  186. protected String read() {
  187. String val = line;
  188. line = readNext();
  189. return val;
  190. }
  191. }
  192. public static abstract class LoaderIterator<T> implements Iterator<T> {
  193. protected final ClassLoader cl;
  194. protected LoaderIterator(ClassLoader cl) {
  195. this.cl = cl;
  196. }
  197. public void remove() {
  198. }
  199. }
  200. public static URL locateResource(String id, ClassLoader loader, Class<?> callingClass) {
  201. URL url = loader.getResource(id);
  202. if (url == null && id.startsWith("/"))
  203. url = loader.getResource(id.substring(1));
  204. if (url == null)
  205. url = locateResource(id, Discover.class.getClassLoader(), callingClass);
  206. if (url == null && callingClass != null)
  207. url = locateResource(id, callingClass.getClassLoader(), null);
  208. if (url == null) {
  209. url = callingClass.getResource(id);
  210. }
  211. if ((url == null) && id.startsWith("/")) {
  212. url = callingClass.getResource(id.substring(1));
  213. }
  214. return url;
  215. }
  216. public static Enumeration<URL> locateResources(String id, ClassLoader loader, Class<?> callingClass)
  217. throws IOException {
  218. Enumeration<URL> urls = loader.getResources(id);
  219. if (urls == null && id.startsWith("/"))
  220. urls = loader.getResources(id.substring(1));
  221. if (urls == null)
  222. urls = locateResources(id, Discover.class.getClassLoader(), callingClass);
  223. if (urls == null)
  224. urls = locateResources(id, callingClass.getClassLoader(), callingClass);
  225. return urls;
  226. }
  227. public static InputStream locateResourceAsStream(String resourceName, ClassLoader loader, Class<?> callingClass) {
  228. URL url = locateResource(resourceName, loader, callingClass);
  229. try {
  230. return (url != null) ? url.openStream() : null;
  231. } catch (IOException e) {
  232. return null;
  233. }
  234. }
  235. }