1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.discovery.resource;
18
19 import org.apache.commons.discovery.Resource;
20 import org.apache.commons.discovery.ResourceDiscover;
21 import org.apache.commons.discovery.ResourceIterator;
22 import org.apache.commons.discovery.ResourceNameIterator;
23 import org.apache.commons.discovery.resource.names.ResourceNameDiscoverImpl;
24
25 /**
26 * Helper class for methods implementing the ResourceDiscover interface.
27 */
28 public abstract class ResourceDiscoverImpl extends ResourceNameDiscoverImpl implements ResourceDiscover {
29
30 private ClassLoaders classLoaders;
31
32 /**
33 * Construct a new resource discoverer.
34 */
35 public ResourceDiscoverImpl() {
36 }
37
38 /**
39 * Construct a new resource discoverer.
40 *
41 * @param classLoaders The class laoders holder
42 */
43 public ResourceDiscoverImpl(ClassLoaders classLoaders) {
44 setClassLoaders(classLoaders);
45 }
46
47 /**
48 * Specify set of class loaders to be used in searching.
49 *
50 * @param loaders The class laoders holder
51 */
52 public void setClassLoaders(ClassLoaders loaders) {
53 classLoaders = loaders;
54 }
55
56 /**
57 * Specify a new class loader to be used in searching.
58 *
59 * The order of loaders determines the order of the result.
60 * It is recommended to add the most specific loaders first.
61 *
62 * @param loader The new class loader to be added
63 */
64 public void addClassLoader(ClassLoader loader) {
65 getClassLoaders().put(loader);
66 }
67
68 /**
69 * Returns the class loaders holder.
70 *
71 * @return The class loaders holder
72 */
73 protected ClassLoaders getClassLoaders() {
74 if (classLoaders == null) {
75 classLoaders = ClassLoaders.getLibLoaders(this.getClass(), null, true);
76 }
77 return classLoaders;
78 }
79
80 /**
81 * {@inheritDoc}
82 */
83 @Override
84 public ResourceNameIterator findResourceNames(String resourceName) {
85 return findResources(resourceName);
86 }
87
88 /**
89 * {@inheritDoc}
90 */
91 @Override
92 public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames) {
93 return findResources(resourceNames);
94 }
95
96 /**
97 * Locate resources that are bound to {@code resourceName}.
98 *
99 * @param resourceName The resource name has to be located
100 * @return The located resources iterator
101 */
102 public abstract ResourceIterator findResources(String resourceName);
103
104 /**
105 * Locate resources that are bound to <code>resourceNames</code>.
106 *
107 * @param inputNames The resources name iterator has to be located
108 * @return The located resources iterator
109 */
110 public ResourceIterator findResources(final ResourceNameIterator inputNames) {
111 return new ResourceIterator() {
112
113 private ResourceIterator resources = null;
114
115 private Resource resource = null;
116
117 public boolean hasNext() {
118 if (resource == null) {
119 resource = getNextResource();
120 }
121 return resource != null;
122 }
123
124 @Override
125 public Resource nextResource() {
126 Resource rsrc = resource;
127 resource = null;
128 return rsrc;
129 }
130
131 private Resource getNextResource() {
132 while (inputNames.hasNext() &&
133 (resources == null || !resources.hasNext())) {
134 resources = findResources(inputNames.nextResourceName());
135 }
136
137 return (resources != null && resources.hasNext())
138 ? resources.nextResource()
139 : null;
140 }
141 };
142 }
143
144 }