001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software 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
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v1.jvm;
024:
025: public final class InternalNameUtils {
026: public static String dottifySlashesAndDollarSigns(String str) {
027: return _dottifySlashesAndDollarSigns(str).toString();
028: }
029:
030: public static String decodeType(String internalrep)
031: throws TypeFormatException {
032: return _decodeType(internalrep).toString();
033: }
034:
035: public static String decodeTypeList(String internalrep)
036: throws TypeFormatException {
037: StringBuffer sb = new StringBuffer(64);
038: _decodeTypeList(internalrep, 0, sb);
039: return sb.toString();
040: }
041:
042: public static boolean isPrimitive(char rep) {
043: return (rep == 'Z' || rep == 'B' || rep == 'C' || rep == 'S'
044: || rep == 'I' || rep == 'J' || rep == 'F' || rep == 'D' || rep == 'V');
045: }
046:
047: private static void _decodeTypeList(String typeList, int start_pos,
048: StringBuffer appendTo) throws TypeFormatException {
049: if (appendTo.length() != 0)
050: appendTo.append(' ');
051:
052: char c = typeList.charAt(start_pos);
053: if (isPrimitive(c)) {
054: appendTo.append(_decodeType(typeList.substring(start_pos,
055: start_pos + 1)));
056: ++start_pos;
057: } else {
058: int stop_index;
059:
060: if (c == '[') {
061: int finger = start_pos + 1;
062: while (typeList.charAt(finger) == '[')
063: ++finger;
064: if (typeList.charAt(finger) == 'L') {
065: ++finger;
066: while (typeList.charAt(finger) != ';')
067: ++finger;
068: }
069: stop_index = finger;
070: } else {
071: stop_index = typeList.indexOf(';', start_pos);
072: if (stop_index < 0)
073: throw new TypeFormatException(
074: typeList.substring(start_pos)
075: + " is neither a primitive nor semicolon terminated!");
076: }
077:
078: appendTo.append(_decodeType(typeList.substring(start_pos,
079: (start_pos = stop_index + 1))));
080: }
081: if (start_pos < typeList.length()) {
082: appendTo.append(',');
083: _decodeTypeList(typeList, start_pos, appendTo);
084: }
085: }
086:
087: private static StringBuffer _decodeType(String type)
088: throws TypeFormatException {
089: // System.err.println("_decodeType: " + type);
090:
091: int array_level = 0;
092: StringBuffer out;
093:
094: char c = type.charAt(0);
095:
096: switch (c) {
097: case 'Z':
098: out = new StringBuffer("boolean");
099: break;
100: case 'B':
101: out = new StringBuffer("byte");
102: break;
103: case 'C':
104: out = new StringBuffer("char");
105: break;
106: case 'S':
107: out = new StringBuffer("short");
108: break;
109: case 'I':
110: out = new StringBuffer("int");
111: break;
112: case 'J':
113: out = new StringBuffer("long");
114: break;
115: case 'F':
116: out = new StringBuffer("float");
117: break;
118: case 'D':
119: out = new StringBuffer("double");
120: break;
121: case 'V':
122: out = new StringBuffer("void");
123: break;
124: case '[':
125: ++array_level;
126: out = _decodeType(type.substring(1));
127: break;
128: case 'L':
129: out = _decodeSimpleClassType(type);
130: break;
131: default:
132: throw new TypeFormatException(type
133: + " is not a valid inernal type name.");
134: }
135: for (int i = 0; i < array_level; ++i)
136: out.append("[]");
137: return out;
138: }
139:
140: private static StringBuffer _decodeSimpleClassType(String type)
141: throws TypeFormatException {
142: int len = type.length();
143: if (type.charAt(0) != 'L' || type.charAt(len - 1) != ';')
144: throw new TypeFormatException(
145: type
146: + " is not a valid representation of a simple class type.");
147:
148: return _dottifySlashesAndDollarSigns(type.substring(1, len - 1));
149: }
150:
151: private static StringBuffer _dottifySlashesAndDollarSigns(String s) {
152: StringBuffer sb = new StringBuffer(s);
153: for (int i = 0, len = sb.length(); i < len; ++i) {
154: char c = sb.charAt(i);
155: if (c == '/' || c == '$')
156: sb.setCharAt(i, '.');
157: }
158: return sb;
159: }
160:
161: private InternalNameUtils() {
162: }
163:
164: public static void main(String[] argv) {
165: try {
166: //System.out.println( decodeType( (new String[0]).getClass().getName() ) );
167: System.out.println(decodeTypeList(argv[0]));
168: } catch (Exception e) {
169: e.printStackTrace();
170: }
171: }
172:
173: // public static String dottifySlashes(String name)
174: // {
175: // StringBuffer sb = new StringBuffer(name);
176:
177: // int pos = name.indexOf('/', 0);
178: // while (pos > 0)
179: // {
180: // sb.setCharAt(pos, '.');
181: // ps = name.indexOf('/', ++pos);
182: // }
183: // return sb.toString();
184: // }
185:
186: }
|