001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.lib.contract.lang.cache;
028:
029: import java.util.*;
030: import java.lang.reflect.*;
031:
032: import org.cougaar.lib.contract.lang.*;
033:
034: /**
035: * Class reflection utilities.
036: * <p>
037: * Add cache here.
038: **/
039: public final class ClassCache {
040:
041: /** classname package prefixes used by <tt>findClass</tt>. **/
042: private static String[] packages = new String[0];
043:
044: /** Not synchronized with <tt>findClass</tt>!. */
045: public static final void setPackages(Collection c) {
046: packages = new String[c.size()];
047: Iterator iter = c.iterator();
048: for (int i = 0; iter.hasNext(); i++) {
049: Object oi = iter.next();
050: if (!(oi instanceof String)) {
051: throw new ClassCastException(
052: "Expecting \"String\" packages");
053: }
054: packages[i] = (String) oi;
055: }
056: }
057:
058: /** Not synchronized with <tt>findClass</tt>!. */
059: public static final void setPackages(String[] sa) {
060: if (sa != null) {
061: packages = new String[sa.length];
062: for (int i = 0; i < sa.length; i++) {
063: String si = sa[i];
064: if (si == null) {
065: throw new ClassCastException(
066: "Expecting \"String\" packages");
067: }
068: packages[i] = si;
069: }
070: } else {
071: packages = new String[0];
072: }
073: }
074:
075: public static final String toString(final Class c) {
076: return toString(c, true);
077: }
078:
079: /**
080: * Format <code>Class</code> to trim known packages.
081: */
082: public static final String toString(final Class c,
083: final boolean verbose) {
084: String s = c.getName();
085: if (!verbose) {
086: int pkgSep = s.lastIndexOf('.');
087: if (pkgSep > 0) {
088: ++pkgSep;
089: for (int i = 0; i < packages.length; i++) {
090: String pi = packages[i];
091: if ((pi.length() == pkgSep) && (s.startsWith(pi))) {
092: // use short classname within package
093: s = s.substring(pkgSep);
094: break;
095: }
096: }
097: }
098: }
099: return s.replace('$', '.');
100: }
101:
102: /**
103: * Find <code>Class</code> "name".
104: **/
105: public static final Class lookup(final String name) {
106: // try the given name
107: try {
108: return Class.forName(name);
109: } catch (Exception e) {
110: }
111:
112: // see if it contains a "."
113: int dotSep = name.lastIndexOf('.');
114: if (dotSep < 0) {
115: // no "." -- try prefixing with packages
116: for (int i = 0; i < packages.length; i++) {
117: String fullname = packages[i] + name;
118: try {
119: return Class.forName(fullname);
120: } catch (Exception e) {
121: }
122: }
123: // no such class
124: return null;
125: }
126:
127: // see if this is some inner class, which requires the
128: // substitution of the "." separator with a "$"
129: String currName = name;
130: while (true) {
131: // replace the last "." with a "$"
132: StringBuffer buf = new StringBuffer(currName);
133: buf.setCharAt(dotSep, '$');
134: currName = buf.toString();
135:
136: // try package prefixes
137: String fullname = currName;
138: int i = -1;
139: while (true) {
140: try {
141: return Class.forName(fullname);
142: } catch (Exception e) {
143: }
144: if (++i >= packages.length) {
145: break;
146: }
147: fullname = packages[i] + currName;
148: }
149:
150: // get the next "."
151: dotSep = currName.lastIndexOf('.');
152: if (dotSep < 0) {
153: // no more potential inner classes
154: break;
155: }
156: }
157:
158: // no such class
159: return null;
160: }
161: }
|