001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.obfuscate;
022:
023: import java.io.*;
024: import java.util.*;
025:
026: /**
027: * This <code>NameFactory</code> generates names that are read from a
028: * specified input file.
029: * Comments (everything starting with '#' on a single line) are ignored.
030: *
031: * @author Eric Lafortune
032: */
033: public class DictionaryNameFactory implements NameFactory {
034: private static final char COMMENT_CHARACTER = '#';
035:
036: private final NameFactory nameFactory;
037: private final List names = new ArrayList();
038:
039: private int index = 0;
040:
041: /**
042: * Creates a new <code>DictionaryNameFactory</code>.
043: * @param file the file from which the names can be read.
044: * @param nameFactory the name factory from which names will be retrieved
045: * if the list of read names has been exhausted.
046: */
047: public DictionaryNameFactory(File file, NameFactory nameFactory)
048: throws IOException {
049: this .nameFactory = nameFactory;
050:
051: Reader reader = new FileReader(file);
052:
053: try {
054: StringBuffer buffer = new StringBuffer();
055:
056: while (true) {
057: // Read the next character.
058: int c = reader.read();
059:
060: // Is it a valid identifier character?
061: if (c != -1
062: && (buffer.length() == 0 ? Character
063: .isJavaIdentifierStart((char) c)
064: : Character
065: .isJavaIdentifierPart((char) c))) {
066: // Append it to the current identifier.
067: buffer.append((char) c);
068: } else {
069: // Did we collect a new identifier?
070: if (buffer.length() > 0) {
071: // Add the completed name to the list of names, if it's
072: // not in it yet.
073: String name = buffer.toString();
074: if (!names.contains(name)) {
075: names.add(name);
076: }
077:
078: // Clear the buffer.
079: buffer.setLength(0);
080: }
081:
082: // Is this the beginning of a comment line?
083: if (c == COMMENT_CHARACTER) {
084: // Skip all characters till the end of the line.
085: do {
086: c = reader.read();
087: } while (c != -1 && c != '\n' && c != '\r');
088: }
089:
090: // Is this the end of the file?
091: if (c == -1) {
092: // Just return.
093: return;
094: }
095: }
096: }
097: } finally {
098: reader.close();
099: }
100: }
101:
102: // Implementations for NameFactory.
103:
104: public void reset() {
105: index = 0;
106:
107: nameFactory.reset();
108: }
109:
110: public String nextName() {
111: String name;
112:
113: // Do we still have names?
114: if (index < names.size()) {
115: // Return the next name.
116: name = (String) names.get(index++);
117: } else {
118: // Return the next different name from the other name factory.
119: do {
120: name = nameFactory.nextName();
121: } while (names.contains(name));
122: }
123:
124: return name;
125: }
126:
127: public static void main(String[] args) {
128: try {
129: DictionaryNameFactory factory = new DictionaryNameFactory(
130: new File(args[0]), new SimpleNameFactory());
131:
132: for (int counter = 0; counter < 50; counter++) {
133: System.out.println("[" + factory.nextName() + "]");
134: }
135: } catch (IOException ex) {
136: ex.printStackTrace();
137: }
138: }
139: }
|