/* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package proguard.io; import proguard.classfile.*; import java.io.*; /** * This DataEntryReader writes the resource data entries that it reads to a * given DataEntryWriter, updating their contents based on the renamed classes * in the given ClassPool. * * @author Eric Lafortune */ public class DataEntryRewriter extends DataEntryCopier { private final ClassPool classPool; /** * Creates a new DataEntryRewriter. */ public DataEntryRewriter(ClassPool classPool, DataEntryWriter dataEntryWriter) { super(dataEntryWriter); this.classPool = classPool; } // Implementations for DataEntryCopier. protected void copyData(InputStream inputStream, OutputStream outputStream) throws IOException { Reader reader = new BufferedReader(new InputStreamReader(inputStream)); Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream)); copyData(reader, writer); writer.flush(); outputStream.flush(); } /** * Copies all data that it can read from the given reader to the given * writer. */ protected void copyData(Reader reader, Writer writer) throws IOException { StringBuffer word = new StringBuffer(); while (true) { int i = reader.read(); if (i < 0) { break; } // Is the character part of a word? char c = (char)i; if (Character.isJavaIdentifierPart(c) || c == '.' || c == '-') { // Collect the characters in this word. word.append(c); } else { // Write out the updated word, if any. writeUpdatedWord(writer, word.toString()); word.setLength(0); // Write out the character that terminated it. writer.write(c); } } // Write out the final word. writeUpdatedWord(writer, word.toString()); } // Small utility methods. /** * Writes the given word to the given writer, after having adapted it, * based on the renamed class names. */ private void writeUpdatedWord(Writer writer, String word) throws IOException { if (word.length() > 0) { String newWord = word; boolean containsDots = word.indexOf('.') >= 0; // Replace dots by forward slashes. String className = containsDots ? word.replace('.', ClassConstants.PACKAGE_SEPARATOR) : word; // Find the class corrsponding to the word. Clazz clazz = classPool.getClass(className); if (clazz != null) { // Update the word if necessary. String newClassName = clazz.getName(); if (!className.equals(newClassName)) { // Replace forward slashes by dots. newWord = containsDots ? newClassName.replace(ClassConstants.PACKAGE_SEPARATOR, '.') : newClassName; } } writer.write(newWord); } } }