001: /*
002: Copyright (c) 2003-2005, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.binding;
030:
031: import java.io.BufferedReader;
032: import java.io.FileInputStream;
033: import java.io.IOException;
034: import java.io.InputStream;
035: import java.io.InputStreamReader;
036: import java.lang.reflect.InvocationTargetException;
037: import java.lang.reflect.Method;
038: import java.util.ArrayList;
039:
040: import org.jibx.runtime.JiBXException;
041:
042: /**
043: * Bind-on-load class runner. This uses a binding loader to compile a binding,
044: * then loads and calls the main execution class for an application substituting
045: * the classes modified by the binding.
046: *
047: * @author Dennis M. Sosnoski
048: * @version 1.0
049: */
050:
051: public class Run {
052: private static final String BINDING_LIST_RESOURCE = "jibx_bindings.txt";
053: private static final String DEFAULT_BINDING_RESOURCE = "jibx_binding.xml";
054:
055: private Run() {
056: }
057:
058: /**
059: * Accumulate list of bindings from stream.
060: *
061: * @param is stream to be read for list of bindings (one per line)
062: * @param bindings accumulated collection of bindings
063: */
064: private static void addBindings(InputStream is, ArrayList bindings)
065: throws IOException {
066: BufferedReader rdr = new BufferedReader(new InputStreamReader(
067: is));
068: String line;
069: while ((line = rdr.readLine()) != null) {
070: if (line.length() > 0) {
071: bindings.add(line);
072: }
073: }
074: }
075:
076: /**
077: * Main method for bind-on-load handling.
078: *
079: * @param args command line arguments
080: */
081: public static void main(String[] args) {
082: if (args.length >= 1) {
083: try {
084:
085: // first get binding definitions and target class information
086: ArrayList files = new ArrayList();
087: ArrayList resources = new ArrayList();
088: int index = 0;
089: String target = null;
090: while (index < args.length) {
091: String arg = args[index++];
092: if ("-b".equals(arg)) {
093: if (index < args.length) {
094: files.add(args[index++]);
095: } else {
096: System.err
097: .println("Missing binding file and "
098: + "target class following '-b'");
099: }
100: } else if ("-l".equals(arg)) {
101: if (index < args.length) {
102: FileInputStream is = new FileInputStream(
103: args[index++]);
104: addBindings(is, files);
105: is.close();
106: } else {
107: System.err
108: .println("Missing binding list file "
109: + "and target class following '-l'");
110: }
111: } else if ("-r".equals(arg)) {
112: if (index < args.length) {
113: resources.add(args[index++]);
114: } else {
115: System.err
116: .println("Missing binding resource and "
117: + "target class following '-r'");
118: }
119: } else {
120: target = arg;
121: break;
122: }
123: }
124:
125: // make sure we have a target class name
126: if (target != null) {
127:
128: // save class name and create loader
129: Loader loader = new Loader();
130:
131: // check binding resources if no specified bindings
132: if (files.size() == 0 && resources.size() == 0) {
133: InputStream is = loader
134: .getResourceAsStream(BINDING_LIST_RESOURCE);
135: if (is == null) {
136: String name = target.replace('.', '/')
137: + "_" + BINDING_LIST_RESOURCE;
138: is = loader.getResourceAsStream(name);
139: }
140: if (is != null) {
141: addBindings(is, resources);
142: is.close();
143: } else {
144: String name = DEFAULT_BINDING_RESOURCE;
145: is = loader.getResourceAsStream(name);
146: if (is == null) {
147: name = target.replace('.', '/') + "_"
148: + DEFAULT_BINDING_RESOURCE;
149: is = loader.getResourceAsStream(name);
150: }
151: if (is != null) {
152: resources.add(name);
153: is.close();
154: }
155:
156: }
157: }
158:
159: // make sure at least one binding has been specified
160: if (files.size() == 0 && resources.size() == 0) {
161: System.err.println("No bindings found");
162: } else {
163:
164: // compile all bindings
165: for (int i = 0; i < files.size(); i++) {
166: loader.loadFileBinding((String) files
167: .get(i));
168: }
169: for (int i = 0; i < resources.size(); i++) {
170: String path = (String) resources.get(i);
171: String fname = Utility.fileName(path);
172: String bname = fname;
173: int split = bname.indexOf('.');
174: if (split >= 0) {
175: bname = bname.substring(0, split);
176: }
177: InputStream is = loader
178: .getResourceAsStream(path);
179: if (is == null) {
180: throw new IOException("Resource "
181: + path
182: + " not found on classpath");
183: }
184: loader.loadBinding(fname, Utility
185: .convertName(bname), is, null);
186: }
187: loader.processBindings();
188:
189: // load the target class using custom class loader
190: Class clas = loader.loadClass(target);
191:
192: // invoke the "main" method of the application class
193: Class[] ptypes = new Class[] { args.getClass() };
194: Method main = clas.getDeclaredMethod("main",
195: ptypes);
196: String[] pargs = new String[args.length - index];
197: System.arraycopy(args, index, pargs, 0,
198: pargs.length);
199: Thread.currentThread().setContextClassLoader(
200: loader);
201: main.invoke(null, new Object[] { pargs });
202:
203: }
204: }
205:
206: } catch (ClassNotFoundException e) {
207: e.printStackTrace();
208: } catch (NoSuchMethodException e) {
209: e.printStackTrace();
210: } catch (IllegalArgumentException e) {
211: e.printStackTrace();
212: } catch (IllegalAccessException e) {
213: e.printStackTrace();
214: } catch (InvocationTargetException e) {
215: e.printStackTrace();
216: } catch (JiBXException e) {
217: e.printStackTrace();
218: } catch (IOException e) {
219: e.printStackTrace();
220: }
221:
222: } else {
223: System.out
224: .println("Usage: org.jibx.binding.Run [-b binding-file][-l list-file]"
225: + "[-r binding-resource] main-class args...");
226: }
227: }
228: }
|