001: /*
002: * XML 2 Java Binding (X2JB) - the excellent Java tool.
003: * Copyright 2007, by Richard Opalka.
004: *
005: * This is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as
007: * published by the Free Software Foundation; either version 2.1 of
008: * the License, or (at your option) any later version.
009: *
010: * This software is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this software; if not see the FSF site:
017: * http://www.fsf.org/ and search for the LGPL License document there.
018: */
019: package org.x2jb.bind;
020:
021: import java.io.BufferedReader;
022: import java.io.InputStream;
023: import java.io.InputStreamReader;
024: import java.text.MessageFormat;
025: import org.x2jb.bind.Messages.BundleKey;
026:
027: /**
028: * This class is used to locate factory classes for XML 2 Java Binding framework
029: *
030: * @author <a href="mailto:richard_opalka@yahoo.com">Richard Opalka</a>
031: * @version 1.0
032: */
033: final class FactoryFinder {
034:
035: private static final String SERVICES_DIR = "META-INF/services/";
036: private static final String UTF8 = "UTF-8";
037: private static final String EMPTY_STRING = "";
038:
039: private FactoryFinder() {
040: // no instances
041: }
042:
043: /**
044: * instantiates an object go the given classname
045: *
046: * @param factoryClassName
047: * @return a factory object
048: * @throws BindingException
049: */
050: private static Object newInstance(String factoryClassName) {
051: ClassLoader classloader = null;
052:
053: try {
054: classloader = Thread.currentThread()
055: .getContextClassLoader();
056: } catch (Exception exception) {
057: throw new RuntimeException(exception.toString(), exception);
058: }
059:
060: try {
061: Class factory = null;
062:
063: if (classloader == null) {
064: factory = Class.forName(factoryClassName);
065: } else {
066: try {
067: factory = classloader.loadClass(factoryClassName);
068: } catch (ClassNotFoundException ignore) {
069: }
070: }
071:
072: if (factory == null) {
073: classloader = FactoryFinder.class.getClassLoader();
074: factory = classloader.loadClass(factoryClassName);
075: }
076:
077: return factory.newInstance();
078: } catch (ClassNotFoundException cnfe) {
079: throw new RuntimeException(MessageFormat.format(Messages
080: .get(BundleKey.FACTORY_NOT_FOUND),
081: new Object[] { factoryClassName }));
082: } catch (Exception e) {
083: throw new RuntimeException(MessageFormat.format(Messages
084: .get(BundleKey.FACTORY_NOT_INSTATIATED),
085: new Object[] { factoryClassName }), e);
086: }
087: }
088:
089: /**
090: * Instantiates a factory object given the factory's property name and the
091: * default class name
092: *
093: * @param factoryPropertyName
094: * @param defaultFactoryClassName
095: * @return a factory object
096: * @throws BindingException
097: */
098: static Object find(String factoryPropertyName) {
099: try {
100: String factoryClassName = System
101: .getProperty(factoryPropertyName);
102: if (factoryClassName != null) {
103: return newInstance(factoryClassName);
104: }
105: } catch (SecurityException ignore) {
106: }
107:
108: String factoryResource = SERVICES_DIR + factoryPropertyName;
109:
110: try {
111: InputStream inputstream = getResource(factoryResource);
112: if (inputstream != null) {
113: BufferedReader bufferedreader = new BufferedReader(
114: new InputStreamReader(inputstream, UTF8));
115: String factoryClassName = bufferedreader.readLine()
116: .trim();
117: bufferedreader.close();
118: if ((factoryClassName != null)
119: && !EMPTY_STRING.equals(factoryClassName)) {
120: return newInstance(factoryClassName);
121: }
122: }
123: } catch (Exception ignore) {
124: }
125:
126: throw new RuntimeException(MessageFormat.format(Messages
127: .get(BundleKey.FACTORY_FOR_PROPERTY_NOT_FOUND),
128: new Object[] { factoryPropertyName }));
129: }
130:
131: /**
132: * Returns an input stream for the specified resource.
133: * @param factoryResource the resource name
134: * @return an InputStream that can be used to read that resource, or
135: * <code>null</code> if the resource could not be resolved
136: */
137: private static InputStream getResource(String factoryResource) {
138: ClassLoader classloader = null;
139:
140: try {
141: classloader = Thread.currentThread()
142: .getContextClassLoader();
143: } catch (SecurityException ignore) {
144: }
145:
146: InputStream inputstream;
147: if (classloader == null) {
148: inputstream = ClassLoader
149: .getSystemResourceAsStream(factoryResource);
150: } else {
151: inputstream = classloader
152: .getResourceAsStream(factoryResource);
153: }
154:
155: if (inputstream == null) {
156: inputstream = FactoryFinder.class.getClassLoader()
157: .getResourceAsStream(factoryResource);
158: }
159:
160: return inputstream;
161: }
162: }
|