001    package sysModel.classFile;
002    
003    /**
004     * Tools for dealing with class files.
005     *
006     * @author Mathias Ricken
007     */
008    public class ClassFileTools {
009    
010    
011        /**
012         * Return a string that represents the access flags set.
013         *
014         * @param flags access flags
015         *
016         * @return string with access flags as words
017         */
018        public static String getAccessString(short flags) {
019            StringBuffer x = new StringBuffer();
020    
021            if (0 != (flags & ClassFile.ACC_PUBLIC)) {
022                x.append("public ");
023            }
024    
025            if (0 != (flags & ClassFile.ACC_PRIVATE)) {
026                x.append("private ");
027            }
028    
029            if (0 != (flags & ClassFile.ACC_PROTECTED)) {
030                x.append("protected ");
031            }
032    
033            if (0 != (flags & ClassFile.ACC_STATIC)) {
034                x.append("static ");
035            }
036    
037            if (0 != (flags & ClassFile.ACC_FINAL)) {
038                x.append("final ");
039            }
040    
041            if (0 != (flags & ClassFile.ACC_SYNCHRONIZED)) {
042                x.append("synchronized ");
043            }
044    
045            if (0 != (flags & ClassFile.ACC_VOLATILE)) {
046                x.append("volatile ");
047            }
048    
049            if (0 != (flags & ClassFile.ACC_TRANSIENT)) {
050                x.append("transient ");
051            }
052    
053            if (0 != (flags & ClassFile.ACC_NATIVE)) {
054                x.append("native ");
055            }
056    
057            if (0 != (flags & ClassFile.ACC_INTERFACE)) {
058                x.append("interface ");
059            }
060    
061            if (0 != (flags & ClassFile.ACC_ABSTRACT)) {
062                x.append("abstract ");
063            }
064    
065            if (0 != (flags & ClassFile.ACC_STRICT)) {
066                x.append("strictfp ");
067            }
068    
069            // TODO: Handle ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_BRIDGE, and ACC_VARARGS here?
070    
071            return x.toString();
072        }
073    
074        /**
075         * Translate a type descriptor descriptor and a variable name into a Java declaration.
076         *
077         * @param typeString type descriptor descriptor
078         * @param varName    variable name
079         *
080         * @return declaration
081         */
082        public static String getTypeString(String typeString, String varName) {
083            int isArray = 0;
084            int ndx = 0;
085            StringBuffer x = new StringBuffer();
086    
087            while('[' == typeString.charAt(ndx)) {
088                ++isArray;
089                ++ndx;
090            }
091    
092            switch(typeString.charAt(ndx)) {
093                case 'B':
094                    x.append("byte");
095                    break;
096                case 'C':
097                    x.append("char");
098                    break;
099                case 'D':
100                    x.append("double");
101                    break;
102                case 'F':
103                    x.append("float");
104                    break;
105                case 'I':
106                    x.append("int");
107                    break;
108                case 'J':
109                    x.append("long");
110                    break;
111                case 'L':
112                    for(int i = ndx + 1; i < typeString.indexOf((int)';'); ++i) {
113                        if ('/' != typeString.charAt(i)) {
114                            x.append(typeString.charAt(i));
115                        }
116                        else {
117                            x.append('.');
118                        }
119                    }
120                    break;
121                case 'V':
122                    x.append("void");
123                    break;
124                case 'S':
125                    x.append("short");
126                    break;
127                case 'Z':
128                    x.append("boolean");
129                    break;
130            }
131            while(0 < isArray) {
132                x.append("[]");
133                isArray--;
134            }
135            x.append(' ');
136            x.append(varName);
137            return x.toString();
138        }
139    
140        /**
141         * Return true if this is a primitive type or an array of primitive types.
142         *
143         * @param typeString type descriptor descriptor
144         *
145         * @return true if primitive type or array of primitive types
146         */
147        public static boolean isPrimitive(String typeString) {
148            int ndx = 0;
149    
150            while('[' == typeString.charAt(ndx)) {
151                ++ndx;
152            }
153    
154            switch(typeString.charAt(ndx)) {
155                case 'B':
156                case 'C':
157                case 'D':
158                case 'F':
159                case 'I':
160                case 'J':
161                case 'V':
162                case 'S':
163                case 'Z':
164                    return true;
165                default:
166                    return false;
167            }
168        }
169    
170        /**
171         * Return the next descriptor from a string of concatenated signatures. For example, if the descriptor was "[BII",
172         * this method would return "II".
173         *
174         * @param sig concatenated signatures
175         *
176         * @return next descriptor
177         */
178        public static String getNextSignature(String sig) {
179            int ndx = 0;
180            String x;
181    
182            while('[' == sig.charAt(ndx)) {
183                ++ndx;
184            }
185    
186            if ('L' == sig.charAt(ndx)) {
187                while(';' != sig.charAt(ndx)) {
188                    ++ndx;
189                }
190            }
191            ++ndx;
192            x = (sig.substring(ndx));
193            return (x);
194        }
195    
196        /**
197         * Return class name in Java form.
198         *
199         * @param s mangled class name
200         *
201         * @return Java class name
202         */
203        public static String getClassName(String s) {
204            if ('[' == s.charAt(0)) {
205                return getTypeString(s, "");
206            }
207    
208            return s.replace('/','.');
209        }
210    }