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