summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jack-tests/tests/com/android/jack/resource/test001/jack/proguard.flags1
-rw-r--r--jack/src/com/android/jack/Jack.java65
-rw-r--r--jack/src/com/android/jack/backend/ResourceWriter.java72
-rw-r--r--jack/src/com/android/jack/backend/dex/DexZipWriter.java49
-rw-r--r--jack/src/com/android/jack/backend/jayce/JayceFileImporter.java15
-rw-r--r--jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java14
-rw-r--r--jack/src/com/android/jack/backend/jayce/JayceZipWriter.java103
-rw-r--r--jack/src/com/android/jack/ir/ast/JPackage.java12
-rw-r--r--jack/src/com/android/jack/ir/ast/JSession.java13
-rw-r--r--jack/src/com/android/jack/ir/ast/Resource.java45
-rw-r--r--jack/src/com/android/jack/scheduling/feature/JackFileOutput.java (renamed from jack/src/com/android/jack/scheduling/feature/JackFileNonZipOutput.java)8
-rw-r--r--jack/src/com/android/jack/scheduling/feature/Resources.java (renamed from jack/src/com/android/jack/scheduling/feature/JackFileZipOutput.java)8
-rw-r--r--jack/src/com/android/jack/util/BytesStreamSucker.java18
-rw-r--r--jack/src/com/android/jack/util/CharactersStreamSucker.java8
-rw-r--r--jack/src/com/android/jack/util/ExecuteFile.java47
-rw-r--r--jack/tests/com/android/jack/ResourceTest.java4
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();