1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2013 Eric Lafortune (eric (at) graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.obfuscate; 22 23 import java.io.*; 24 import java.util.*; 25 26 /** 27 * This <code>NameFactory</code> generates names that are read from a 28 * specified input file. 29 * Comments (everything starting with '#' on a single line) are ignored. 30 * 31 * @author Eric Lafortune 32 */ 33 public class DictionaryNameFactory implements NameFactory 34 { 35 private static final char COMMENT_CHARACTER = '#'; 36 37 38 private final List names; 39 private final NameFactory nameFactory; 40 41 private int index = 0; 42 43 44 /** 45 * Creates a new <code>DictionaryNameFactory</code>. 46 * @param file the file from which the names can be read. 47 * @param nameFactory the name factory from which names will be retrieved 48 * if the list of read names has been exhausted. 49 */ 50 public DictionaryNameFactory(File file, 51 NameFactory nameFactory) throws IOException 52 { 53 this.names = new ArrayList(); 54 this.nameFactory = nameFactory; 55 56 Reader reader = new FileReader(file); 57 58 try 59 { 60 StringBuffer buffer = new StringBuffer(); 61 62 while (true) 63 { 64 // Read the next character. 65 int c = reader.read(); 66 67 // Is it a valid identifier character? 68 if (c != -1 && 69 (buffer.length() == 0 ? 70 Character.isJavaIdentifierStart((char)c) : 71 Character.isJavaIdentifierPart((char)c))) 72 { 73 // Append it to the current identifier. 74 buffer.append((char)c); 75 } 76 else 77 { 78 // Did we collect a new identifier? 79 if (buffer.length() > 0) 80 { 81 // Add the completed name to the list of names, if it's 82 // not in it yet. 83 String name = buffer.toString(); 84 if (!names.contains(name)) 85 { 86 names.add(name); 87 } 88 89 // Clear the buffer. 90 buffer.setLength(0); 91 } 92 93 // Is this the beginning of a comment line? 94 if (c == COMMENT_CHARACTER) 95 { 96 // Skip all characters till the end of the line. 97 do 98 { 99 c = reader.read(); 100 } 101 while (c != -1 && 102 c != '\n' && 103 c != '\r'); 104 } 105 106 // Is this the end of the file? 107 if (c == -1) 108 { 109 // Just return. 110 return; 111 } 112 } 113 } 114 } 115 finally 116 { 117 reader.close(); 118 } 119 } 120 121 122 /** 123 * Creates a new <code>DictionaryNameFactory</code>. 124 * @param dictionaryNameFactory the dictionary name factory whose dictionary 125 * will be used. 126 * @param nameFactory the name factory from which names will be 127 * retrieved if the list of read names has been 128 * exhausted. 129 */ 130 public DictionaryNameFactory(DictionaryNameFactory dictionaryNameFactory, 131 NameFactory nameFactory) 132 { 133 this.names = dictionaryNameFactory.names; 134 this.nameFactory = nameFactory; 135 } 136 137 138 // Implementations for NameFactory. 139 140 public void reset() 141 { 142 index = 0; 143 144 nameFactory.reset(); 145 } 146 147 148 public String nextName() 149 { 150 String name; 151 152 // Do we still have names? 153 if (index < names.size()) 154 { 155 // Return the next name. 156 name = (String)names.get(index++); 157 } 158 else 159 { 160 // Return the next different name from the other name factory. 161 do 162 { 163 name = nameFactory.nextName(); 164 } 165 while (names.contains(name)); 166 } 167 168 return name; 169 } 170 171 172 public static void main(String[] args) 173 { 174 try 175 { 176 DictionaryNameFactory factory = 177 new DictionaryNameFactory(new File(args[0]), new SimpleNameFactory()); 178 179 for (int counter = 0; counter < 50; counter++) 180 { 181 System.out.println("["+factory.nextName()+"]"); 182 } 183 } 184 catch (IOException ex) 185 { 186 ex.printStackTrace(); 187 } 188 } 189 } 190