diff options
16 files changed, 288 insertions, 194 deletions
diff --git a/jack-tests/tests/com/android/jack/resource/test001/jack/proguard.flags b/jack-tests/tests/com/android/jack/resource/test001/jack/proguard.flags index a8d845e..7c233c3 100644 --- a/jack-tests/tests/com/android/jack/resource/test001/jack/proguard.flags +++ b/jack-tests/tests/com/android/jack/resource/test001/jack/proguard.flags @@ -1 +1,2 @@ -keep class com.android.jack.resource.test001.jack.IrrelevantForTest +-dontobfuscate diff --git a/jack/src/com/android/jack/Jack.java b/jack/src/com/android/jack/Jack.java index ca07644..12ab7aa 100644 --- a/jack/src/com/android/jack/Jack.java +++ b/jack/src/com/android/jack/Jack.java @@ -26,6 +26,7 @@ import com.android.jack.analysis.defsuses.DefUsesAndUseDefsChainRemover; import com.android.jack.analysis.defsuses.UseDefsChecker; import com.android.jack.analysis.dfa.reachingdefs.ReachingDefinitions; import com.android.jack.analysis.dfa.reachingdefs.ReachingDefinitionsRemover; +import com.android.jack.backend.ResourceWriter; import com.android.jack.backend.dex.ClassAnnotationBuilder; import com.android.jack.backend.dex.ClassDefItemBuilder; import com.android.jack.backend.dex.DexFileBuilder; @@ -43,7 +44,6 @@ import com.android.jack.backend.dex.rop.CodeItemBuilder; import com.android.jack.backend.jayce.JackFormatProduct; import com.android.jack.backend.jayce.JayceFileImporter; import com.android.jack.backend.jayce.JayceSingleTypeWriter; -import com.android.jack.backend.jayce.JayceZipWriter; import com.android.jack.cfg.CfgBuilder; import com.android.jack.cfg.CfgMarkerRemover; import com.android.jack.config.id.JavaVersionPropertyId.JavaVersion; @@ -84,8 +84,8 @@ import com.android.jack.scheduling.adapter.JPackageAdapter; import com.android.jack.scheduling.feature.DexNonZipOutput; import com.android.jack.scheduling.feature.DexZipOutput; import com.android.jack.scheduling.feature.DxLegacy; -import com.android.jack.scheduling.feature.JackFileNonZipOutput; -import com.android.jack.scheduling.feature.JackFileZipOutput; +import com.android.jack.scheduling.feature.JackFileOutput; +import com.android.jack.scheduling.feature.Resources; import com.android.jack.scheduling.feature.SourceVersion7; import com.android.jack.scheduling.tags.DexFileProduct; import com.android.jack.shrob.SeedFile; @@ -211,7 +211,9 @@ import com.android.sched.util.log.Tracer; import com.android.sched.util.log.TracerFactory; import com.android.sched.vfs.InputVDir; import com.android.sched.vfs.direct.InputDirectDir; +import com.android.sched.vfs.direct.OutputDirectDir; import com.android.sched.vfs.zip.InputZipArchive; +import com.android.sched.vfs.zip.OutputZipRootVDir; import org.antlr.runtime.RecognitionException; @@ -339,6 +341,8 @@ public abstract class Jack { JSession session = buildSession(options, hooks); Request request = createInitialRequest(); + request.addFeature(Resources.class); + JavaVersion sourceVersion = config.get(Options.JAVA_SOURCE_VERSION); if (sourceVersion.compareTo(JavaVersion.JAVA_7) >= 0) { request.addFeature(SourceVersion7.class); @@ -381,11 +385,7 @@ public abstract class Jack { } if (config.get(Options.GENERATE_JACK_FILE).booleanValue()) { - if (config.get(Options.JACK_OUTPUT_CONTAINER_TYPE) == Container.ZIP) { - request.addFeature(JackFileZipOutput.class); - } else { - request.addFeature(JackFileNonZipOutput.class); - } + request.addFeature(JackFileOutput.class); } if (options.ecjArguments == null) { @@ -421,12 +421,13 @@ public abstract class Jack { } else { fillJavaToJaycePlan(options, planBuilder); } - if (features.contains(DexZipOutput.class)) { - planBuilder.append(JayceZipWriter.class); - } else { - SubPlanBuilder<JDefinedClassOrInterface> typePlan = - planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdaptor.class); - typePlan.append(JayceSingleTypeWriter.class); + SubPlanBuilder<JDefinedClassOrInterface> typePlan = + planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdaptor.class); + typePlan.append(JayceSingleTypeWriter.class); + + if (features.contains(Resources.class)) { + SubPlanBuilder<JPackage> packagePlan = planBuilder.appendSubPlan(JPackageAdapter.class); + packagePlan.append(ResourceWriter.class); } } else if (options.ecjArguments == null) { assert targetProduction.contains(DexFileProduct.class); @@ -466,6 +467,35 @@ public abstract class Jack { JackFormatIr.class); } + if (config.get(Options.GENERATE_JACK_FILE).booleanValue()) { + Container outputContainer = config.get(Options.JACK_OUTPUT_CONTAINER_TYPE); + if (outputContainer == Container.DIR) { + session.setOutputVDir(new OutputDirectDir(config.get(Options.JACK_FILE_OUTPUT_DIR))); + } else if (outputContainer == Container.ZIP) { + try { + final OutputZipRootVDir vDir = + new OutputZipRootVDir(config.get(Options.JACK_FILE_OUTPUT_ZIP)); + final File jayceOutZip = options.jayceOutZip; + hooks.addHook(new Runnable() { + @Override + public void run() { + try { + vDir.close(); + } catch (IOException e) { + logger.log(Level.WARNING, + "Failed to close zip for '" + jayceOutZip.getAbsolutePath() + "'.", e); + } + } + }); + session.setOutputVDir(vDir); + } catch (IOException e) { + throw new JackFileException( + "Error initializing jack output zip: " + options.jayceOutZip.getAbsolutePath(), + e); + } + } + } + PlanPrinterFactory.getPlanPrinter().printPlan(plan); try { plan.getScheduleInstance().process(session); @@ -808,17 +838,12 @@ public abstract class Jack { methodPlan3.append(FieldInitMethodCallRemover.class); typePlan4.append(FieldInitMethodRemover.class); - if (features.contains(JackFileNonZipOutput.class)) { + if (features.contains(JackFileOutput.class)) { typePlan4.append(JayceSingleTypeWriter.class); } typePlan4.append(ReflectAnnotationsAdder.class); } } - - if (features.contains(JackFileZipOutput.class)) { - planBuilder.append(JayceZipWriter.class); - } - { SubPlanBuilder<JDefinedClassOrInterface> typePlan4 = planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdaptor.class); diff --git a/jack/src/com/android/jack/backend/ResourceWriter.java b/jack/src/com/android/jack/backend/ResourceWriter.java new file mode 100644 index 0000000..93d9d26 --- /dev/null +++ b/jack/src/com/android/jack/backend/ResourceWriter.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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 com.android.jack.backend; + +import com.android.jack.ir.ast.JPackage; +import com.android.jack.ir.ast.Resource; +import com.android.jack.ir.formatter.BinaryQualifiedNameFormatter; +import com.android.jack.scheduling.feature.Resources; +import com.android.jack.util.BytesStreamSucker; +import com.android.sched.item.Description; +import com.android.sched.item.Name; +import com.android.sched.item.Synchronized; +import com.android.sched.schedulable.RunnableSchedulable; +import com.android.sched.schedulable.Support; +import com.android.sched.vfs.InputVFile; +import com.android.sched.vfs.OutputVDir; +import com.android.sched.vfs.OutputVFile; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +import javax.annotation.Nonnull; + +/** + * Writer of resources. + */ +@Description("Writer of resources") +@Name("ResourceWriter") +@Support(Resources.class) +@Synchronized +public class ResourceWriter implements RunnableSchedulable<JPackage> { + + @Override + public synchronized void run(@Nonnull JPackage pack) throws Exception { + OutputVDir outputVDir = pack.getSession().getOutputVDir(); + List<Resource> resources = pack.getResources(); + for (Resource resource : resources) { + InputVFile inputFile = resource.getVFile(); + BinaryQualifiedNameFormatter formatter = BinaryQualifiedNameFormatter.getFormatter(); + String path = formatter.getName(pack, inputFile.getName()); + OutputVFile outputFile = outputVDir.createOutputVFile(path); + InputStream is = inputFile.openRead(); + OutputStream os = outputFile.openWrite(); + try { + BytesStreamSucker sucker = new BytesStreamSucker(is, os); + sucker.suck(); + } finally { + if (is != null) { + is.close(); + } + if (os != null) { + os.close(); + } + } + } + } +} diff --git a/jack/src/com/android/jack/backend/dex/DexZipWriter.java b/jack/src/com/android/jack/backend/dex/DexZipWriter.java index 6acb657..189b7b8 100644 --- a/jack/src/com/android/jack/backend/dex/DexZipWriter.java +++ b/jack/src/com/android/jack/backend/dex/DexZipWriter.java @@ -17,8 +17,9 @@ package com.android.jack.backend.dex; import com.android.jack.JackFileException; -import com.android.jack.backend.jayce.ResourceContainerMarker; import com.android.jack.dx.dex.file.DexFile; +import com.android.jack.ir.ast.JPackage; +import com.android.jack.ir.ast.Resource; import com.android.jack.ir.ast.JSession; import com.android.jack.scheduling.feature.DexZipOutput; import com.android.jack.scheduling.marker.DexFileMarker; @@ -64,24 +65,7 @@ public class DexZipWriter extends DexFileWriter { zos.putNextEntry(entry); dexFile.writeTo(zos, null, false); zos.closeEntry(); - - ResourceContainerMarker resourceContainer = session.getMarker(ResourceContainerMarker.class); - if (resourceContainer != null) { - for (InputVFile resource : resourceContainer.getResources()) { - Location location = resource.getLocation(); - String entryName; - if (location instanceof ZipLocation) { - ZipLocation zipLocation = (ZipLocation) location; - entryName = zipLocation.getEntryName(); - } else { - entryName = resource.getName(); - } - ZipEntry resourceEntry = new ZipEntry(entryName); - zos.putNextEntry(resourceEntry); - BytesStreamSucker sucker = new BytesStreamSucker(resource.openRead(), zos); - sucker.run(); - } - } + writeResourcesInPackages(session.getTopLevelPackage(), zos); } catch (IOException e) { throw new JackFileException( "Could not write Dex archive to output '" + outputFile.getAbsolutePath() + "'", e); @@ -91,4 +75,31 @@ public class DexZipWriter extends DexFileWriter { } } } + + private void writeResourcesInPackages(@Nonnull JPackage pack, @Nonnull ZipOutputStream zos) + throws IOException { + for (Resource resource : pack.getResources()) { + writeResource(resource, zos); + } + for (JPackage subpack : pack.getSubPackages()) { + writeResourcesInPackages(subpack, zos); + } + } + + private void writeResource(@Nonnull Resource resource, @Nonnull ZipOutputStream zos) + throws IOException { + InputVFile vFile = resource.getVFile(); + Location location = vFile.getLocation(); + String entryName; + if (location instanceof ZipLocation) { + ZipLocation zipLocation = (ZipLocation) location; + entryName = zipLocation.getEntryName(); + } else { + entryName = vFile.getName(); + } + ZipEntry resourceEntry = new ZipEntry(entryName); + zos.putNextEntry(resourceEntry); + BytesStreamSucker sucker = new BytesStreamSucker(vFile.openRead(), zos); + sucker.suck(); + } } diff --git a/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java b/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java index e975cc3..2937278 100644 --- a/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java +++ b/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java @@ -21,6 +21,7 @@ import com.android.jack.JackEventType; import com.android.jack.JackFileException; import com.android.jack.ir.ast.JDefinedClassOrInterface; import com.android.jack.ir.ast.JPackage; +import com.android.jack.ir.ast.Resource; import com.android.jack.ir.ast.JSession; import com.android.jack.jayce.JayceFormatException; import com.android.jack.jayce.JayceVersionException; @@ -85,17 +86,12 @@ public class JayceFileImporter { public void doImport(@Nonnull JSession session) throws JayceFormatException, JayceVersionException, JackFileException { - ResourceContainerMarker resourceMarker = session.getMarker(ResourceContainerMarker.class); - if (resourceMarker == null) { - resourceMarker = new ResourceContainerMarker(); - session.addMarker(resourceMarker); - } for (InputVDir jayceContainer : jayceContainers) { try { logger.log(Level.FINE, "Importing {0}", jayceContainer.getLocation().getDescription()); JPackage topLevelPackage = session.getTopLevelPackage(); for (VElement subFile : jayceContainer.list()) { - importJayceFile(subFile, session, topLevelPackage, resourceMarker); + importJayceFile(subFile, session, topLevelPackage); } } catch (IOException e) { throw new JackFileException( @@ -105,18 +101,17 @@ public class JayceFileImporter { } private void importJayceFile(@Nonnull VElement element, @Nonnull JSession session, - @Nonnull JPackage pack, @Nonnull ResourceContainerMarker resourceMarker) throws IOException, - JayceFormatException, JayceVersionException { + @Nonnull JPackage pack) throws IOException, JayceFormatException, JayceVersionException { if (element instanceof InputVDir) { for (VElement subFile : ((InputVDir) element).list()) { - importJayceFile(subFile, session, pack.getSubPackage(element.getName()), resourceMarker); + importJayceFile(subFile, session, pack.getSubPackage(element.getName())); } } else if (element instanceof InputVFile) { InputVFile file = (InputVFile) element; if (isJackFileName(file.getName())) { addImportedTypes(session, file.getName(), pack, file.getLocation()); } else { - resourceMarker.addResource(file); + pack.addResource(new Resource(file)); } } else { throw new AssertionError(); diff --git a/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java b/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java index fef2d32..e7976c4 100644 --- a/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java +++ b/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java @@ -18,14 +18,13 @@ package com.android.jack.backend.jayce; import com.android.jack.Jack; import com.android.jack.JackFileException; -import com.android.jack.Options; import com.android.jack.ir.JackFormatIr; import com.android.jack.ir.NonJackFormatIr; import com.android.jack.ir.ast.JDefinedClassOrInterface; import com.android.jack.ir.formatter.BinaryQualifiedNameFormatter; import com.android.jack.ir.formatter.TypeFormatter; import com.android.jack.jayce.JayceWriter; -import com.android.jack.scheduling.feature.JackFileNonZipOutput; +import com.android.jack.scheduling.feature.JackFileOutput; import com.android.sched.item.Description; import com.android.sched.item.Name; import com.android.sched.item.Synchronized; @@ -33,11 +32,8 @@ import com.android.sched.schedulable.Constraint; import com.android.sched.schedulable.Produce; import com.android.sched.schedulable.RunnableSchedulable; import com.android.sched.schedulable.Support; -import com.android.sched.util.config.ThreadConfig; -import com.android.sched.util.file.Directory; import com.android.sched.vfs.OutputVDir; import com.android.sched.vfs.OutputVFile; -import com.android.sched.vfs.direct.OutputDirectDir; import java.io.BufferedOutputStream; import java.io.File; @@ -53,19 +49,17 @@ import javax.annotation.Nonnull; @Name("JayceSingleTypeWriter") @Constraint(need = {JackFormatIr.class}, no = {NonJackFormatIr.class}) @Produce(JackFormatProduct.class) -@Support(JackFileNonZipOutput.class) +@Support(JackFileOutput.class) @Synchronized public class JayceSingleTypeWriter implements RunnableSchedulable<JDefinedClassOrInterface> { @Nonnull private static final TypeFormatter formatter = new FilePathFormatter(); - @Nonnull - private final Directory outputDir = ThreadConfig.get(Options.JACK_FILE_OUTPUT_DIR); - @Override public synchronized void run(@Nonnull JDefinedClassOrInterface type) throws Exception { - OutputVDir vDir = new OutputDirectDir(outputDir); + OutputVDir vDir = type.getSession().getOutputVDir(); + assert vDir != null; OutputVFile vFile = vDir.createOutputVFile(getFilePath(type)); try { diff --git a/jack/src/com/android/jack/backend/jayce/JayceZipWriter.java b/jack/src/com/android/jack/backend/jayce/JayceZipWriter.java deleted file mode 100644 index 4b63226..0000000 --- a/jack/src/com/android/jack/backend/jayce/JayceZipWriter.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * 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 com.android.jack.backend.jayce; - -import com.android.jack.JackFileException; -import com.android.jack.Options; -import com.android.jack.ir.JackFormatIr; -import com.android.jack.ir.NonJackFormatIr; -import com.android.jack.ir.ast.JDefinedClassOrInterface; -import com.android.jack.ir.ast.JSession; -import com.android.jack.jayce.JayceWriter; -import com.android.jack.scheduling.feature.JackFileZipOutput; -import com.android.jack.util.BytesStreamSucker; -import com.android.sched.item.Description; -import com.android.sched.item.Name; -import com.android.sched.schedulable.Constraint; -import com.android.sched.schedulable.Produce; -import com.android.sched.schedulable.RunnableSchedulable; -import com.android.sched.schedulable.Support; -import com.android.sched.util.config.ThreadConfig; -import com.android.sched.util.location.Location; -import com.android.sched.util.location.ZipLocation; -import com.android.sched.vfs.InputVFile; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import javax.annotation.Nonnull; - -/** - * Writer of Jayce files in a zip organized according to package names. - */ -@Description("Writer of Jayce files in a zip organized according to package names") -@Name("JayceZipWriter") -@Constraint(need = {JackFormatIr.class}, no = {NonJackFormatIr.class}) -@Produce(JackFormatProduct.class) -@Support(JackFileZipOutput.class) -public class JayceZipWriter implements RunnableSchedulable<JSession> { - - @Nonnull - private final File outputZip = ThreadConfig.get(Options.JACK_FILE_OUTPUT_ZIP); - - @Override - public void run(@Nonnull JSession session) throws Exception { - - try { - ZipOutputStream zos = - new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outputZip))); - try { - for (JDefinedClassOrInterface type : session.getTypesToEmit()) { - String filePath = JayceSingleTypeWriter.getFilePath(type); - ZipEntry zipEntry = new ZipEntry(filePath); - zos.putNextEntry(zipEntry); - JayceWriter writer = new JayceWriter(zos); - writer.write(type, "jack-zip"); - } - - ResourceContainerMarker resourceContainer = - session.getMarker(ResourceContainerMarker.class); - if (resourceContainer != null) { - for (InputVFile resource : resourceContainer.getResources()) { - Location location = resource.getLocation(); - String entryName; - if (location instanceof ZipLocation) { - ZipLocation zipLocation = (ZipLocation) location; - entryName = zipLocation.getEntryName(); - } else { - entryName = resource.getName(); - } - ZipEntry resourceEntry = new ZipEntry(entryName); - zos.putNextEntry(resourceEntry); - BytesStreamSucker sucker = - new BytesStreamSucker(resource.openRead(), zos); - sucker.run(); - } - } - } finally { - zos.close(); - } - } catch (IOException e) { - throw new JackFileException( - "Could not write Jack archive to output '" + outputZip.getAbsolutePath() + "'", e); - } - } -} diff --git a/jack/src/com/android/jack/ir/ast/JPackage.java b/jack/src/com/android/jack/ir/ast/JPackage.java index a09b06f..34f1118 100644 --- a/jack/src/com/android/jack/ir/ast/JPackage.java +++ b/jack/src/com/android/jack/ir/ast/JPackage.java @@ -79,6 +79,9 @@ public class JPackage extends JNode implements HasName, CanBeRenamed, HasEnclosi private final List<JPhantomAnnotation> phantomAnnotations = new ArrayList<JPhantomAnnotation>(); @Nonnull + private final List<Resource> resources = new ArrayList<Resource>(); + + @Nonnull private String name; @Nonnull @@ -117,6 +120,10 @@ public class JPackage extends JNode implements HasName, CanBeRenamed, HasEnclosi subPackages.add(newPackage); } + public void addResource(@Nonnull Resource resource) { + resources.add(resource); + } + public void add(@Nonnull HasEnclosingPackage node) { if (node instanceof JDefinedClassOrInterface) { addType((JDefinedClassOrInterface) node); @@ -139,6 +146,11 @@ public class JPackage extends JNode implements HasName, CanBeRenamed, HasEnclosi return declaredTypes; } + @Nonnull + public List<Resource> getResources() { + return resources; + } + @Override @CheckForNull public JPackage getEnclosingPackage() { diff --git a/jack/src/com/android/jack/ir/ast/JSession.java b/jack/src/com/android/jack/ir/ast/JSession.java index 61801ed..20c72e7 100644 --- a/jack/src/com/android/jack/ir/ast/JSession.java +++ b/jack/src/com/android/jack/ir/ast/JSession.java @@ -27,6 +27,7 @@ import com.android.sched.scheduler.ScheduleInstance; import com.android.sched.transform.TransformRequest; import com.android.sched.util.log.Tracer; import com.android.sched.util.log.TracerFactory; +import com.android.sched.vfs.OutputVDir; import java.util.ArrayList; import java.util.List; @@ -61,6 +62,18 @@ public class JSession extends JNode { @Nonnull private final transient Tracer tracer = TracerFactory.getTracer(); + @CheckForNull + private transient OutputVDir outputVDir; + + @CheckForNull + public OutputVDir getOutputVDir() { + return outputVDir; + } + + public void setOutputVDir(@Nonnull OutputVDir outputVDir) { + this.outputVDir = outputVDir; + } + public JSession() { super(SourceOrigin.create(0, 0, JSession.class.getName())); topLevelPackage = new JPackage("", this, null); diff --git a/jack/src/com/android/jack/ir/ast/Resource.java b/jack/src/com/android/jack/ir/ast/Resource.java new file mode 100644 index 0000000..4efd5de --- /dev/null +++ b/jack/src/com/android/jack/ir/ast/Resource.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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 com.android.jack.ir.ast; + +import com.android.sched.item.Description; +import com.android.sched.vfs.InputVFile; + +import java.io.Serializable; + +import javax.annotation.Nonnull; + +/** + * Represents a resource. + */ +@Description("Represents a resource") +public class Resource implements Serializable { + + private static final long serialVersionUID = 1L; + + @Nonnull + private final transient InputVFile vFile; + + public Resource(@Nonnull InputVFile vFile) { + this.vFile = vFile; + } + + @Nonnull + public InputVFile getVFile() { + return vFile; + } +} diff --git a/jack/src/com/android/jack/scheduling/feature/JackFileNonZipOutput.java b/jack/src/com/android/jack/scheduling/feature/JackFileOutput.java index 71ca439..1e3d397 100644 --- a/jack/src/com/android/jack/scheduling/feature/JackFileNonZipOutput.java +++ b/jack/src/com/android/jack/scheduling/feature/JackFileOutput.java @@ -21,9 +21,9 @@ import com.android.sched.item.Feature; import com.android.sched.item.Name; /** - * Jack non-zip output + * Jack file output */ -@Description("Jack non-zip output") -@Name("JackNonZipOutput") -public class JackFileNonZipOutput implements Feature { +@Description("Jack file output") +@Name("JackFileOutput") +public class JackFileOutput implements Feature { } diff --git a/jack/src/com/android/jack/scheduling/feature/JackFileZipOutput.java b/jack/src/com/android/jack/scheduling/feature/Resources.java index 7428a7b..5d821d1 100644 --- a/jack/src/com/android/jack/scheduling/feature/JackFileZipOutput.java +++ b/jack/src/com/android/jack/scheduling/feature/Resources.java @@ -21,9 +21,9 @@ import com.android.sched.item.Feature; import com.android.sched.item.Name; /** - * Jack file zip output + * Resource support */ -@Description("Jack file zip output") -@Name("JackFileZipOutput") -public class JackFileZipOutput implements Feature { +@Description("Resource support") +@Name("Resources") +public class Resources implements Feature { } diff --git a/jack/src/com/android/jack/util/BytesStreamSucker.java b/jack/src/com/android/jack/util/BytesStreamSucker.java index de8c123..8ded5a8 100644 --- a/jack/src/com/android/jack/util/BytesStreamSucker.java +++ b/jack/src/com/android/jack/util/BytesStreamSucker.java @@ -28,9 +28,12 @@ import javax.annotation.Nonnull; * Class that continuously read an {@link InputStream} and optionally could write the input in a * {@link OutputStream}. */ -public class BytesStreamSucker implements Runnable { +public class BytesStreamSucker { + + private static final int BUFFER_SIZE = 4096; + @Nonnull - private final byte[] buffer = new byte[1024]; + private final byte[] buffer = new byte[BUFFER_SIZE]; @Nonnull private final InputStream is; @@ -55,23 +58,16 @@ public class BytesStreamSucker implements Runnable { this(is, new NullOutputStream(), false); } - @Override - public void run() { + public void suck() throws IOException { try { int bytesRead; while ((bytesRead = is.read(buffer)) >= 0) { os.write(buffer, 0, bytesRead); os.flush(); } - } catch (Exception e) { - // Best effort } finally { if (toBeClose) { - try { - os.close(); - } catch (IOException e) { - // Best effort - } + os.close(); } } } diff --git a/jack/src/com/android/jack/util/CharactersStreamSucker.java b/jack/src/com/android/jack/util/CharactersStreamSucker.java index 65e21fc..80fedf0 100644 --- a/jack/src/com/android/jack/util/CharactersStreamSucker.java +++ b/jack/src/com/android/jack/util/CharactersStreamSucker.java @@ -17,6 +17,7 @@ package com.android.jack.util; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; @@ -27,7 +28,7 @@ import javax.annotation.Nonnull; * Class that continuously read an {@link InputStream} and optionally could print the input in a * {@link PrintStream}. */ -public class CharactersStreamSucker implements Runnable { +public class CharactersStreamSucker { @Nonnull private final BufferedReader ir; @@ -52,16 +53,13 @@ public class CharactersStreamSucker implements Runnable { this(is, new NullPrintStream(), false); } - @Override - public void run() { + public void suck() throws IOException { String line; try { while ((line = ir.readLine()) != null) { os.println(line); } - } catch (Exception e) { - // Best effort } finally { if (toBeClose) { os.close(); diff --git a/jack/src/com/android/jack/util/ExecuteFile.java b/jack/src/com/android/jack/util/ExecuteFile.java index 1120121..a17155e 100644 --- a/jack/src/com/android/jack/util/ExecuteFile.java +++ b/jack/src/com/android/jack/util/ExecuteFile.java @@ -186,8 +186,8 @@ public class ExecuteFile { InputStream localInStream = inStream; if (localInStream != null) { - suckIn = - new Thread(new BytesStreamSucker(localInStream, proc.getOutputStream(), inToBeClose)); + suckIn = new Thread( + new ThreadBytesStreamSucker(localInStream, proc.getOutputStream(), inToBeClose)); } else { proc.getOutputStream().close(); } @@ -195,22 +195,22 @@ public class ExecuteFile { OutputStream localOutStream = outStream; if (localOutStream != null) { if (localOutStream instanceof PrintStream) { - suckOut = new Thread(new CharactersStreamSucker(proc.getInputStream(), + suckOut = new Thread(new ThreadCharactersStreamSucker(proc.getInputStream(), (PrintStream) localOutStream, outToBeClose)); } else { suckOut = new Thread( - new BytesStreamSucker(proc.getInputStream(), localOutStream, outToBeClose)); + new ThreadBytesStreamSucker(proc.getInputStream(), localOutStream, outToBeClose)); } } OutputStream localErrStream = errStream; if (localErrStream != null) { if (localErrStream instanceof PrintStream) { - suckErr = new Thread(new CharactersStreamSucker(proc.getErrorStream(), + suckErr = new Thread(new ThreadCharactersStreamSucker(proc.getErrorStream(), (PrintStream) localErrStream, errToBeClose)); } else { suckErr = new Thread( - new BytesStreamSucker(proc.getErrorStream(), localErrStream, errToBeClose)); + new ThreadBytesStreamSucker(proc.getErrorStream(), localErrStream, errToBeClose)); } } @@ -243,4 +243,39 @@ public class ExecuteFile { return false; } } + + private static class ThreadBytesStreamSucker extends BytesStreamSucker implements Runnable { + + public ThreadBytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os, + boolean toBeClose) { + super(is, os, toBeClose); + } + + @Override + public void run() { + try { + suck(); + } catch (IOException e) { + // Best effort + } + } + } + + private static class ThreadCharactersStreamSucker extends CharactersStreamSucker implements + Runnable { + + public ThreadCharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream ps, + boolean toBeClose) { + super(is, ps, toBeClose); + } + + @Override + public void run() { + try { + suck(); + } catch (IOException e) { + // Best effort + } + } + } }
\ No newline at end of file diff --git a/jack/tests/com/android/jack/ResourceTest.java b/jack/tests/com/android/jack/ResourceTest.java index 5f67828..19b8cf7 100644 --- a/jack/tests/com/android/jack/ResourceTest.java +++ b/jack/tests/com/android/jack/ResourceTest.java @@ -305,7 +305,7 @@ public class ResourceTest { try { fos = new FileOutputStream(copiedFile); BytesStreamSucker sucker = new BytesStreamSucker(fis, fos); - sucker.run(); + sucker.suck(); } finally { if (fos != null) { fos.close(); @@ -327,7 +327,7 @@ public class ResourceTest { ZipEntry sourceEntry = new ZipEntry(entryName); zos.putNextEntry(sourceEntry); BytesStreamSucker sucker = new BytesStreamSucker(fis, zos); - sucker.run(); + sucker.suck(); } finally { if (fis != null) { fis.close(); |