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;
018
019 import org.apache.commons.discovery.Resource;
020 import org.apache.commons.discovery.ResourceDiscover;
021 import org.apache.commons.discovery.ResourceIterator;
022 import org.apache.commons.discovery.ResourceNameIterator;
023 import org.apache.commons.discovery.resource.names.ResourceNameDiscoverImpl;
024
025 /**
026 * Helper class for methods implementing the ResourceDiscover interface.
027 */
028 public abstract class ResourceDiscoverImpl extends ResourceNameDiscoverImpl implements ResourceDiscover {
029
030 private ClassLoaders classLoaders;
031
032 /**
033 * Construct a new resource discoverer.
034 */
035 public ResourceDiscoverImpl() {
036 }
037
038 /**
039 * Construct a new resource discoverer.
040 *
041 * @param classLoaders The class laoders holder
042 */
043 public ResourceDiscoverImpl(ClassLoaders classLoaders) {
044 setClassLoaders(classLoaders);
045 }
046
047 /**
048 * Specify set of class loaders to be used in searching.
049 *
050 * @param loaders The class laoders holder
051 */
052 public void setClassLoaders(ClassLoaders loaders) {
053 classLoaders = loaders;
054 }
055
056 /**
057 * Specify a new class loader to be used in searching.
058 *
059 * The order of loaders determines the order of the result.
060 * It is recommended to add the most specific loaders first.
061 *
062 * @param loader The new class loader to be added
063 */
064 public void addClassLoader(ClassLoader loader) {
065 getClassLoaders().put(loader);
066 }
067
068 /**
069 * Returns the class loaders holder.
070 *
071 * @return The class loaders holder
072 */
073 protected ClassLoaders getClassLoaders() {
074 if (classLoaders == null) {
075 classLoaders = ClassLoaders.getLibLoaders(this.getClass(), null, true);
076 }
077 return classLoaders;
078 }
079
080 /**
081 * {@inheritDoc}
082 */
083 @Override
084 public ResourceNameIterator findResourceNames(String resourceName) {
085 return findResources(resourceName);
086 }
087
088 /**
089 * {@inheritDoc}
090 */
091 @Override
092 public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames) {
093 return findResources(resourceNames);
094 }
095
096 /**
097 * Locate resources that are bound to {@code resourceName}.
098 *
099 * @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 }