1 /* 2 * Copyright 2011-2012 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.util.lang; 17 18 import java.io.IOException; 19 import java.io.InputStream; 20 import java.net.MalformedURLException; 21 import java.net.URL; 22 import java.util.Enumeration; 23 24 import org.apache.commons.lang.ObjectUtils; 25 26 /** 27 * A constraint on resources to be loaded from the class path. 28 */ 29 public final class ClassPathContext 30 { 31 // ********************************* Fields ********************************* 32 33 // --- constants ------------------------------------------------------------ 34 35 // --- members -------------------------------------------------------------- 36 37 /** 38 * The class loader to load the directory listings. 39 */ 40 private final ClassLoader classLoader; 41 42 /** 43 * Selects the archive root to load from. 44 */ 45 private final String archiveRoot; 46 47 // ****************************** Initializer ******************************* 48 49 // ****************************** Constructors ****************************** 50 51 /** 52 * Default constructor. 53 * 54 * @param classLoader the class loader to load the directory listings. 55 * @param archiveRoot the value for archiveRoot. 56 * @throws NullPointerException if {@code classLoader} is <code>null</code>. 57 */ 58 public ClassPathContext(final ClassLoader classLoader, 59 final String archiveRoot) throws NullPointerException 60 { 61 Arguments.checkNotNull("classLoader", classLoader); 62 63 this.classLoader = classLoader; 64 this.archiveRoot = archiveRoot; 65 } 66 67 // ****************************** Inner Classes ***************************** 68 69 // ********************************* Methods ******************************** 70 71 // --- init ----------------------------------------------------------------- 72 73 // --- get&set -------------------------------------------------------------- 74 75 // --- business ------------------------------------------------------------- 76 77 /** 78 * Constructs the URL to the resource. 79 * 80 * @param resource the resource whose URL is requested. 81 * @return the URL to the resource or <code>null</code> if the resource cannot 82 * be found on the class path. 83 */ 84 public URL getResource(final String resource) 85 { 86 if (archiveRoot == null) 87 { 88 return classLoader.getResource(resource); 89 } 90 91 // TODO: maybe we should simply construct the URL? 92 try 93 { 94 for (final Enumeration<URL> en = classLoader.getResources(resource); en 95 .hasMoreElements();) 96 { 97 final URL current = en.nextElement(); 98 final String urlString = current.toExternalForm(); 99 if (urlString.startsWith(archiveRoot)) 100 { 101 return current; 102 } 103 } 104 } 105 catch (final IOException e) 106 { 107 // return null 108 } 109 return null; 110 } 111 112 /** 113 * Opens the stream to the resource. 114 * 115 * @param resource the resource whose stream is requested. 116 * @return the stream to the resource or <code>null</code> if the resource 117 * cannot be found on the class path. If a stream is returned, the 118 * client is responsible to close that stream. 119 */ 120 public InputStream getResourceAsStream(final String resource) 121 { 122 final URL url = getResource(resource); 123 if (url != null) 124 { 125 try 126 { 127 return url.openStream(); 128 } 129 catch (final IOException e) 130 { 131 // return null; 132 } 133 } 134 return null; 135 } 136 137 /** 138 * Constructs the URL to the resource. 139 * 140 * @param resource the resource whose URL is requested. 141 * @return the constructed URL. 142 * @throws IllegalArgumentException if the URL to the resource cannot be 143 * constructed. 144 */ 145 public URL createUrl(final String resource) throws IllegalArgumentException 146 { 147 try 148 { 149 final String urlString = 150 (archiveRoot != null ? archiveRoot : "") + resource; 151 return new URL(urlString); 152 } 153 catch (final MalformedURLException e) 154 { 155 throw new IllegalArgumentException("Cannot construct URL with resource '" 156 + resource + "'.", e); 157 } 158 } 159 160 // --- object basics -------------------------------------------------------- 161 162 /** 163 * Returns the hash code of the object. 164 * 165 * @return the hash code. 166 */ 167 @Override 168 public int hashCode() 169 { 170 return ObjectUtils.hashCode(archiveRoot); 171 } 172 173 /** 174 * Returns <code>true</code> if the given object is semantically equal to the 175 * given object, <code>false</code> otherwise. 176 * 177 * @param object the instance to compare to. 178 * @return <code>true</code> if the given object is semantically equal to the 179 * given object, <code>false</code> otherwise. 180 */ 181 @Override 182 public boolean equals(final Object object) 183 { 184 if (this == object) 185 { 186 return true; 187 } 188 else if (object == null || getClass() != object.getClass()) 189 { 190 return false; 191 } 192 193 final ClassPathContext other = (ClassPathContext) object; 194 195 return ObjectUtils.equals(archiveRoot, other.archiveRoot); 196 } 197 198 @Override 199 public String toString() 200 { 201 return archiveRoot != null ? archiveRoot : "<unspecified archive root>"; 202 } 203 }