001: /**
002: * JavaGuard -- an obfuscation package for Java classfiles.
003: *
004: * Copyright (c) 1999 Mark Welsh (markw@retrologic.com)
005: * Copyright (c) 2002 Thorsten Heit (theit@gmx.de)
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * The author may be contacted at theit@gmx.de.
022: *
023: *
024: * $Id: Tools.java,v 1.1 2002/05/11 18:52:09 glurk Exp $
025: */package net.sf.javaguard;
026:
027: import java.util.Vector;
028:
029: /** The Tools class contains generally useful, miscellaneous static methods.
030: *
031: * @author <a href="mailto:theit@gmx.de">Thorsten Heit</a>
032: * @author <a href="mailto:markw@retrologic.com">Mark Welsh</a>
033: */
034: public class Tools {
035: /** Checks whether a string is contained in a given array.
036: * @param s the string to check
037: * @param list the string array
038: * @return true if the string is contained in the array; false else
039: */
040: public static boolean isInArray(String s, String[] list) {
041: for (int i = 0; i < list.length; i++) {
042: if (s.equals(list[i]))
043: return true;
044: }
045: return false;
046: }
047:
048: /** Checks whether a string is contained in a given array. Capitalization is
049: * ignored when comparing strings.
050: * @param s the string to check
051: * @param list the string array
052: * @return true if the string is contained in the array; false else
053: */
054: public static boolean isInArrayIgnoreCase(String s, String[] list) {
055: for (int i = 0; i < list.length; i++) {
056: if (s.equalsIgnoreCase(list[i]))
057: return true;
058: }
059: return false;
060: }
061:
062: /** Parse a method or field descriptor into a list of parameter names (for
063: * methods) and a return type. The format is the same as the Class.forName()
064: * method returns.
065: * @param descriptor the method or field descriptor to parse
066: * @return array with parameter names and a return type
067: * @see #parseDescriptor(String, boolean)
068: * @throws IllegalStateException if an error occurs
069: */
070: public static String[] parseDescriptor(String descriptor)
071: throws IllegalStateException {
072: return parseDescriptor(descriptor, false);
073: }
074:
075: /** Parse a method or field descriptor into a list of parameter names (for
076: * methods) and a return type. The format is the same as the Class.forName()
077: * method returns.
078: * @param descriptor the method or field descriptor to parse
079: * @param isDisplay true if the pretty display form for array types should be
080: * used; false if slashes in array type names should be replaced by the
081: * dot character
082: * @return array with parameter names and a return type
083: * @see #parseDescriptor(String)
084: * @throws IllegalStateException if an error occurs
085: */
086: public static String[] parseDescriptor(String descriptor,
087: boolean isDisplay) throws IllegalStateException {
088: // Check for field descriptor
089: String[] names = null;
090: if (descriptor.charAt(0) != '(') {
091: names = new String[1];
092: names[0] = descriptor;
093: } else {
094: // Method descriptor
095: Vector namesVec = new Vector();
096: descriptor = descriptor.substring(1);
097: String type = "";
098: while (descriptor.length() > 0) {
099: switch (descriptor.charAt(0)) {
100: case '[':
101: type = type + "[";
102: descriptor = descriptor.substring(1);
103: break;
104:
105: case 'B':
106: case 'C':
107: case 'D':
108: case 'F':
109: case 'I':
110: case 'J':
111: case 'S':
112: case 'Z':
113: case 'V':
114: namesVec.addElement(type
115: + descriptor.substring(0, 1));
116: descriptor = descriptor.substring(1);
117: type = "";
118: break;
119:
120: case ')':
121: descriptor = descriptor.substring(1);
122: break;
123:
124: case 'L': {
125: int pos = descriptor.indexOf(';') + 1;
126: namesVec.addElement(type
127: + descriptor.substring(0, pos));
128: descriptor = descriptor.substring(pos);
129: type = "";
130: }
131: break;
132:
133: default:
134: throw new IllegalStateException(
135: "Illegal field or method descriptor: "
136: + descriptor);
137: }
138: }
139: names = new String[namesVec.size()];
140: for (int i = 0; i < names.length; i++) {
141: names[i] = (String) namesVec.elementAt(i);
142: }
143: }
144:
145: // Translate the names from JVM to Class.forName() format.
146: String[] translatedNames = new String[names.length];
147: for (int i = 0; i < names.length; i++) {
148: translatedNames[i] = translateType(names[i], isDisplay);
149: }
150: return translatedNames;
151: }
152:
153: /** Translates a type specifier from the internal JVM convention to the
154: * Class.forName() one.
155: * @param inName the type specifier to translate
156: * @param isDisplay true if the pretty display form for array types should be
157: * returned; false if slashes in array type names should be replaced by the
158: * dot charactoer
159: * @return translated type
160: * @throws IllegalStateException if an error occurs
161: */
162: public static String translateType(String inName, boolean isDisplay)
163: throws IllegalStateException {
164: String outName = null;
165: switch (inName.charAt(0)) {
166: case '[':
167: // For array types, Class.forName() inconsistently uses the internal
168: // type name but with '/' --> '.'
169: if (!isDisplay) {
170: // return the Class.forName() form
171: outName = translate(inName);
172: } else {
173: // return the pretty display form
174: outName = translateType(inName.substring(1), true)
175: + "[]";
176: }
177: break;
178:
179: case 'B':
180: outName = Byte.TYPE.getName();
181: break;
182:
183: case 'C':
184: outName = Character.TYPE.getName();
185: break;
186:
187: case 'D':
188: outName = Double.TYPE.getName();
189: break;
190:
191: case 'F':
192: outName = Float.TYPE.getName();
193: break;
194:
195: case 'I':
196: outName = Integer.TYPE.getName();
197: break;
198:
199: case 'J':
200: outName = Long.TYPE.getName();
201: break;
202:
203: case 'S':
204: outName = Short.TYPE.getName();
205: break;
206:
207: case 'Z':
208: outName = Boolean.TYPE.getName();
209: break;
210:
211: case 'V':
212: outName = Void.TYPE.getName();
213: break;
214:
215: case 'L': {
216: int pos = inName.indexOf(';');
217: outName = translate(inName
218: .substring(1, inName.indexOf(';')));
219: }
220: break;
221:
222: default:
223: throw new IllegalStateException("Illegal type: " + inName);
224: }
225: return outName;
226: }
227:
228: /** Translate a class name from the internal '/' convention to the regular
229: * '.' one.
230: * @param name the class name to translate
231: * @return translated class name
232: */
233: public static String translate(String name) {
234: return name.replace('/', '.');
235: }
236: }
|