001: /**
002: * YGuard -- an obfuscation library for Java(TM) classfiles.
003: *
004: * Copyright (c) 2002 yWorks GmbH (yguard@yworks.com)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * The author may be contacted at yguard@yworks.com
021: *
022: * Java and all Java-based marks are trademarks or registered
023: * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
024: */package com.yworks.yguard;
025:
026: import com.yworks.yguard.obf.ClassTree;
027: import java.util.StringTokenizer;
028:
029: /**
030: *
031: * @author muellese
032: */
033: public class Conversion {
034:
035: /** Creates a new instance of Conversion */
036: protected Conversion() {
037: }
038:
039: public static String toJavaClass(String className) {
040: if (className.endsWith(".class")) {
041: className = className.substring(0, className.length() - 6);
042: }
043: return className.replace('/', '.');
044: }
045:
046: public static String toJavaType(String type) {
047: StringBuffer nat = new StringBuffer(30);
048: int arraydim = 0;
049: while (type.charAt(arraydim) == '[')
050: arraydim++;
051: type = type.substring(arraydim);
052: switch (type.charAt(0)) {
053: default:
054: throw new IllegalArgumentException("unknown native type:"
055: + type);
056: case 'B':
057: nat.append("byte");
058: break;
059: case 'C':
060: nat.append("char");
061: break;
062: case 'D':
063: nat.append("double");
064: break;
065: case 'F':
066: nat.append("float");
067: break;
068: case 'I':
069: nat.append("int");
070: break;
071: case 'J':
072: nat.append("long");
073: break;
074: case 'S':
075: nat.append("short");
076: break;
077: case 'Z':
078: nat.append("boolean");
079: break;
080: case 'V':
081: nat.append("void");
082: break;
083: case 'L':
084: String className = type.substring(1, type.length() - 1);
085: if (className.indexOf('<') >= 0) {
086: String parameters = type.substring(className
087: .indexOf('<') + 2,
088: className.lastIndexOf('>') - 1);
089: className = className.substring(0, className
090: .indexOf('<'));
091: nat.append(className.replace('/', '.'));
092: nat.append('<');
093: nat.append(toJavaParameters(parameters));
094: nat.append('>');
095: } else {
096: nat.append(className.replace('/', '.'));
097: }
098: break;
099: }
100: for (int i = 0; i < arraydim; i++) {
101: nat.append("[]");
102: }
103: return nat.toString();
104: }
105:
106: /** Mapping for signatures (used for generics in 1.5).
107: * @see com.yworks.yguard.obf.classfile.NameMapper#mapSignature */
108: public static String mapSignature(String signature) {
109: return new ClassTree().mapSignature(signature);
110: }
111:
112: public static String toJavaParameters(String parameters) {
113: StringBuffer nat = new StringBuffer(30);
114: switch (parameters.charAt(0)) {
115: default:
116: throw new IllegalArgumentException("unknown native type:"
117: + parameters.charAt(0));
118: case '+':
119: nat.append("? extends ").append(
120: toJavaParameters(parameters.substring(1)));
121: break;
122: case '-':
123: nat.append("? super ").append(
124: toJavaParameters(parameters.substring(1)));
125: break;
126: case '*':
127: nat.append("*");
128: if (parameters.length() > 1) {
129: nat.append(", ").append(
130: toJavaParameters(parameters.substring(1)));
131: }
132: break;
133: case 'B':
134: nat.append("byte");
135: break;
136: case 'C':
137: nat.append("char");
138: break;
139: case 'D':
140: nat.append("double");
141: break;
142: case 'F':
143: nat.append("float");
144: break;
145: case 'I':
146: nat.append("int");
147: break;
148: case 'J':
149: nat.append("long");
150: break;
151: case 'S':
152: nat.append("short");
153: break;
154: case 'Z':
155: nat.append("boolean");
156: break;
157: case 'V':
158: nat.append("void");
159: break;
160: case 'L':
161: int len = parameters.indexOf('<');
162: if (len >= 0) {
163: len = Math.min(len, parameters.indexOf(';'));
164: }
165: break;
166: case 'T':
167: int index = parameters.indexOf(';');
168: nat.append(parameters.substring(1, index));
169: if (parameters.length() > index) {
170: nat.append(", ");
171: nat.append(parameters.substring(index));
172: }
173: break;
174: }
175: return nat.toString();
176: }
177:
178: public static String toJavaMethod(String name, String signature) {
179: String argsonly = signature
180: .substring(signature.indexOf('(') + 1);
181: String ret = signature.substring(signature.indexOf(')') + 1);
182: ret = toJavaType(ret);
183: StringBuffer args = new StringBuffer();
184: args.append('(');
185: if (argsonly.indexOf(')') > 0) {
186: argsonly = argsonly.substring(0, argsonly.indexOf(')'));
187: toJavaArguments(argsonly, args);
188: }
189: args.append(')');
190: return ret + " " + name + args.toString();
191: }
192:
193: public static String toJavaArguments(String args) {
194: StringBuffer b = new StringBuffer(args.length() + 32);
195: toJavaArguments(args, b);
196: return b.toString();
197: }
198:
199: private static void toJavaArguments(String argsonly,
200: StringBuffer args) {
201: int argcount = 0;
202: int pos = 0;
203: StringBuffer arg = new StringBuffer(20);
204: while (pos < argsonly.length()) {
205: while (argsonly.charAt(pos) == '[') {
206: arg.append('[');
207: pos++;
208: }
209: if (argsonly.charAt(pos) == 'L') {
210: while (argsonly.charAt(pos) != ';') {
211: arg.append(argsonly.charAt(pos));
212: pos++;
213: }
214: arg.append(';');
215: if (argcount > 0) {
216: args.append(',');
217: args.append(' ');
218: }
219: args.append(toJavaType(arg.toString()));
220: argcount++;
221: arg.setLength(0);
222: pos++;
223: } else {
224: arg.append(argsonly.charAt(pos));
225: if (argcount > 0) {
226: args.append(',');
227: args.append(' ');
228: }
229: args.append(toJavaType(arg.toString()));
230: argcount++;
231: arg.setLength(0);
232: pos++;
233: }
234: }
235: }
236: }
|