proguard.io.DataEntryCopier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proguard-core Show documentation
Show all versions of proguard-core Show documentation
ProGuardCORE is a free library to read, analyze, modify, and write Java class files.
/*
* ProGuardCORE -- library to process Java bytecode.
*
* Copyright (c) 2002-2020 Guardsquare NV
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package proguard.io;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import proguard.classfile.ClassConstants;
import proguard.util.ExtensionMatcher;
import java.io.*;
/**
* This {@link DataEntryReader} writes the ZIP entries and files that it reads to a
* given {@link DataEntryWriter}.
*
* @author Eric Lafortune
*/
public class DataEntryCopier implements DataEntryReader
{
private static final byte[] JMOD_HEADER = new byte[] { 'J', 'M', 1, 0 };
private static final int BUFFER_SIZE = 1024;
private static final Logger logger = LogManager.getLogger(DataEntryCopier.class);
private final DataEntryWriter dataEntryWriter;
private final byte[] buffer = new byte[BUFFER_SIZE];
/**
* Creates a new DataEntryCopier.
*/
public DataEntryCopier(DataEntryWriter dataEntryWriter)
{
this.dataEntryWriter = dataEntryWriter;
}
// Implementations for DataEntryReader.
@Override
public void read(DataEntry dataEntry) throws IOException
{
try
{
if (dataEntry.isDirectory())
{
dataEntryWriter.createDirectory(dataEntry);
}
else
{
// Get the output entry corresponding to this input entry.
OutputStream outputStream = dataEntryWriter.createOutputStream(dataEntry);
if (outputStream != null)
{
try
{
InputStream inputStream = dataEntry.getInputStream();
try
{
// Copy the data from the input entry to the output entry.
copyData(inputStream, outputStream);
// Flush the output stream, just to be sure.
outputStream.flush();
}
finally
{
// Close the input stream.
dataEntry.closeInputStream();
}
}
finally
{
// Close the output stream.
outputStream.close();
}
}
}
}
catch (IOException ex)
{
logger.error("Warning: can't write resource [{}] ({})", dataEntry.getName(), ex.getMessage());
}
catch (Exception ex)
{
throw (IOException)new IOException("Can't write resource ["+dataEntry.getName()+"] ("+ex.getMessage()+")").initCause(ex);
}
}
/**
* Copies all data that it can read from the given input stream to the
* given output stream. The caller of this method will open and
* afterwards flush and close the input stream and the output stream.
* The implementation of this method needs to make sure that any wrapping
* output streams are flushed before returning.
*/
protected void copyData(InputStream inputStream,
OutputStream outputStream)
throws IOException
{
while (true)
{
int count = inputStream.read(buffer);
if (count < 0)
{
break;
}
outputStream.write(buffer, 0, count);
}
}
/**
* A main method for testing file/archive/directory copying.
*/
public static void main(String[] args)
{
try
{
String input = args[0];
String output = args[1];
boolean outputIsApk = output.endsWith(".apk") ||
output.endsWith(".ap_");
boolean outputIsJar = output.endsWith(".jar");
boolean outputIsAar = output.endsWith(".aar");
boolean outputIsWar = output.endsWith(".war");
boolean outputIsEar = output.endsWith(".ear");
boolean outputIsJmod = output.endsWith(".jmod");
boolean outputIsZip = output.endsWith(".zip");
DataEntryWriter writer =
outputIsApk ||
outputIsJar ||
outputIsAar ||
outputIsWar ||
outputIsEar ||
outputIsJmod ||
outputIsZip ?
new FixedFileWriter(new File(output)) :
new DirectoryWriter(new File(output));
// Zip up any zips, if necessary.
DataEntryWriter zipWriter = new ZipWriter(null,
1,
false,
0,
new byte[0],
writer);
if (outputIsZip)
{
// Always zip.
writer = zipWriter;
}
else
{
// Only zip up zips.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".zip"))),
zipWriter,
writer);
}
// Zip up any jmods, if necessary.
DataEntryWriter jmodWriter = new ZipWriter(null,
1,
false,
0,
JMOD_HEADER,
writer);
if (outputIsJmod)
{
// Always zip.
writer = jmodWriter;
}
else
{
// Only zip up jmods.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".jmod"))),
jmodWriter,
writer);
}
// Zip up any wars, if necessary.
DataEntryWriter warWriter = new ZipWriter(null,
1,
false,
0,
new byte[0],
writer);
if (outputIsWar)
{
// Always zip.
writer = warWriter;
}
else
{
// Only zip up wars.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".war"))),
warWriter,
writer);
}
// Zip up any aars, if necessary.
DataEntryWriter aarWriter = new ZipWriter(null,
1,
false,
0,
new byte[0],
writer);
if (outputIsWar)
{
// Always zip.
writer = aarWriter;
}
else
{
// Only zip up aars.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".aar"))),
aarWriter,
writer);
}
// Zip up any jars, if necessary.
DataEntryWriter jarWriter = new ZipWriter(null,
1,
false,
0,
new byte[0],
writer);
if (outputIsJar)
{
// Always zip.
writer = jarWriter;
}
else
{
// Only zip up jars.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".jar"))),
jarWriter,
writer);
}
// Zip up any apks, if necessary.
DataEntryWriter apkWriter = new ZipWriter(null,
1,
false,
0,
new byte[0],
writer);
if (outputIsApk)
{
// Always zip.
writer = apkWriter;
}
else
{
// Only zip up apks.
writer = new FilteredDataEntryWriter(new DataEntryParentFilter(
new DataEntryNameFilter(
new ExtensionMatcher(".apk"))),
apkWriter,
writer);
}
// Create the copying DataEntryReader.
DataEntryReader reader = new DataEntryCopier(writer);
boolean inputIsApk = input.endsWith(".apk") ||
input.endsWith(".ap_");
boolean inputIsJar = input.endsWith(".jar");
boolean inputIsAar = input.endsWith(".aar");
boolean inputIsWar = input.endsWith(".war");
boolean inputIsEar = input.endsWith(".ear");
boolean inputIsJmod = input.endsWith(".jmod");
boolean inputIsZip = input.endsWith(".zip");
// Unzip any apks, if necessary.
DataEntryReader apkReader = new JarReader(reader);
if (inputIsApk)
{
// Always unzip.
reader = apkReader;
}
else
{
// Only unzip apk entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".apk")),
apkReader,
reader);
// Unzip any jars, if necessary.
DataEntryReader jarReader = new JarReader(reader);
if (inputIsJar)
{
// Always unzip.
reader = jarReader;
}
else
{
// Only unzip jar entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".jar")),
jarReader,
reader);
// Unzip any aars, if necessary.
DataEntryReader aarReader = new JarReader(reader);
if (inputIsAar)
{
// Always unzip.
reader = aarReader;
}
else
{
// Only unzip aar entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".aar")),
aarReader,
reader);
// Unzip any wars, if necessary.
DataEntryReader warReader = new JarReader(reader);
if (inputIsWar)
{
// Always unzip.
reader = warReader;
}
else
{
// Only unzip war entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".war")),
warReader,
reader);
// Unzip any ears, if necessary.
DataEntryReader earReader = new JarReader(reader);
if (inputIsEar)
{
// Always unzip.
reader = earReader;
}
else
{
// Only unzip ear entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".ear")),
earReader,
reader);
// Unzip any jmods, if necessary.
DataEntryReader jmodReader = new JarReader(true, reader);
if (inputIsJmod)
{
// Always unzip.
reader = jmodReader;
}
else
{
// Only unzip jmod entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".jmod")),
jmodReader,
reader);
// Unzip any zips, if necessary.
DataEntryReader zipReader = new JarReader(reader);
if (inputIsZip)
{
// Always unzip.
reader = zipReader;
}
else
{
// Only unzip zip entries.
reader = new FilteredDataEntryReader(new DataEntryNameFilter(
new ExtensionMatcher(".zip")),
zipReader,
reader);
}
}
}
}
}
}
}
DataEntrySource source = new DirectorySource(new File(input));
source.pumpDataEntries(reader);
writer.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy