1b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang/* 2b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * of Java bytecode. 4b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) 6b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 7b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This program is free software; you can redistribute it and/or modify it 8b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * under the terms of the GNU General Public License as published by the Free 9b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Software Foundation; either version 2 of the License, or (at your option) 10b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * any later version. 11b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 12b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This program is distributed in the hope that it will be useful, but WITHOUT 13b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * more details. 16b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 17b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * You should have received a copy of the GNU General Public License along 18b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * with this program; if not, write to the Free Software Foundation, Inc., 19b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */ 21b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangpackage proguard.io; 22b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 23b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.*; 242270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.io.ProgramClassWriter; 252270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.util.SimplifiedVisitor; 262270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.visitor.ClassVisitor; 27b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 28b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport java.io.*; 29b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 30b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang/** 31b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This ClassVisitor writes out the ProgramClass objects that it visits to the 32b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * given DataEntry, modified to have the correct name. 33b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 34b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * @author Eric Lafortune 35b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */ 36b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangpublic class DataEntryClassWriter 37b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangextends SimplifiedVisitor 38b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimplements ClassVisitor 39b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang{ 40b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang private final DataEntryWriter dataEntryWriter; 41b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang private final DataEntry templateDataEntry; 42b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 43b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 44b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang /** 45b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Creates a new DataEntryClassWriter for writing to the given 46b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * DataEntryWriter, based on the given template DataEntry. 47b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */ 48b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang public DataEntryClassWriter(DataEntryWriter dataEntryWriter, 49b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang DataEntry templateDataEntry) 50b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 51b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang this.dataEntryWriter = dataEntryWriter; 52b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang this.templateDataEntry = templateDataEntry; 53b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 54b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 55b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 56b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Implementations for ClassVisitor. 57b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 58b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang public void visitProgramClass(ProgramClass programClass) 59b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 60b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Rename the data entry if necessary. 61b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang String actualClassName = programClass.getName(); 62b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang DataEntry actualDataEntry = 63b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang new RenamedDataEntry(templateDataEntry, 64b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang actualClassName + ClassConstants.CLASS_FILE_EXTENSION); 65b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 66b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang try 67b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 68b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Get the output entry corresponding to this input entry. 69b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang OutputStream outputStream = dataEntryWriter.getOutputStream(actualDataEntry); 70b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (outputStream != null) 71b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 72b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Write the class to the output entry. 73b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang DataOutputStream classOutputStream = new DataOutputStream(outputStream); 74b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 75b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang new ProgramClassWriter(classOutputStream).visitProgramClass(programClass); 76b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 77b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang classOutputStream.flush(); 78b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 79b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 80b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang catch (IOException e) 81b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang throw new RuntimeException("Can't write program class ["+actualClassName+"] to ["+actualDataEntry+"] ("+e.getMessage()+")", e); 83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 84b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 85b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang} 86