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 }