001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.base.location;
019:
020: import java.net.MalformedURLException;
021: import java.net.URL;
022: import java.util.HashMap;
023: import java.util.Map;
024:
025: import org.ofbiz.base.util.UtilProperties;
026:
027: /**
028: * A special location resolver that uses Strings like URLs, but with more options
029: *
030: */
031:
032: public class FlexibleLocation {
033:
034: protected static Map locationResolvers = new HashMap();
035:
036: protected static Map defaultResolvers = new HashMap();
037:
038: protected static String standardUrlResolverName = StandardUrlLocationResolver.class
039: .getName();
040: protected static String classpathResolverName = ClasspathLocationResolver.class
041: .getName();
042: protected static String ofbizHomeResolverName = OFBizHomeLocationResolver.class
043: .getName();
044: protected static String componentResolverName = ComponentLocationResolver.class
045: .getName();
046:
047: static {
048: defaultResolvers.put("http", standardUrlResolverName);
049: defaultResolvers.put("https", standardUrlResolverName);
050: defaultResolvers.put("ftp", standardUrlResolverName);
051: defaultResolvers.put("jar", standardUrlResolverName);
052: defaultResolvers.put("file", standardUrlResolverName);
053:
054: defaultResolvers.put("classpath", classpathResolverName);
055: defaultResolvers.put("ofbizhome", ofbizHomeResolverName);
056: defaultResolvers.put("component", componentResolverName);
057: }
058:
059: /**
060: * Resolves the gives location into a URL object for use in various ways.
061: *
062: * The general format of the location is like a URL: {locationType}://location/path/file.ext
063: *
064: * Supports standard locationTypes like http, https, ftp, jar, & file
065: * Supports a classpath location type for when desired to be used like any other URL
066: * Supports OFBiz specific location types like ofbizhome and component
067: * Supports additional locationTypes specified in the locationresolvers.properties file
068: *
069: * @param location The location String to parse and create a URL from
070: * @return URL object corresponding to the location String passed in
071: * @throws MalformedURLException
072: */
073: public static URL resolveLocation(String location)
074: throws MalformedURLException {
075: return resolveLocation(location, null);
076: }
077:
078: public static URL resolveLocation(String location,
079: ClassLoader loader) throws MalformedURLException {
080: if (location == null || location.length() == 0) {
081: return null;
082: }
083: String locationType = getLocationType(location);
084:
085: LocationResolver resolver = (LocationResolver) locationResolvers
086: .get(locationType);
087: if (resolver == null) {
088: synchronized (FlexibleLocation.class) {
089: resolver = (LocationResolver) locationResolvers
090: .get(locationType);
091: if (resolver == null) {
092: String locationResolverName = UtilProperties
093: .getPropertyValue("locationresolvers",
094: locationType);
095: if (locationResolverName == null
096: || locationResolverName.length() == 0) {
097: // try one of the defaults
098: locationResolverName = (String) defaultResolvers
099: .get(locationType);
100: }
101:
102: if (locationResolverName == null
103: || locationResolverName.length() == 0) {
104: // still nothing, give up
105: throw new MalformedURLException(
106: "Could not find a LocationResolver class name for the location type: "
107: + locationType);
108: }
109:
110: // now create a new instance of the class...
111: try {
112: Class lClass = null;
113:
114: try {
115: ClassLoader classLoader = Thread
116: .currentThread()
117: .getContextClassLoader();
118: lClass = classLoader
119: .loadClass(locationResolverName);
120: } catch (ClassNotFoundException e) {
121: throw new MalformedURLException(
122: "Error loading Location Resolver class \""
123: + locationResolverName
124: + "\": " + e.toString());
125: }
126:
127: try {
128: resolver = (LocationResolver) lClass
129: .newInstance();
130: } catch (IllegalAccessException e) {
131: throw new MalformedURLException(
132: "Error loading Location Resolver class \""
133: + locationResolverName
134: + "\": " + e.toString());
135: } catch (InstantiationException e) {
136: throw new MalformedURLException(
137: "Error loading Location Resolver class \""
138: + locationResolverName
139: + "\": " + e.toString());
140: }
141: } catch (SecurityException e) {
142: throw new MalformedURLException(
143: "Error loading Location Resolver class \""
144: + locationResolverName + "\": "
145: + e.toString());
146: }
147:
148: if (resolver != null) {
149: locationResolvers.put(locationType, resolver);
150: }
151: }
152: }
153: }
154:
155: if (resolver != null) {
156: if (loader != null
157: && resolver instanceof ClasspathLocationResolver) {
158: ClasspathLocationResolver cplResolver = (ClasspathLocationResolver) resolver;
159: return cplResolver.resolveLocation(location, loader);
160: } else {
161: return resolver.resolveLocation(location);
162: }
163: } else {
164: throw new MalformedURLException(
165: "Could not find a LocationResolver for the location type: "
166: + locationType);
167: }
168: }
169:
170: /**
171: * Find the location type descriptor for the passed location String;
172: * generally is all text before the first ":" character.
173: * If no type descriptor is found, defaults to "classpath".
174: */
175: public static String getLocationType(String location) {
176: if (location == null || location.length() == 0) {
177: return null;
178: }
179:
180: int colonIndex = location.indexOf(":");
181: if (colonIndex > 0) {
182: return location.substring(0, colonIndex);
183: } else {
184: return "classpath";
185: }
186: }
187:
188: public static String stripLocationType(String location) {
189: if (location == null || location.length() == 0) {
190: return "";
191: }
192:
193: StringBuffer strippedSoFar = new StringBuffer(location);
194:
195: // first take care of the colon and everything before it
196: int colonIndex = strippedSoFar.indexOf(":");
197: if (colonIndex == 0) {
198: strippedSoFar.deleteCharAt(0);
199: } else if (colonIndex > 0) {
200: strippedSoFar.delete(0, colonIndex + 1);
201: }
202:
203: // now remove any extra forward slashes, ie as long as the first two are forward slashes remove the first one
204: while (strippedSoFar.charAt(0) == '/'
205: && strippedSoFar.charAt(1) == '/') {
206: strippedSoFar.deleteCharAt(0);
207: }
208:
209: return strippedSoFar.toString();
210: }
211: }
|