001: package org.jacorb.util;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.io.BufferedReader;
024: import java.io.IOException;
025: import java.net.MalformedURLException;
026: import java.net.URL;
027:
028: /**
029: * @author Gerald Brose, FU Berlin
030: * @version $Id: ObjectUtil.java,v 1.21 2006/11/30 13:11:07 alphonse.bendt Exp $
031: */
032:
033: public class ObjectUtil {
034: //for byte -> hexchar
035: private static final char[] lookup = new char[] { '0', '1', '2',
036: '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
037: 'F' };
038:
039: private ObjectUtil() {
040: // utility class
041: }
042:
043: /**
044: * @return the contents of the resource as a string, or null
045: * if the contents of the resource could not be located using url
046: */
047: public static final String readURL(String url)
048: throws java.io.IOException {
049: final BufferedReader reader = new BufferedReader(
050: newInputStreamReader(url));
051:
052: try {
053: return reader.readLine();
054: } finally {
055: reader.close();
056: }
057: }
058:
059: private static java.io.InputStreamReader newInputStreamReader(
060: String url) throws MalformedURLException, IOException {
061: String token = "file://";
062: java.io.InputStreamReader isr = null;
063: if (url.startsWith(token)) {
064: try {
065: isr = new java.io.FileReader(url.substring(token
066: .length()));
067: } catch (Exception e) {
068: System.out.println("Tried and failed to open file: " + // NOPMD
069: url.substring(token.length()));
070: // no worries, let the URL handle it
071: }
072: }
073:
074: if (isr == null) {
075: java.net.URL urlCopy = new java.net.URL(url);
076: isr = new java.io.InputStreamReader(urlCopy.openStream());
077: }
078: return isr;
079: }
080:
081: /**
082: * Returns the <code>Class</code> object for the class or interface
083: * with the given string name. This method is a replacement for
084: * <code>Class.forName(String name)</code>. Unlike
085: * <code>Class.forName(String name)</code> (which always uses the
086: * caller's loader or one of its ancestors), <code>classForName</code>
087: * uses a thread-specific loader that has no delegation relationship
088: * with the caller's loader. It attempts the load the desired class
089: * with the thread-specific context class loader and falls back to
090: * <code>Class.forName(String name)</code> only if the context class
091: * loader cannot load the class.
092: * <p>
093: * Loading a class with a loader that is not necessarily an ancestor
094: * of the caller's loader is a crucial thing in many scenarios. As an
095: * example, assume that JacORB was loaded by the boot class loader,
096: * and suppose that some code in JacORB contains a call
097: * <code>Class.forName(someUserClass)</code>. Such usage of
098: * <code>Class.forName</code> effectively forces the user to place
099: * <code>someUserClass</code> in the boot class path. If
100: * <code>classForName(someUserClass)</code> were used instead, the user
101: * class would be loaded by the context class loader, which by default
102: * is set to the system (CLASSPATH) classloader.
103: * <p>
104: * In this simple example above, the default setting of the context class
105: * loader allows classes in the boot classpath to reach classes in the
106: * system classpath. In other scenarios, the context class loader might
107: * be different from the system classloader. Middleware systems like
108: * servlet containers or EJB containers set the context class loader so
109: * that a given thread can reach user-provided classes that are not in
110: * the system classpath.
111: * <p>
112: * For maximum flexibility, <code>classForName</code> should replace
113: * <code>Class.forName(String name)</code> in nearly all cases.
114: *
115: * @param name the fully qualified name of a class
116: *
117: * @return the Class object for that class
118: *
119: * @throws IllegalArgumentException if <code>name</code> is null
120: * @throws ClassNotFoundException if the named class cannot be found
121: * @throws LinkageError if the linkage fails
122: * @throws ExceptionInInitializerError if the class initialization fails
123: */
124:
125: public static Class classForName(String name)
126: throws ClassNotFoundException, IllegalArgumentException {
127: if (name == null) {
128: throw new IllegalArgumentException(
129: "Class name must not be null!");
130: }
131:
132: try {
133: // Here we prefer classLoader.loadClass() over the three-argument
134: // form of Class.forName(), as the latter is reported to cause
135: // caching of stale Class instances (due to a buggy cache of
136: // loaded classes).
137: return Thread.currentThread().getContextClassLoader()
138: .loadClass(name);
139: } catch (Exception e) {
140: // As a fallback, we prefer Class.forName(name) because it loads
141: // array classes (i.e., it handles arguments like
142: // "[Lsome.class.Name;" or "[[I;", which classLoader.loadClass()
143: // does not handle).
144: return Class.forName(name);
145: }
146: }
147:
148: public static String bufToString(byte values[], int start, int len) {
149: final StringBuffer result = new StringBuffer();
150: final StringBuffer chars = new StringBuffer();
151:
152: for (int i = start; i < (start + len); i++) {
153: if ((i % 16) == 0) {
154: result.append(chars.toString());
155: result.append('\n');
156: chars.setLength(0);
157: }
158:
159: chars.append(toAscii(values[i]));
160: result.append(toHex(values[i]));
161:
162: if ((i % 4) == 3) {
163: chars.append(' ');
164: result.append(' ');
165: }
166: }
167:
168: if (len % 16 != 0) {
169: int pad = 0;
170: int delta_bytes = 16 - (len % 16);
171:
172: //rest of line (no of bytes)
173: //each byte takes two chars plus one ws
174: pad = delta_bytes * 3;
175:
176: //additional whitespaces after four bytes
177: pad += (delta_bytes / 4);
178:
179: // additional whitespace after completed 4 byte block
180: if ((delta_bytes % 4) > 0) {
181: pad += 1;
182: }
183:
184: for (int i = 0; i < pad; i++) {
185: chars.insert(0, ' ');
186: }
187: }
188:
189: result.append(chars.toString());
190: return result.toString();
191: }
192:
193: /**
194: * <code>toHex</code> converts a byte into a readable string.
195: *
196: * @param value a <code>byte</code> value
197: * @return a <code>String</code> value
198: */
199:
200: public static final String toHex(byte value) {
201: final StringBuffer buffer = new StringBuffer();
202:
203: int upper = (value >> 4) & 0x0F;
204: buffer.append(lookup[upper]);
205:
206: int lower = value & 0x0F;
207: buffer.append(lookup[lower]);
208:
209: buffer.append(' ');
210:
211: return buffer.toString();
212: }
213:
214: public static final char toAscii(byte value) {
215: if (value > (byte) 31 && value < (byte) 127) {
216: return (char) value;
217: }
218:
219: return '.';
220: }
221:
222: /**
223: * Convenience method to parse an argument vector (typically from
224: * the command line) and sets any arguments of the form "-Dy=x"
225: * as values in a properties object.
226: */
227:
228: public static java.util.Properties argsToProps(String[] args) {
229: java.util.Properties props = new java.util.Properties();
230:
231: for (int i = 0; i < args.length; i++) {
232: if (args[i].startsWith("-D")) {
233: int idx = args[i].indexOf('=');
234: if (idx < 3) {
235: continue;
236: }
237: String key = args[i].substring(2, idx);
238:
239: props.put(key, args[i].substring(idx + 1));
240: }
241: }
242: return props;
243: }
244:
245: public static URL getResource(String name) {
246: if (Thread.currentThread().getContextClassLoader() != null) {
247: return Thread.currentThread().getContextClassLoader()
248: .getResource(name);
249: }
250: return ObjectUtil.class.getResource(name);
251: }
252:
253: /**
254: * factory method to create Integers from ints.
255: * should be used throughout the code to prepare
256: * transition to JDK 1.5 (Integer.valueOf(int))
257: */
258: public static Integer newInteger(int value) {
259: return new Integer(value); // NOPMD
260: }
261: }
|