Source Code Cross Referenced for ScriptFile.java in  » Development » javaguard » net » sf » javaguard » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » javaguard » net.sf.javaguard 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * JavaGuard -- an obfuscation package for Java classfiles.
003:         *
004:         * Copyright (c) 2002 Thorsten Heit (theit@gmx.de)
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 theit@gmx.de.
021:         *
022:         *
023:         * $Id: ScriptFile.java,v 1.5 2002/05/11 18:55:54 glurk Exp $
024:         */package net.sf.javaguard;
025:
026:        import java.io.*;
027:        import java.util.*;
028:
029:        /** Parser for a JavaGuard script file.
030:         *
031:         * @author <a href="mailto:theit@gmx.de">Thorsten Heit</a>
032:         */
033:        public class ScriptFile implements  ScriptConstants {
034:            /** Holds all parsed entries from the script file. */
035:            private Vector entries;
036:
037:            /** Holds the script file name. */
038:            private String name;
039:
040:            /** Constructor that reads and parses the given script file.
041:             * @param aScript file object for a valid JavaGuard script
042:             * @throws IOException if an error occurs during reading
043:             */
044:            public ScriptFile(File aScript) throws IOException {
045:                entries = new Vector();
046:                setName(aScript.getName());
047:
048:                InputStream is = null;
049:                try {
050:                    is = new FileInputStream(aScript);
051:                    StreamTokenizer tk = new StreamTokenizer(
052:                            new BufferedReader(new InputStreamReader(is)));
053:                    // use our own syntax schema
054:                    tk.resetSyntax();
055:                    tk.eolIsSignificant(true);
056:                    // everything below ' ' should be treated as a whitespace character...
057:                    tk.whitespaceChars(0x00, 0x20);
058:                    // ...and everything else as a word character
059:                    tk.wordChars('!', '~');
060:                    // enable C/C++-style and shell script-like comments:
061:                    tk.slashSlashComments(true);
062:                    tk.slashStarComments(true);
063:                    tk.commentChar('#');
064:                    readEntries(tk);
065:                } finally {
066:                    if (null != is) {
067:                        is.close();
068:                    }
069:                }
070:            }
071:
072:            /** Reads all script file entries from the given input stream.
073:             * @param tk the input stream for the script file
074:             * @throws IOException if an error occurs during reading
075:             */
076:            private void readEntries(StreamTokenizer tk) throws IOException {
077:                ScriptEntry scriptEntry;
078:                try {
079:                    while (null != (scriptEntry = readNextEntry(tk))) {
080:                        entries.add(scriptEntry);
081:                    }
082:                } catch (IOException ex) {
083:                    IOException ioex = new IOException("Parse error at line "
084:                            + tk.lineno() + ": " + ex.getMessage() + ".");
085:                    ioex.fillInStackTrace();
086:                    throw ioex;
087:                } catch (IllegalArgumentException iaex) {
088:                    IOException ioex = new IOException("Parse error at line "
089:                            + tk.lineno() + ": " + iaex.getMessage() + ".");
090:                    ioex.fillInStackTrace();
091:                    throw ioex;
092:                }
093:            }
094:
095:            /** Read the next entry in the script file.
096:             * @param tk the valid input stream for the script file
097:             * @return next entry in the script file; null if nothing more is available
098:             * @throws IOException if an error occurs during reading
099:             * @throws IllegalArgumentException if an error occurs during parsing
100:             */
101:            private ScriptEntry readNextEntry(StreamTokenizer tk)
102:                    throws IOException, IllegalArgumentException {
103:                // Reset the 'next error' state
104:                ScriptEntry entry = null;
105:
106:                // read the next token in the stream
107:                readNextToken(tk);
108:                if (tk.ttype == StreamTokenizer.TT_EOF)
109:                    return null;
110:
111:                // parse and validate the actual token (which must be a script file directive)
112:                int type = parseDirective(tk);
113:                if (type < 0) {
114:                    throw new IllegalArgumentException(
115:                            "Unknown script file directive");
116:                }
117:
118:                // each script directive requires at least one additional word following it
119:                readNextTokenInLine(tk);
120:                entry = new ScriptEntry(type, tk.sval);
121:
122:                // depending on the script directive read additional parameters
123:                switch (type) {
124:                case TYPE_ATTRIBUTE:
125:                    if (!Tools.isInArrayIgnoreCase(entry.getName(), validAttrs)) {
126:                        throw new IllegalArgumentException(
127:                                "Unknown attribute option specified");
128:                    }
129:                    // optionally read an additional info string for the attribute
130:                    if (conditionalReadNextTokenInLine(tk)) {
131:                        entry.setInfo(tk.sval);
132:                    }
133:                    break;
134:
135:                case TYPE_RENAME:
136:                    if (!Tools
137:                            .isInArrayIgnoreCase(entry.getName(), renameAttrs)) {
138:                        throw new IllegalArgumentException(
139:                                "Unknown rename option specified");
140:                    }
141:                    // optionally read an additional info string for the attribute
142:                    if (conditionalReadNextTokenInLine(tk)) {
143:                        entry.setInfo(tk.sval);
144:                    }
145:                    break;
146:
147:                case TYPE_PRESERVE:
148:                    if (!Tools.isInArrayIgnoreCase(entry.getName(),
149:                            preserveAttrs)) {
150:                        throw new IllegalArgumentException(
151:                                "Unknown preserve option specified");
152:                    }
153:                    if (conditionalReadNextTokenInLine(tk)) {
154:                        entry.setInfo(tk.sval);
155:                    }
156:                    break;
157:
158:                case TYPE_PACKAGE:
159:                    // read additional options, the same as for a ".class" directive
160:                    readClassOptions(tk, entry);
161:                    break;
162:
163:                case TYPE_PACKAGE_MAP:
164:                    // read the mapping name for a ".package_map" directive
165:                    readNextTokenInLine(tk);
166:                    checkJavaIdentifier(tk.sval);
167:                    entry.setMappedName(tk.sval);
168:                    // read additional options, the same as for a ".class" directive
169:                    readClassOptions(tk, entry);
170:                    break;
171:
172:                case TYPE_CLASS:
173:                    // read additional options for a ".class" directive
174:                    readClassOptions(tk, entry);
175:                    break;
176:
177:                case TYPE_CLASS_MAP:
178:                    // read the mapping name and additional options a ".class_map" directive
179:                    readNextTokenInLine(tk);
180:                    checkJavaInnerIdentifier(tk.sval);
181:                    entry.setMappedName(tk.sval);
182:                    readClassOptions(tk, entry);
183:                    break;
184:
185:                case TYPE_METHOD:
186:                    // optionally read the descriptor for the ".method" directive
187:                    if (conditionalReadNextTokenInLine(tk)) {
188:                        checkMethodDescriptor(tk.sval);
189:                        entry.setDescriptor(tk.sval);
190:                    }
191:                    break;
192:
193:                case TYPE_METHOD_MAP:
194:                    // read the descriptor for the ".method_map" directive...
195:                    readNextTokenInLine(tk);
196:                    checkMethodDescriptor(tk.sval);
197:                    entry.setDescriptor(tk.sval);
198:                    // ...and read the mapping name
199:                    readNextTokenInLine(tk);
200:                    checkJavaIdentifier(tk.sval);
201:                    entry.setMappedName(tk.sval);
202:                    break;
203:
204:                case TYPE_FIELD:
205:                    // optionally read the descriptor for the ".field" directive
206:                    if (conditionalReadNextTokenInLine(tk)) {
207:                        checkJavaType(tk.sval);
208:                        entry.setDescriptor(tk.sval);
209:                    }
210:                    break;
211:
212:                case TYPE_FIELD_MAP: {
213:                    // If there are two more tokens in the current line available the first
214:                    // one specifies the descriptor and the second the mapped name;
215:                    // otherwise the token specifies the mapped name
216:                    readNextTokenInLine(tk);
217:                    String tmp = tk.sval;
218:                    if (conditionalReadNextTokenInLine(tk)) {
219:                        // two tokens available -> first = descriptor, second = mapped name
220:                        checkJavaType(tmp);
221:                        entry.setDescriptor(tmp);
222:                        entry.setMappedName(tk.sval);
223:                    } else {
224:                        entry.setMappedName(tmp);
225:                    }
226:                    checkJavaIdentifier(entry.getMappedName());
227:                    break;
228:                }
229:
230:                case TYPE_IGNORE_METHOD:
231:                    // try to read an optional method descriptor
232:                    if (conditionalReadNextTokenInLine(tk)) {
233:                        checkMethodDescriptor(tk.sval);
234:                        entry.setDescriptor(tk.sval);
235:                    }
236:                    break;
237:
238:                case TYPE_IGNORE_FIELD:
239:                    // try to read an optional field descriptor
240:                    if (conditionalReadNextTokenInLine(tk)) {
241:                        checkJavaType(tk.sval);
242:                        entry.setDescriptor(tk.sval);
243:                    }
244:                    break;
245:
246:                case TYPE_OBFUSCATE_METHOD:
247:                    // try to read an optional method descriptor
248:                    if (conditionalReadNextTokenInLine(tk)) {
249:                        checkMethodDescriptor(tk.sval);
250:                        entry.setDescriptor(tk.sval);
251:                    }
252:                    break;
253:
254:                case TYPE_OBFUSCATE_FIELD:
255:                    // try to read an optional field descriptor
256:                    if (conditionalReadNextTokenInLine(tk)) {
257:                        checkJavaType(tk.sval);
258:                        entry.setDescriptor(tk.sval);
259:                    }
260:                    break;
261:                }
262:
263:                return entry;
264:            }
265:
266:            /** Reads the next word token from the given input stream.
267:             * @param tk the valid input stream
268:             * @throws IOException if an error occurs during reading
269:             */
270:            private void readNextToken(StreamTokenizer tk) throws IOException {
271:                int token = StreamTokenizer.TT_EOL;
272:
273:                // read the next word token
274:                while (token == StreamTokenizer.TT_EOL) {
275:                    token = tk.nextToken();
276:                }
277:            }
278:
279:            /** Reads the next word token in the current line in the given input stream.
280:             * @param tk the valid input stream
281:             * @throws IOException if an error occurs during reading
282:             */
283:            private void readNextTokenInLine(StreamTokenizer tk)
284:                    throws IOException {
285:                int token = StreamTokenizer.TT_NUMBER;
286:
287:                // read the next token
288:                while (token == StreamTokenizer.TT_NUMBER) {
289:                    token = tk.nextToken();
290:                }
291:                if (token != StreamTokenizer.TT_WORD) {
292:                    throw new IOException("Unexpected end of file at line "
293:                            + tk.lineno() + " of script file.");
294:                }
295:            }
296:
297:            /** Tries to read the next available word in the current line in the input
298:             * stream.
299:             * @return true if the current line contains one more word; false else
300:             * @param tk the input stream
301:             * @throws IOException if an error occurs during reading
302:             */
303:            private boolean conditionalReadNextTokenInLine(StreamTokenizer tk)
304:                    throws IOException {
305:                int token = StreamTokenizer.TT_NUMBER;
306:
307:                // read the next token
308:                while (token == StreamTokenizer.TT_NUMBER) {
309:                    token = tk.nextToken();
310:                }
311:                // if the next token is not a word push it back to the input stream
312:                if (token != StreamTokenizer.TT_WORD) {
313:                    tk.pushBack();
314:                    return false;
315:                }
316:                return true;
317:            }
318:
319:            /** Read and parse optional parameters that can be specified in <code>.class</code>
320:             * or <code>.class_map</code> directives.
321:             * @param tk the valid input stream
322:             * @param entry the current script file entry
323:             * @throws IOException if an error occurs during reading
324:             * @throws IllegalArgumentException if an illegal or an invalid class option
325:             * is found
326:             */
327:            private void readClassOptions(StreamTokenizer tk, ScriptEntry entry)
328:                    throws IOException, IllegalArgumentException {
329:                while (conditionalReadNextTokenInLine(tk)) {
330:                    int subtype;
331:                    switch (subtype = parseToken(tk.sval, options, optionTypes)) {
332:                    case OPTION_TYPE_PUBLIC:
333:                        entry.setRetainPublic(true);
334:                        break;
335:
336:                    case OPTION_TYPE_PROTECTED:
337:                        entry.setRetainProtected(true);
338:                        break;
339:
340:                    case OPTION_TYPE_METHOD:
341:                        entry.setRetainMethods(true);
342:                        break;
343:
344:                    case OPTION_TYPE_FIELD:
345:                        entry.setRetainFields(true);
346:                        break;
347:
348:                    default:
349:                        throw new IllegalArgumentException(
350:                                "Unknown class option");
351:                    }
352:                }
353:                // check whether the "field" or "method" option are specified together
354:                // with the "public" or "protected" option
355:                if ((entry.canRetainFields() || entry.canRetainMethods())
356:                        && !entry.canRetainPublic()
357:                        && !entry.canRetainProtected()) {
358:                    throw new IllegalArgumentException(
359:                            "Missing option \"public\" or \"protected\"");
360:                }
361:                // check whether the "public" or "protected" keywords were given
362:                // without any "field" or "method" modifier
363:                if ((entry.canRetainPublic() || entry.canRetainProtected())
364:                        && !entry.canRetainFields()
365:                        && !entry.canRetainMethods()) {
366:                    // no "method" and "field" modifier are specified
367:                    // -> all public/protected elements should be retained
368:                    entry.setRetainFields(true);
369:                    entry.setRetainMethods(true);
370:                }
371:            }
372:
373:            /** Checks whether the current token is a valid script file directive.
374:             * @return the code of the directive if the token is a valid script file
375:             * directive; -1 else
376:             * @param tk the input stream
377:             */
378:            private int parseDirective(StreamTokenizer tk) {
379:                if (tk.ttype == StreamTokenizer.TT_WORD) {
380:                    return parseToken(tk.sval, directives, directiveTypes);
381:                }
382:                return -1;
383:            }
384:
385:            /** Checks whether a string exists in an array of strings. If yes return an
386:             * <code>int</code> value representing the string code.
387:             * @param str The string to check
388:             * @param list An array of strings; may not be null
389:             * @param codes An array of <code>int</code> values representing the string
390:             * codes. Must have the same size as the <code>list</code> parameter.
391:             * @return An <code>int</code> value from the <code>codes</code> array if
392:             * the string exists in the list; -1 else
393:             */
394:            private int parseToken(String str, String[] list, int[] codes) {
395:                for (int i = 0; i < list.length; i++) {
396:                    if (str.equalsIgnoreCase(list[i])) {
397:                        return codes[i];
398:                    }
399:                }
400:                return -1;
401:            }
402:
403:            /** Checks whether a given method descriptor is valid.
404:             * @param s the string to check
405:             * @throws IllegalArgumentException if the descriptor is invalid
406:             */
407:            private void checkMethodDescriptor(String s)
408:                    throws IllegalArgumentException {
409:                if (s.length() == 0 || s.charAt(0) != '(') {
410:                    throw new IllegalArgumentException(
411:                            "Empty or invalid method descriptor.");
412:                }
413:                s = s.substring(1);
414:
415:                // Check each type
416:                while (s.length() > 0 && s.charAt(0) != ')') {
417:                    s = checkFirstJavaType(s);
418:                }
419:                checkJavaType(s.substring(1));
420:            }
421:
422:            /** Checks whether the first Java type is valid.
423:             * @param s the string to check
424:             * @throws IllegalArgumentException if the first type is invalid.
425:             * @return all but first type in the string
426:             */
427:            private String checkFirstJavaType(String s)
428:                    throws IllegalArgumentException {
429:                // Pull off the array specifiers
430:                while (s.charAt(0) == '[') {
431:                    s = s.substring(1);
432:                    if (s.length() == 0) {
433:                        throw new IllegalArgumentException("Invalid Java type");
434:                    }
435:                }
436:
437:                // Check a type
438:                int pos = 0;
439:                switch (s.charAt(0)) {
440:                case 'B':
441:                case 'C':
442:                case 'D':
443:                case 'F':
444:                case 'I':
445:                case 'J':
446:                case 'S':
447:                case 'V':
448:                case 'Z':
449:                    break;
450:
451:                case 'L':
452:                    pos = s.indexOf(';');
453:                    if (pos == -1) {
454:                        throw new IllegalArgumentException(
455:                                "Invalid class or interface type specification");
456:                    }
457:                    // Check the class type
458:                    checkClassSpec(s.substring(0, pos));
459:                    break;
460:
461:                default:
462:                    throw new IllegalArgumentException("Unknown Java type");
463:                }
464:                return s.substring(pos + 1);
465:            }
466:
467:            /** Checks whether the Java type is valid.
468:             * @param s the string to check
469:             * @throws IllegalArgumentException if the string is invalid
470:             */
471:            private void checkJavaType(String s)
472:                    throws IllegalArgumentException {
473:                if (!checkFirstJavaType(s).equals("")) {
474:                    throw new IllegalArgumentException("Invalid Java type");
475:                }
476:            }
477:
478:            /** Checks whether the given string specifies a correct class specification.
479:             * @param s the string to check
480:             * @throws IllegalArgumentException if the string is invalid
481:             */
482:            private void checkClassSpec(String s)
483:                    throws IllegalArgumentException {
484:                if (s.length() == 0) {
485:                    throw new IllegalArgumentException(
486:                            "Class specification may not be empty");
487:                }
488:
489:                int pos = -1;
490:                // check all possible inner classes first
491:                while ((pos = s.lastIndexOf('$')) != -1) {
492:                    checkJavaInnerIdentifier(s.substring(pos + 1));
493:                    s = s.substring(0, pos);
494:                }
495:                // now check all class and package names
496:                while ((pos = s.lastIndexOf('/')) != -1) {
497:                    checkJavaIdentifier(s.substring(pos + 1));
498:                    s = s.substring(0, pos);
499:                }
500:                checkJavaIdentifier(s);
501:            }
502:
503:            /** Checks whether the given string is a valid Java identifier.
504:             * @param s the string to check
505:             * @throws IllegalArgumentException if the string is invalid
506:             */
507:            private void checkJavaIdentifier(String s)
508:                    throws IllegalArgumentException {
509:                if (s.length() == 0
510:                        || !Character.isJavaIdentifierStart(s.charAt(0))) {
511:                    throw new IllegalArgumentException(
512:                            "Identifier empty or invalid start character");
513:                }
514:                for (int i = 1; i < s.length(); i++) {
515:                    if (!Character.isJavaIdentifierPart(s.charAt(i))) {
516:                        throw new IllegalArgumentException(
517:                                "Invalid character inside the identifier");
518:                    }
519:                }
520:            }
521:
522:            /** Checks whether the given string is a valid Java identifier. Allows
523:             * anonymous inner class names like '4'.
524:             * @param s the string to check
525:             * @throws IllegalArgumentException if the string is invalid
526:             */
527:            private void checkJavaInnerIdentifier(String s)
528:                    throws IllegalArgumentException {
529:                if (s.length() == 0) {
530:                    throw new IllegalArgumentException(
531:                            "Identifier may not be empty");
532:                }
533:                for (int i = 0; i < s.length(); i++) {
534:                    if (!Character.isJavaIdentifierPart(s.charAt(i))) {
535:                        throw new IllegalArgumentException(
536:                                "Invalid character inside the identifier");
537:                    }
538:                }
539:            }
540:
541:            /** Returns an iterator over the elements in the script file in proper
542:             * sequence.
543:             * @return an iterator over the elements in this list in proper sequence.
544:             */
545:            public Iterator iterator() {
546:                return entries.iterator();
547:            }
548:
549:            /** Stores the script file name.
550:             * @param aName the script file name
551:             * @see #getName
552:             */
553:            public void setName(String aName) {
554:                this .name = aName;
555:            }
556:
557:            /** Returns the current script file name.
558:             * @return script file name
559:             * @see #setName
560:             */
561:            public String getName() {
562:                return name;
563:            }
564:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.