diff options
author | mikaelpeltier <mikaelpeltier@google.com> | 2014-11-10 11:17:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-11-10 11:17:34 +0000 |
commit | 449d72f039ec05b2bcb089ba9f48bc065358386c (patch) | |
tree | eaee11822e62c8119fae534366ff528dd54b146d /jack/src | |
parent | db6ec1e71ffcce464e16af58a60d8f029c676a91 (diff) | |
parent | acb363570e0d4feaede480f052ec1daa26f48275 (diff) | |
download | toolchain_jack-449d72f039ec05b2bcb089ba9f48bc065358386c.zip toolchain_jack-449d72f039ec05b2bcb089ba9f48bc065358386c.tar.gz toolchain_jack-449d72f039ec05b2bcb089ba9f48bc065358386c.tar.bz2 |
Merge "Library versioning support" into ub-jack
Diffstat (limited to 'jack/src')
42 files changed, 1532 insertions, 550 deletions
diff --git a/jack/src/com/android/jack/Jack.java b/jack/src/com/android/jack/Jack.java index 64d18a9..40761bc 100644 --- a/jack/src/com/android/jack/Jack.java +++ b/jack/src/com/android/jack/Jack.java @@ -85,8 +85,9 @@ import com.android.jack.ir.sourceinfo.SourceInfoCreation; import com.android.jack.jayce.JaycePackageLoader; import com.android.jack.library.BinaryKind; import com.android.jack.library.InputJackLibrary; +import com.android.jack.library.JackLibraryFactory; +import com.android.jack.library.LibraryReadingException; import com.android.jack.library.LibraryWritingException; -import com.android.jack.library.OutputJackLibrary; import com.android.jack.library.OutputLibrary; import com.android.jack.lookup.CommonTypes; import com.android.jack.lookup.JPhantomLookup; @@ -346,6 +347,11 @@ public abstract class Jack { } @Nonnull + public static String getEmitterId() { + return "jack"; + } + + @Nonnull public static UnmodifiableCollections getUnmodifiableCollections() { if (unmodifiableCollections == null) { unmodifiableCollections = @@ -433,7 +439,8 @@ public abstract class Jack { } else { outputDir = ThreadConfig.get(Options.JAYCE_FILE_OUTPUT_ZIP); } - session.setOutputLibrary(new OutputJackLibrary(outputDir)); + session.setJackOutputLibrary(JackLibraryFactory.getOutputLibrary(outputDir, + Jack.getEmitterId(), Jack.getVersionString())); } Request request = createInitialRequest(); @@ -610,9 +617,9 @@ public abstract class Jack { PlanPrinterFactory.getPlanPrinter().printPlan(plan); try { plan.getScheduleInstance().process(session); - OutputLibrary outputLibrary = session.getOutputLibrary(); - if (outputLibrary != null) { - outputLibrary.close(); + OutputLibrary jackOutputLibrary = session.getJackOutputLibrary(); + if (jackOutputLibrary != null) { + jackOutputLibrary.close(); } } catch (LibraryWritingException e) { session.getReporter().report(Severity.FATAL, e); @@ -670,8 +677,14 @@ public abstract class Jack { JSession session = getSession(); - JayceFileImporter jayceImporter = - getJayceFileImporter(options.jayceImport, hooks, session); + JayceFileImporter jayceImporter; + try { + jayceImporter = getJayceFileImporter(options.jayceImport, hooks, session); + } catch (LibraryReadingException e) { + session.getReporter().report(Severity.FATAL, e); + throw new JackAbortException(e); + } + putInJackClasspath(options.getBootclasspath(), hooks, session); putInJackClasspath(options.getClasspath(), hooks, session); @@ -720,24 +733,26 @@ public abstract class Jack { @Nonnull private static JayceFileImporter getJayceFileImporter(@Nonnull List<File> jayceImport, - @Nonnull RunnableHooks hooks, @Nonnull JSession session) throws JackFileException { + @Nonnull RunnableHooks hooks, @Nonnull JSession session) throws LibraryReadingException { List<InputJackLibrary> inputJackLibraries = new ArrayList<InputJackLibrary>(jayceImport.size()); ReflectFactory<JaycePackageLoader> factory = ThreadConfig.get(IMPORT_POLICY); for (final File jackFile : jayceImport) { try { InputRootVDir vDir = wrapAsVDir(jackFile, hooks); - InputJackLibrary inputJackLibrary = new InputJackLibrary(vDir); + InputJackLibrary inputJackLibrary = JackLibraryFactory.getInputLibrary(vDir); inputJackLibraries.add(inputJackLibrary); // add to classpath - JaycePackageLoader rootPLoader = factory.create(inputJackLibrary, - session.getPhantomLookup()); + JaycePackageLoader rootPLoader = + factory.create(inputJackLibrary, session.getPhantomLookup()); session.getTopLevelPackage().addLoader(rootPLoader); session.addImportSource(vDir); } catch (IOException ioException) { - throw new JackFileException("Error importing jack container: " + ioException.getMessage(), - ioException); + throw new LibraryReadingException(ioException); + } catch (LibraryException libException) { + throw new LibraryReadingException(libException); } } + return new JayceFileImporter(inputJackLibraries); } @@ -749,7 +764,7 @@ public abstract class Jack { try { InputRootVDir vDir = wrapAsVDir(jackFile, hooks); JaycePackageLoader rootPLoader = - factory.create(new InputJackLibrary(vDir), session.getPhantomLookup()); + factory.create(JackLibraryFactory.getInputLibrary(vDir), session.getPhantomLookup()); session.getTopLevelPackage().addLoader(rootPLoader); session.addClasspathSource(vDir); } catch (IOException ioException) { @@ -1450,7 +1465,7 @@ public abstract class Jack { } { SubPlanBuilder<JDefinedClassOrInterface> typePlan3 = - planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class); + planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class); { { SubPlanBuilder<JMethod> methodPlan2 = @@ -1471,7 +1486,7 @@ public abstract class Jack { } { SubPlanBuilder<JDefinedClassOrInterface> typePlan = - planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class); + planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class); typePlan.append(ReflectAnnotationsAdder.class); { SubPlanBuilder<JMethod> methodPlan = typePlan.appendSubPlan(JMethodAdapter.class); @@ -1484,7 +1499,7 @@ public abstract class Jack { } { SubPlanBuilder<JDefinedClassOrInterface> typePlan4 = - planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class); + planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class); typePlan4.append(ClassDefItemBuilder.class); typePlan4.append(ClassAnnotationBuilder.class); { @@ -1535,7 +1550,7 @@ public abstract class Jack { { SubPlanBuilder<JDefinedClassOrInterface> typePlan5 = - planBuilder.appendSubPlan(JDefinedClassOrInterfaceAdapter.class); + planBuilder.appendSubPlan(ExcludeTypeFromLibWithBinaryAdapter.class); { SubPlanBuilder<JMethod> methodPlan4 = typePlan5.appendSubPlan(JMethodAdapter.class); diff --git a/jack/src/com/android/jack/JayceException.java b/jack/src/com/android/jack/JayceException.java new file mode 100644 index 0000000..32ac02d --- /dev/null +++ b/jack/src/com/android/jack/JayceException.java @@ -0,0 +1,31 @@ +/* + * 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; + +import javax.annotation.Nonnull; + +/** + * Exception representing a problem related to a Jayce file. + */ +public abstract class JayceException extends JackUserException { + + private static final long serialVersionUID = 1L; + + public JayceException(@Nonnull String string) { + super(string); + } +} diff --git a/jack/src/com/android/jack/JackFileException.java b/jack/src/com/android/jack/LibraryException.java index 94dadc6..440f5da 100644 --- a/jack/src/com/android/jack/JackFileException.java +++ b/jack/src/com/android/jack/LibraryException.java @@ -20,22 +20,21 @@ import javax.annotation.Nonnull; /** - * Exception representing a problem related to Jayce files. + * Exception representing a problem related to a library. */ -public class JackFileException extends JackIOException { +public abstract class LibraryException extends JackUserException { private static final long serialVersionUID = 1L; - public JackFileException() { + protected LibraryException() { super(); } - public JackFileException(@Nonnull String message) { + protected LibraryException(@Nonnull String message) { super(message); } - public JackFileException(@Nonnull String message, @Nonnull Throwable cause) { - super(message, cause); + public LibraryException(@Nonnull Throwable cause) { + super(cause); } - } diff --git a/jack/src/com/android/jack/Options.java b/jack/src/com/android/jack/Options.java index 11de084..b18345b 100644 --- a/jack/src/com/android/jack/Options.java +++ b/jack/src/com/android/jack/Options.java @@ -597,6 +597,7 @@ public class Options { configBuilder.set(GENERATE_JAYCE_FILE, true); if (generateIntermediateDex) { configBuilder.set(GENERATE_INTERMEDIATE_DEX, true); + configBuilder.set(INTERMEDIATE_DEX_DIR, null); } } @@ -698,7 +699,7 @@ public class Options { // Check Jack arguments if (generateIntermediateDex && (out != null || outZip != null || jayceOutZip != null)) { throw new IllegalOptionsException( - "--generate-intermediate-dex must be use only with --output-jack"); + "--generate-intermediate-dex must be use only with --output-jack-dir"); } if (emitSyntheticDebugInfo && !emitLocalDebugInfo) { diff --git a/jack/src/com/android/jack/backend/dex/DexProperties.java b/jack/src/com/android/jack/backend/dex/DexProperties.java new file mode 100644 index 0000000..3f5629c --- /dev/null +++ b/jack/src/com/android/jack/backend/dex/DexProperties.java @@ -0,0 +1,29 @@ +/* + * 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.dex; + +import javax.annotation.Nonnull; + +/** + * Properties related to dex files. + */ +public interface DexProperties { + + @Nonnull + public static final String KEY_DEX = "dex"; + +} diff --git a/jack/src/com/android/jack/backend/dex/DexWritingTool.java b/jack/src/com/android/jack/backend/dex/DexWritingTool.java index 8f782c4..fffbe25 100644 --- a/jack/src/com/android/jack/backend/dex/DexWritingTool.java +++ b/jack/src/com/android/jack/backend/dex/DexWritingTool.java @@ -36,6 +36,7 @@ import com.android.sched.util.file.CannotCreateFileException; import com.android.sched.util.file.CannotReadException; import com.android.sched.util.file.NotFileOrDirectoryException; import com.android.sched.util.location.Location; +import com.android.sched.util.log.LoggerFactory; import com.android.sched.vfs.InputRootVDir; import com.android.sched.vfs.InputVFile; import com.android.sched.vfs.OutputVDir; @@ -46,6 +47,8 @@ import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nonnull; @@ -55,6 +58,9 @@ import javax.annotation.Nonnull; public abstract class DexWritingTool { @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + @Nonnull private final boolean forceJumbo = ThreadConfig.get(CodeItemBuilder.FORCE_JUMBO).booleanValue(); @Nonnull @@ -131,7 +137,10 @@ public abstract class DexWritingTool { new VPath(BinaryQualifiedNameFormatter.getFormatter().getName(type), '/'), BinaryKind.DEX); } catch (BinaryDoesNotExistException e) { - throw new LibraryFormatException(e); + logger.log(Level.SEVERE, + "Library " + inputLibrary.getLocation().getDescription() + " is invalid", + e); + throw new LibraryFormatException(inputLibrary.getLocation()); } } else { inputVFile = getIntermediateDexDir().getInputVFile(DexWriter.getFilePath(type)); diff --git a/jack/src/com/android/jack/backend/dex/IntermediateDexPerTypeWriter.java b/jack/src/com/android/jack/backend/dex/IntermediateDexPerTypeWriter.java index 3bcfa07..0312a94 100644 --- a/jack/src/com/android/jack/backend/dex/IntermediateDexPerTypeWriter.java +++ b/jack/src/com/android/jack/backend/dex/IntermediateDexPerTypeWriter.java @@ -55,7 +55,7 @@ public class IntermediateDexPerTypeWriter extends DexWriter implements RunnableSchedulable<JDefinedClassOrInterface> { @CheckForNull - private final OutputLibrary outputLibrary = Jack.getSession().getOutputLibrary(); + private final OutputLibrary outputLibrary = Jack.getSession().getJackOutputLibrary(); @CheckForNull protected InputOutputVDir intermediateDexDir = ThreadConfig.get(Options.INTERMEDIATE_DEX_DIR); diff --git a/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java b/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java index b306783..0581fba 100644 --- a/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java +++ b/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java @@ -24,6 +24,7 @@ import com.android.jack.ir.ast.JPackageLookupException; import com.android.jack.ir.ast.JSession; import com.android.jack.ir.ast.JTypeLookupException; import com.android.jack.ir.ast.Resource; +import com.android.jack.library.BinaryKind; import com.android.jack.library.InputJackLibrary; import com.android.jack.library.InputLibrary; import com.android.jack.library.JackLibrary; @@ -69,7 +70,7 @@ public class JayceFileImporter { private static final Logger logger = LoggerFactory.getLogger(); @Nonnull - private final List<InputJackLibrary> inputJackLibraries; + private final List<InputJackLibrary> jackLibraries; private static final char VPATH_SEPARATOR = JLookup.PACKAGE_SEPARATOR; @@ -113,34 +114,34 @@ public class JayceFileImporter { ThreadConfig.get(RESOURCE_COLLISION_POLICY); public JayceFileImporter(@Nonnull List<InputJackLibrary> jackLibraries) { - this.inputJackLibraries = jackLibraries; + this.jackLibraries = jackLibraries; } public void doImport(@Nonnull JSession session) throws JPackageLookupException, ImportConflictException, JTypeLookupException { - for (InputJackLibrary inputJackLibrary : inputJackLibraries) { - InputRootVDir libraryVDir = inputJackLibrary.getInputVDir(); + for (InputJackLibrary jackLibrary : jackLibraries) { + InputRootVDir libraryVDir = jackLibrary.getInputVDir(); logger.log(Level.FINE, "Importing {0}", libraryVDir.getLocation().getDescription()); for (InputVElement subFile : libraryVDir.list()) { - importJayceFile(inputJackLibrary, subFile, session, ""); + importJayceFile(jackLibrary, subFile, session, ""); } } } - private void importJayceFile(@Nonnull InputJackLibrary inputJackLibrary, + private void importJayceFile(@Nonnull InputLibrary inputLibrary, @Nonnull InputVElement element, @Nonnull JSession session, @Nonnull String currentPath) throws JPackageLookupException, TypeImportConflictException, ResourceImportConflictException, JTypeLookupException { String path = currentPath + element.getName(); if (element.isVDir()) { for (InputVElement subFile : ((InputVDir) element).list()) { - importJayceFile(inputJackLibrary, subFile, session, path + VPATH_SEPARATOR); + importJayceFile(inputLibrary, subFile, session, path + VPATH_SEPARATOR); } } else { InputVFile file = (InputVFile) element; if (isJackFileName(file.getName())) { - addImportedTypes(session, path, inputJackLibrary); + addImportedTypes(session, path, inputLibrary); } else { addImportedResource(file, session, path); } @@ -188,8 +189,9 @@ public class JayceFileImporter { private void addImportedResource(@Nonnull InputVFile file, @Nonnull JSession session, @Nonnull String currentPath) throws ResourceImportConflictException { VPath path = new VPath(currentPath, VPATH_SEPARATOR); - // library.properties is not a resource - if (path.equals(JackLibrary.LIBRARY_PROPERTIES_VPATH)) { + // library.properties and dex files are not resources + if (path.equals(JackLibrary.LIBRARY_PROPERTIES_VPATH) || + currentPath.endsWith(BinaryKind.DEX.getFileExtension())) { return; } Resource newResource = new Resource(path, file); diff --git a/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java b/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java index 87d5699..108ce65 100644 --- a/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java +++ b/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java @@ -17,15 +17,15 @@ package com.android.jack.backend.jayce; import com.android.jack.Jack; -import com.android.jack.JackFileException; import com.android.jack.experimental.incremental.CompilerState; import com.android.jack.experimental.incremental.JackIncremental; 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.jayce.JayceWriter; -import com.android.jack.library.OutputLibrary; +import com.android.jack.jayce.JayceWriterFactory; +import com.android.jack.library.LibraryIOException; +import com.android.jack.library.OutputJackLibrary; import com.android.jack.scheduling.feature.JayceFileOutput; import com.android.sched.item.Description; import com.android.sched.item.Name; @@ -56,30 +56,28 @@ import javax.annotation.Nonnull; public class JayceSingleTypeWriter implements RunnableSchedulable<JDefinedClassOrInterface> { @Nonnull - private final OutputLibrary outputLibrary; + private final OutputJackLibrary outputJackLibrary; { - OutputLibrary ol = Jack.getSession().getOutputLibrary(); - assert ol != null; - this.outputLibrary = ol; + OutputJackLibrary ojl = Jack.getSession().getJackOutputLibrary(); + assert ojl != null; + this.outputJackLibrary = ojl; } @Synchronized public boolean needsSynchronization() { - return outputLibrary.needsSequentialWriting(); + return outputJackLibrary.needsSequentialWriting(); } @Override public void run(@Nonnull JDefinedClassOrInterface type) throws Exception { - OutputVFile vFile = outputLibrary.getJayceOutputVFile( + OutputVFile vFile = outputJackLibrary.getJayceOutputVFile( new VPath(BinaryQualifiedNameFormatter.getFormatter().getName(type), '/')); try { OutputStream out = new BufferedOutputStream(vFile.openWrite()); try { - // Write to file - JayceWriter writer = new JayceWriter(out); - writer.write(type, "jack " + Jack.getVersionString()); + JayceWriterFactory.get(outputJackLibrary, out).write(type); if (ThreadConfig.get(JackIncremental.GENERATE_COMPILER_STATE).booleanValue()) { assert vFile instanceof DirectFile; @@ -92,7 +90,7 @@ public class JayceSingleTypeWriter implements RunnableSchedulable<JDefinedClassO out.close(); } } catch (IOException e) { - throw new JackFileException("Could not write Jayce file to output '" + vFile + "'", e); + throw new LibraryIOException(outputJackLibrary.getLocation(), e); } } diff --git a/jack/src/com/android/jack/ir/ast/JSession.java b/jack/src/com/android/jack/ir/ast/JSession.java index 641fee9..20118d0 100644 --- a/jack/src/com/android/jack/ir/ast/JSession.java +++ b/jack/src/com/android/jack/ir/ast/JSession.java @@ -24,7 +24,7 @@ import com.android.jack.ir.ast.JPrimitiveType.JPrimitiveTypeEnum; import com.android.jack.ir.sourceinfo.SourceInfo; import com.android.jack.ir.sourceinfo.SourceInfoFactory; import com.android.jack.library.BinaryKind; -import com.android.jack.library.OutputLibrary; +import com.android.jack.library.OutputJackLibrary; import com.android.jack.lookup.JNodeLookup; import com.android.jack.lookup.JPhantomLookup; import com.android.jack.reporting.Reporter; @@ -89,7 +89,7 @@ public class JSession extends JNode { private final List<BinaryKind> generatedBinaryKinds = new ArrayList<BinaryKind>(1); @CheckForNull - private OutputLibrary outputLibrary; + private OutputJackLibrary jackOutputLibrary; @Nonnull private final List<InputRootVDir> importSources = new ArrayList<InputRootVDir>(0); @@ -201,12 +201,12 @@ public class JSession extends JNode { } @CheckForNull - public OutputLibrary getOutputLibrary() { - return outputLibrary; + public OutputJackLibrary getJackOutputLibrary() { + return jackOutputLibrary; } - public void setOutputLibrary(@Nonnull OutputLibrary outputLibrary) { - this.outputLibrary = outputLibrary; + public void setJackOutputLibrary(@Nonnull OutputJackLibrary jackOutputLibrary) { + this.jackOutputLibrary = jackOutputLibrary; } @Nonnull diff --git a/jack/src/com/android/jack/jayce/JayceClassOrInterfaceLoader.java b/jack/src/com/android/jack/jayce/JayceClassOrInterfaceLoader.java index d859f78..c500412 100644 --- a/jack/src/com/android/jack/jayce/JayceClassOrInterfaceLoader.java +++ b/jack/src/com/android/jack/jayce/JayceClassOrInterfaceLoader.java @@ -17,7 +17,7 @@ package com.android.jack.jayce; import com.android.jack.Jack; -import com.android.jack.JackFileException; +import com.android.jack.LibraryException; import com.android.jack.frontend.ParentSetter; import com.android.jack.ir.ast.JDefinedAnnotation; import com.android.jack.ir.ast.JDefinedClassOrInterface; @@ -153,10 +153,7 @@ public class JayceClassOrInterfaceLoader extends AbtractClassOrInterfaceLoader i @Nonnull JDefinedClassOrInterface load() throws JayceFormatException, JayceVersionException, IOException { - - DeclaredTypeNode type = - getNNode(NodeLevel.TYPES, enclosingPackage.getSession().getUserLogger()); - + DeclaredTypeNode type = getNNode(NodeLevel.TYPES); String expectedSignature = Jack.getLookupFormatter().getName(enclosingPackage, simpleName); if (!type.getSignature().equals(expectedSignature)) { throw new JayceFormatException("Wrong type in '" + source + "', found '" @@ -169,9 +166,7 @@ public class JayceClassOrInterfaceLoader extends AbtractClassOrInterfaceLoader i @Nonnull private JDefinedClassOrInterface create(@Nonnull JSession session) throws JayceFormatException, JayceVersionException, IOException { - - DeclaredTypeNode type = getNNode(NodeLevel.TYPES, session.getUserLogger()); - + DeclaredTypeNode type = getNNode(NodeLevel.TYPES); String packageQualifiedName = NamingTools.getPackageNameFromBinaryName( NamingTools.getClassBinaryNameFromDescriptor(type.getSignature())); JPackage pack = session.getLookup().getOrCreatePackage(packageQualifiedName); @@ -180,18 +175,17 @@ public class JayceClassOrInterfaceLoader extends AbtractClassOrInterfaceLoader i } @Nonnull - DeclaredTypeNode getNNode(@Nonnull NodeLevel minimumLevel, @Nonnull Logger userLogger) + DeclaredTypeNode getNNode(@Nonnull NodeLevel minimumLevel) throws IOException, JayceFormatException, JayceVersionException { DeclaredTypeNode type = nnode.get(); if (type == null || !type.getLevel().keep(minimumLevel)) { InputStream in = new BufferedInputStream(source.openRead()); try { - JayceReader reader = new JayceReader(in, userLogger); NodeLevel loadLevel = defaultLoadLevel; if (!loadLevel.keep(minimumLevel)) { loadLevel = minimumLevel; } - type = reader.readType(loadLevel); + type = JayceReaderFactory.get(inputJackLibrary, in).readType(loadLevel); nnode = new SoftReference<DeclaredTypeNode>(type); } finally { try { @@ -213,10 +207,10 @@ public class JayceClassOrInterfaceLoader extends AbtractClassOrInterfaceLoader i structureLoaded = true; DeclaredTypeNode type; try { - type = getNNode(NodeLevel.STRUCTURE, loaded.getSession().getUserLogger()); + type = getNNode(NodeLevel.STRUCTURE); } catch (IOException e) { throw new JackLoadingException(getLocation(), e); - } catch (JackFileException e) { + } catch (LibraryException e) { throw new JackLoadingException(getLocation(), e); } try { diff --git a/jack/src/com/android/jack/jayce/JayceFormatException.java b/jack/src/com/android/jack/jayce/JayceFormatException.java index a9f5aec..2ea1027 100644 --- a/jack/src/com/android/jack/jayce/JayceFormatException.java +++ b/jack/src/com/android/jack/jayce/JayceFormatException.java @@ -16,14 +16,14 @@ package com.android.jack.jayce; -import com.android.jack.JackFileException; +import com.android.jack.JayceException; import javax.annotation.Nonnull; /** * Exception representing a problem related to Jayce files format. */ -public class JayceFormatException extends JackFileException { +public class JayceFormatException extends JayceException { private static final long serialVersionUID = 1L; diff --git a/jack/src/com/android/jack/jayce/JayceMethodLoader.java b/jack/src/com/android/jack/jayce/JayceMethodLoader.java index 86d45fd..43c897a 100644 --- a/jack/src/com/android/jack/jayce/JayceMethodLoader.java +++ b/jack/src/com/android/jack/jayce/JayceMethodLoader.java @@ -16,7 +16,7 @@ package com.android.jack.jayce; -import com.android.jack.JackFileException; +import com.android.jack.LibraryException; import com.android.jack.ir.ast.JMethod; import com.android.jack.ir.ast.JNode; import com.android.jack.library.HasInputLibrary; @@ -66,7 +66,7 @@ public class JayceMethodLoader extends AbstractMethodLoader implements HasInputL MethodNode methodNode; try { methodNode = getNNode(loaded); - } catch (JackFileException e) { + } catch (LibraryException e) { throw new JackLoadingException(getLocation(loaded), e); } catch (IOException e) { throw new JackLoadingException(getLocation(loaded), e); @@ -96,8 +96,7 @@ public class JayceMethodLoader extends AbstractMethodLoader implements HasInputL JayceVersionException, IOException { MethodNode methodNode = nnode.get(); if (methodNode == null || methodNode.getLevel() != NodeLevel.FULL) { - DeclaredTypeNode declaredTypeNode = enclosingClassLoader.getNNode(NodeLevel.FULL, - loaded.getEnclosingType().getSession().getUserLogger()); + DeclaredTypeNode declaredTypeNode = enclosingClassLoader.getNNode(NodeLevel.FULL); methodNode = declaredTypeNode.getMethodNode(loaded); } return methodNode; diff --git a/jack/src/com/android/jack/jayce/JaycePackageLoader.java b/jack/src/com/android/jack/jayce/JaycePackageLoader.java index 7101e41..9ad6c3f 100644 --- a/jack/src/com/android/jack/jayce/JaycePackageLoader.java +++ b/jack/src/com/android/jack/jayce/JaycePackageLoader.java @@ -16,7 +16,6 @@ package com.android.jack.jayce; -import com.android.jack.JackFileException; import com.android.jack.backend.jayce.JayceFileImporter; import com.android.jack.ir.ast.JDefinedClassOrInterface; import com.android.jack.ir.ast.JPackage; @@ -25,10 +24,12 @@ import com.android.jack.ir.ast.MissingJTypeLookupException; import com.android.jack.library.HasInputLibrary; import com.android.jack.library.InputJackLibrary; import com.android.jack.library.InputLibrary; +import com.android.jack.library.LibraryFormatException; import com.android.jack.load.JackLoadingException; import com.android.jack.load.PackageLoader; import com.android.jack.lookup.JPhantomLookup; import com.android.sched.util.location.Location; +import com.android.sched.util.log.LoggerFactory; import com.android.sched.vfs.InputVDir; import com.android.sched.vfs.InputVElement; import com.android.sched.vfs.InputVFile; @@ -37,6 +38,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nonnull; @@ -46,6 +49,9 @@ import javax.annotation.Nonnull; public class JaycePackageLoader implements PackageLoader, HasInputLibrary { @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + @Nonnull private final InputVDir dir; @Nonnull @@ -80,8 +86,20 @@ public class JaycePackageLoader implements PackageLoader, HasInputLibrary { defaultLoadLevel).load(); } catch (IOException e) { throw new JackLoadingException(sub.getLocation(), e); - } catch (JackFileException e) { - throw new JackLoadingException(sub.getLocation() , e); + } catch (LibraryFormatException e) { + throw new JackLoadingException(sub.getLocation(), e); + } catch (JayceFormatException e) { + logger.log(Level.SEVERE, + "Library " + inputJackLibrary.getLocation().getDescription() + " is invalid", + e); + throw new JackLoadingException(sub.getLocation(), + new LibraryFormatException(inputJackLibrary.getLocation())); + } catch (JayceVersionException e) { + logger.log(Level.SEVERE, + "Library " + inputJackLibrary.getLocation().getDescription() + " is invalid", + e); + throw new JackLoadingException(sub.getLocation(), + new LibraryFormatException(inputJackLibrary.getLocation())); } } } diff --git a/jack/src/com/android/jack/jayce/JayceProcessor.java b/jack/src/com/android/jack/jayce/JayceProcessor.java index d1b94b3..2e532cf 100644 --- a/jack/src/com/android/jack/jayce/JayceProcessor.java +++ b/jack/src/com/android/jack/jayce/JayceProcessor.java @@ -27,7 +27,7 @@ import javax.annotation.Nonnull; public class JayceProcessor { @Nonnull - protected Object instantiateConstructorWithParameters(@Nonnull String className, + protected static Object instantiateConstructorWithParameters(@Nonnull String className, @Nonnull Class<?>[] parameterTypes, @Nonnull Object[] parameterInstances, @Nonnull String version) throws JayceVersionException { diff --git a/jack/src/com/android/jack/jayce/JayceProperties.java b/jack/src/com/android/jack/jayce/JayceProperties.java new file mode 100644 index 0000000..f5421e4 --- /dev/null +++ b/jack/src/com/android/jack/jayce/JayceProperties.java @@ -0,0 +1,33 @@ +/* + * 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.jayce; + +import javax.annotation.Nonnull; + +/** + * Properties related to Jayce files. + */ +public interface JayceProperties { + + @Nonnull + public static final String KEY_JAYCE = "jayce"; + @Nonnull + public static final String KEY_JAYCE_MAJOR_VERSION = "jayce.version.major"; + @Nonnull + public static final String KEY_JAYCE_MINOR_VERSION = "jayce.version.minor"; + +} diff --git a/jack/src/com/android/jack/jayce/JayceReader.java b/jack/src/com/android/jack/jayce/JayceReader.java deleted file mode 100644 index 17f14b3..0000000 --- a/jack/src/com/android/jack/jayce/JayceReader.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.android.jack.jayce; -/* - * 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. - */ - - - -import java.io.IOException; -import java.io.InputStream; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -/** - * A reader of Jayce streams. - */ -public class JayceReader extends JayceProcessor { - - @Nonnull - private final InputStream in; - @CheckForNull - private JayceInternalReader jayceInternalReader; - @CheckForNull - private NodeLevel nodeLevel; - @Nonnull - private static final String UNKNOWN_VERSION_STRING = "UNKNOWN"; - - private static final int UNKNOWN_VERSION = -1; - - private int majorVersion = UNKNOWN_VERSION; - - private int minorVersion = UNKNOWN_VERSION; - @Nonnull - private final String readerClassName; - @CheckForNull - private final String emitterId; - @Nonnull - private final Logger userLogger; - - public JayceReader(@Nonnull InputStream in, @Nonnull Logger userLogger) - throws IOException, JayceFormatException { - this.in = in; - JayceHeader jayceHeader = new JayceHeader(in); - String majorVersionString = jayceHeader.getMajorVersionString(); - majorVersion = jayceHeader.getMajorVersion(); - minorVersion = jayceHeader.getMinorVersion(); - emitterId = jayceHeader.getEmitterId(); - readerClassName = - "com.android.jack.jayce.v" + majorVersionString + ".io.JayceInternalReaderImpl"; - this.userLogger = userLogger; - } - - /** - * Reads type from a Jayce stream as a {@link Node}. - * - * @param nodeLevel the level of the wanted node - * @return the node representing the types found in the jayce stream. - * @throws IOException thrown when there is an issue reading the stream - * @throws JayceFormatException thrown if the Jayce stream has an invalid format - * @throws JayceVersionException thrown if the version of the Jayce stream is not supported - */ - public DeclaredTypeNode readType(@Nonnull NodeLevel nodeLevel) - throws IOException, JayceFormatException, JayceVersionException { - if (jayceInternalReader == null) { - initialize(nodeLevel); - } - assert jayceInternalReader != null; - assert this.nodeLevel == nodeLevel; - return jayceInternalReader.readType(nodeLevel); - - } - private void initialize(@Nonnull NodeLevel nodeLevel) throws JayceVersionException { - - jayceInternalReader = (JayceInternalReader) instantiateConstructorWithParameters( - readerClassName, new Class[] {InputStream.class}, - new Object[] {in}, majorVersion + "." + minorVersion); - int minorMin = jayceInternalReader.getMinorMin(); - int currentMinor = jayceInternalReader.getCurrentMinor(); - if (minorVersion < minorMin) { - throw new JayceVersionException("The version of the jayce file is not supported anymore." - + "File version: " + majorVersion + "." + minorVersion + " - Current version: " - + majorVersion + "." + currentMinor + - " - Minimum compatible version: " + majorVersion + "." + minorMin); - } else if (minorVersion > currentMinor) { - throw new JayceVersionException("The version of the jayce file is too recent." - + "File version: " + majorVersion + "." + minorVersion + " - Current version: " - + majorVersion + "." + currentMinor); - } else if (minorVersion < currentMinor) { - userLogger.log(Level.WARNING, - "The version of the jayce file is older than the current version but should be" - + "supported. File version: {0}.{1} - Current version: {2}.{3}", new Object[] { - Integer.valueOf(majorVersion), Integer.valueOf(minorVersion), - Integer.valueOf(majorVersion), Integer.valueOf(currentMinor)}); - } - this.nodeLevel = nodeLevel; - } - - @Nonnull - public String getVersionString() { - if (majorVersion != UNKNOWN_VERSION && minorVersion != UNKNOWN_VERSION) { - return majorVersion + "." + minorVersion; - } else { - return UNKNOWN_VERSION_STRING; - } - } - - @Nonnull - public String getEmitterId() { - if (emitterId != null) { - return emitterId; - } else { - return UNKNOWN_VERSION_STRING; - } - } - -} diff --git a/jack/src/com/android/jack/jayce/JayceReaderFactory.java b/jack/src/com/android/jack/jayce/JayceReaderFactory.java new file mode 100644 index 0000000..6976e77 --- /dev/null +++ b/jack/src/com/android/jack/jayce/JayceReaderFactory.java @@ -0,0 +1,114 @@ +/* + * 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.jayce; + +import com.android.jack.Jack; +import com.android.jack.JackAbortException; +import com.android.jack.library.InputJackLibrary; +import com.android.jack.library.JackLibraryFactory; +import com.android.jack.library.LibraryFormatException; +import com.android.jack.library.LibraryReadingException; +import com.android.jack.reporting.ReportableException; +import com.android.jack.reporting.Reporter.Severity; +import com.android.sched.util.log.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Nonnull; + +/** + * A factory of {@link JayceInternalReader}. + */ +public abstract class JayceReaderFactory extends JayceProcessor { + + @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + @Nonnull + public static JayceInternalReader get(@Nonnull InputJackLibrary inputJackLibrary, + @Nonnull InputStream in) throws LibraryFormatException { + String majorVersionStr = inputJackLibrary.getProperty(JayceProperties.KEY_JAYCE_MAJOR_VERSION); + String minorVersionStr = inputJackLibrary.getProperty(JayceProperties.KEY_JAYCE_MINOR_VERSION); + + int majorVersion; + int minorVersion; + + try { + majorVersion = Integer.parseInt(majorVersionStr); + } catch (NumberFormatException e) { + logger.log(Level.SEVERE, "Failed to parse the property " + + JayceProperties.KEY_JAYCE_MAJOR_VERSION + " from " + + inputJackLibrary.getLocation().getDescription(), e); + throw new LibraryFormatException(inputJackLibrary.getLocation()); + } + + try { + minorVersion = Integer.parseInt(minorVersionStr); + } catch (NumberFormatException e) { + logger.log(Level.SEVERE, "Failed to parse the property " + + JayceProperties.KEY_JAYCE_MINOR_VERSION + " from " + + inputJackLibrary.getLocation().getDescription(), e); + throw new LibraryFormatException(inputJackLibrary.getLocation()); + } + + String className = "com.android.jack.jayce.v" + + JackLibraryFactory.getVersionString(majorVersion) + ".io.JayceInternalReaderImpl"; + + JayceInternalReader jayceReader = (JayceInternalReader) instantiateConstructorWithParameters( + className, new Class[] {InputStream.class}, new Object[] {in}, majorVersionStr); + + + int minorMin = jayceReader.getMinorMin(); + int currentMinor = jayceReader.getCurrentMinor(); + if (minorVersion < minorMin) { + throw new JayceVersionException("The version of the jayce file is not supported anymore." + + "File version: " + majorVersionStr + "." + minorVersion + " - Current version: " + + majorVersionStr + "." + currentMinor + " - Minimum compatible version: " + + majorVersionStr + "." + minorMin); + } else if (minorVersion > currentMinor) { + throw new JayceVersionException("The version of the jayce file is too recent." + + "File version: " + majorVersionStr + "." + minorVersion + " - Current version: " + + majorVersionStr + "." + currentMinor); + } else if (minorVersion < currentMinor) { + Jack.getSession().getUserLogger().log(Level.WARNING, + "The version of the jayce file is older than the current version but is " + + "supported. File version: {0}.{1} - Current version: {2}.{3}", new Object[] { + Integer.valueOf(majorVersionStr), Integer.valueOf(minorVersion), + Integer.valueOf(majorVersionStr), Integer.valueOf(currentMinor)}); + } + + if (Integer.parseInt(majorVersionStr) == 2 && minorVersion == 14) { + // Read jayce file header, after jayce version 2.14, header does no longer exists it was moved + // to jack library properties + try { + new JayceHeader(in); + } catch (JayceFormatException e) { + logger.log(Level.SEVERE, + "Library " + inputJackLibrary.getLocation().getDescription() + " is invalid", e); + throw new LibraryFormatException(inputJackLibrary.getLocation()); + } catch (IOException e) { + ReportableException exceptionToReport = new LibraryReadingException(e); + Jack.getSession().getReporter().report(Severity.FATAL, exceptionToReport); + throw new JackAbortException(exceptionToReport); + } + } + return jayceReader; + } +} diff --git a/jack/src/com/android/jack/jayce/JayceVersionException.java b/jack/src/com/android/jack/jayce/JayceVersionException.java index 8325e81..d0c32a6 100644 --- a/jack/src/com/android/jack/jayce/JayceVersionException.java +++ b/jack/src/com/android/jack/jayce/JayceVersionException.java @@ -16,14 +16,14 @@ package com.android.jack.jayce; -import com.android.jack.JackFileException; +import com.android.jack.JayceException; import javax.annotation.Nonnull; /** * Exception representing a problem related to Jayce files version. */ -public class JayceVersionException extends JackFileException { +public class JayceVersionException extends JayceException { private static final long serialVersionUID = 1L; diff --git a/jack/src/com/android/jack/jayce/JayceWriter.java b/jack/src/com/android/jack/jayce/JayceWriter.java deleted file mode 100644 index c2c998c..0000000 --- a/jack/src/com/android/jack/jayce/JayceWriter.java +++ /dev/null @@ -1,97 +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.jayce; - -import com.android.jack.JackEventType; -import com.android.jack.ir.ast.JNode; -import com.android.sched.util.log.Event; -import com.android.sched.util.log.Tracer; -import com.android.sched.util.log.TracerFactory; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.annotation.Nonnull; - -/** - * A writer of Jayce streams. - */ -public class JayceWriter extends JayceProcessor { - - public static final int DEFAULT_MAJOR_VERSION = 2; - - @Nonnull - private static final Tracer tracer = TracerFactory.getTracer(); - - @Nonnull - private final OutputStream out; - - public JayceWriter(@Nonnull OutputStream out) { - this.out = out; - } - - /** - * Write a {@link JNode} as a Jayce stream. - * - * @param jNode the node to write as a Jayce stream - * @param emitterId the identifier of the emitter - * @throws IOException thrown when there is an issue writing the stream - * @throws JayceFormatException thrown if the Jayce stream has an invalid format - * @throws JayceVersionException thrown if the version of the Jayce stream is not supported - */ - public void write( - @Nonnull JNode jNode, @Nonnull String emitterId) - throws IOException, JayceFormatException, JayceVersionException { - write(jNode, emitterId, DEFAULT_MAJOR_VERSION); - } - - /** - * Write a {@link JNode} as a Jayce stream. - * - * @param jNode the node to write as a Jayce stream - * @param emitterId the identifier of the emitter - * @param majorVersion major version number of the Jayce format to use - * @throws IOException thrown when there is an issue writing the stream - * @throws JayceFormatException thrown if the Jayce stream has an invalid format - * @throws JayceVersionException thrown if the version of the Jayce stream is not supported - */ - public void write( - @Nonnull JNode jNode, @Nonnull String emitterId, int majorVersion) - throws IOException, JayceFormatException, JayceVersionException { - - String majorVersionString = JayceHeader.getVersionString(majorVersion); - - String className = - "com.android.jack.jayce.v" + majorVersionString + ".io.JayceInternalWriterImpl"; - JayceInternalWriter jayceInternalWriter = - (JayceInternalWriter) instantiateConstructorWithParameters(className, - new Class[] {OutputStream.class}, new Object[] {out}, - String.valueOf(majorVersion)); - int currentMinor = jayceInternalWriter.getCurrentMinor(); - JayceHeader jayceHeader = new JayceHeader(majorVersion, currentMinor, emitterId); - - Event event = tracer.start(JackEventType.NNODE_WRITING); - - try { - jayceHeader.writeHeader(out); - jayceInternalWriter.write(jNode); - out.flush(); - } finally { - event.end(); - } - } -} diff --git a/jack/src/com/android/jack/jayce/JayceWriterFactory.java b/jack/src/com/android/jack/jayce/JayceWriterFactory.java new file mode 100644 index 0000000..da4e35c --- /dev/null +++ b/jack/src/com/android/jack/jayce/JayceWriterFactory.java @@ -0,0 +1,46 @@ +/* + * 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.jayce; + +import com.android.jack.jayce.v0002.io.JayceInternalWriterImpl; +import com.android.jack.library.OutputJackLibrary; + +import java.io.OutputStream; + +import javax.annotation.Nonnull; + +/** + * {@link JayceInternalWriter} Factory. + */ +public abstract class JayceWriterFactory extends JayceProcessor { + + public static final int DEFAULT_MAJOR_VERSION = 2; + + @Nonnull + public static JayceInternalWriter get(@Nonnull OutputJackLibrary outputJackLibrary, + @Nonnull OutputStream out) { + JayceInternalWriterImpl jayceWriter = new JayceInternalWriterImpl(out); + + outputJackLibrary.putProperty(JayceProperties.KEY_JAYCE, String.valueOf(true)); + outputJackLibrary.putProperty(JayceProperties.KEY_JAYCE_MAJOR_VERSION, + String.valueOf(DEFAULT_MAJOR_VERSION)); + outputJackLibrary.putProperty(JayceProperties.KEY_JAYCE_MINOR_VERSION, + String.valueOf(jayceWriter.getCurrentMinor())); + + return jayceWriter; + } +} diff --git a/jack/src/com/android/jack/jayce/v0002/Version.java b/jack/src/com/android/jack/jayce/v0002/Version.java index df11e0b..8a3d7e2 100644 --- a/jack/src/com/android/jack/jayce/v0002/Version.java +++ b/jack/src/com/android/jack/jayce/v0002/Version.java @@ -23,5 +23,5 @@ public class Version { public static final int MINOR_MIN = 14; - public static final int CURRENT_MINOR = 14; + public static final int CURRENT_MINOR = 15; } diff --git a/jack/src/com/android/jack/jayce/v0002/io/JayceInternalWriterImpl.java b/jack/src/com/android/jack/jayce/v0002/io/JayceInternalWriterImpl.java index 69a2001..5155a86 100644 --- a/jack/src/com/android/jack/jayce/v0002/io/JayceInternalWriterImpl.java +++ b/jack/src/com/android/jack/jayce/v0002/io/JayceInternalWriterImpl.java @@ -323,15 +323,21 @@ public class JayceInternalWriterImpl implements JayceInternalWriter { @Override public void write(@Nonnull JNode jNode) throws IOException { - ImportHelper importHelper = new ImportHelper(new NodeFactory()); - Event event = tracer.start(JackEventType.JNODE_TO_NNODE_CONVERSION); - NNode nNode; + Event eventWriting = tracer.start(JackEventType.NNODE_WRITING); try { - nNode = importHelper.load(jNode); + ImportHelper importHelper = new ImportHelper(new NodeFactory()); + Event eventConvert = tracer.start(JackEventType.JNODE_TO_NNODE_CONVERSION); + NNode nNode; + try { + nNode = importHelper.load(jNode); + } finally { + eventConvert.end(); + } + + writeNode(nNode); } finally { - event.end(); + eventWriting.end(); } - writeNode(nNode); } @Override diff --git a/jack/src/com/android/jack/library/CommonJackLibrary.java b/jack/src/com/android/jack/library/CommonJackLibrary.java new file mode 100644 index 0000000..9725c59 --- /dev/null +++ b/jack/src/com/android/jack/library/CommonJackLibrary.java @@ -0,0 +1,56 @@ +/* + * 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.library; + +import com.android.sched.util.log.LoggerFactory; + +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Nonnull; + +/** + * Common part of {@link InputLibrary} and {@link OutputLibrary} + */ +public abstract class CommonJackLibrary implements JackLibrary { + + @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + @Nonnull + protected final Properties libraryProperties; + + public CommonJackLibrary(@Nonnull Properties libraryProperties) { + this.libraryProperties = libraryProperties; + } + + @Nonnull + @Override + public String getProperty(@Nonnull String key) throws LibraryFormatException { + if (!libraryProperties.containsKey(key)) { + logger.log(Level.SEVERE, + "Property " + key + " from the library " + getLocation() + " does not exist"); + throw new LibraryFormatException(getLocation()); + } + return (String) libraryProperties.get(key); + } + + public void putProperty(@Nonnull String key, @Nonnull String value) { + libraryProperties.put(key, value); + } +} diff --git a/jack/src/com/android/jack/library/InputJackLibrary.java b/jack/src/com/android/jack/library/InputJackLibrary.java index a745942..7950495 100644 --- a/jack/src/com/android/jack/library/InputJackLibrary.java +++ b/jack/src/com/android/jack/library/InputJackLibrary.java @@ -17,132 +17,54 @@ package com.android.jack.library; import com.android.jack.Jack; -import com.android.sched.util.file.NotFileOrDirectoryException; -import com.android.sched.vfs.InputRootVDir; -import com.android.sched.vfs.InputVDir; -import com.android.sched.vfs.InputVElement; -import com.android.sched.vfs.InputVFile; -import com.android.sched.vfs.VPath; +import com.android.jack.LibraryException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.Properties; +import java.util.logging.Level; import javax.annotation.Nonnull; + /** - * Jack library used as input. + * Interface representing an input jack library. */ -public class InputJackLibrary implements InputLibrary, JackLibrary { - - @Nonnull - private final InputRootVDir libraryVDir; - - @Nonnull - private final InputLibraryLocation location = new InputLibraryLocation() { - - @Override - @Nonnull - public String getDescription() { - return libraryVDir.getLocation().getDescription(); - } - - @Override - public int hashCode() { - return InputJackLibrary.this.hashCode(); - } - - @Override - @Nonnull - public InputLibrary getInputLibrary() { - return InputJackLibrary.this; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof InputLibraryLocation - && ((InputLibraryLocation) obj).getInputLibrary().equals(getInputLibrary()); - } - }; - - @Nonnull - private final Set<BinaryKind> binaryKinds = new HashSet<BinaryKind>(1); - - public InputJackLibrary(@Nonnull InputRootVDir libraryVDir) { - this.libraryVDir = libraryVDir; - fillBinaryKinds(libraryVDir); - } - - @Override - @Nonnull - public InputLibraryLocation getLocation() { - return location; - } - - @Override - @Nonnull - public Collection<BinaryKind> getBinaryKinds() { - return Jack.getUnmodifiableCollections().getUnmodifiableCollection(binaryKinds); - } - - @Override - public boolean hasBinary(@Nonnull BinaryKind binaryKind) { - return binaryKinds.contains(binaryKind); - } +public abstract class InputJackLibrary extends CommonJackLibrary implements InputLibrary { - @Override - @Nonnull - public List<InputVFile> getBinaries(@Nonnull BinaryKind binaryKind) { - List<InputVFile> binaries = new ArrayList<InputVFile>(); - fillBinaries(libraryVDir, binaryKind, binaries); - return binaries; + public InputJackLibrary(@Nonnull Properties libraryProperties) throws LibraryException { + super(libraryProperties); + check(); } - @Override - @Nonnull - public InputVFile getBinary(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) - throws BinaryDoesNotExistException { - try { - return libraryVDir.getInputVFile( - new VPath(typePath.getPathAsString('/') + BinaryKind.DEX.getFileExtension(), '/')); - } catch (NotFileOrDirectoryException e) { - throw new BinaryDoesNotExistException(getLocation(), typePath, binaryKind); + private void check() throws LibraryException { + getProperty(JackLibrary.KEY_LIB_EMITTER); + getProperty(JackLibrary.KEY_LIB_EMITTER_VERSION); + getProperty(JackLibrary.KEY_LIB_MAJOR_VERSION); + getProperty(JackLibrary.KEY_LIB_MINOR_VERSION); + + int majorVersion = getMajorVersion(); + int minorVersion = getMinorVersion(); + int supportedMinorMin = getSupportedMinorMin(); + int supportedMinor = getSupportedMinor(); + + if (minorVersion < supportedMinorMin) { + throw new LibraryVersionException("The version of the library file is not supported anymore." + + "Library version: " + majorVersion + "." + minorVersion + " - Current version: " + + majorVersion + "." + supportedMinor + " - Minimum compatible version: " + majorVersion + + "." + supportedMinorMin); + } else if (minorVersion > supportedMinor) { + throw new LibraryVersionException("The version of the library file is too recent." + + "Library version: " + majorVersion + "." + minorVersion + " - Current version: " + + majorVersion + "." + supportedMinor); + } else if (minorVersion < supportedMinor) { + Jack.getSession().getUserLogger().log(Level.WARNING, + "The version of the library is older than the current version but is " + + "supported. File version: {0}.{1} - Current version: {2}.{3}", new Object[] { + Integer.valueOf(majorVersion), Integer.valueOf(minorVersion), + Integer.valueOf(majorVersion), Integer.valueOf(supportedMinor)}); } } - @Override - @Nonnull - public InputRootVDir getInputVDir() { - return libraryVDir; - } - - private void fillBinaryKinds(@Nonnull InputVDir vDir) { - for (InputVElement subFile : vDir.list()) { - if (subFile.isVDir()) { - fillBinaryKinds((InputVDir) subFile); - } else { - try { - binaryKinds.add(BinaryKind.getBinaryKind((InputVFile) subFile)); - } catch (NotBinaryException e) { - // Ok, nothing to do - } - } - } - } + public abstract int getSupportedMinor(); - private void fillBinaries(@Nonnull InputVDir vDir, @Nonnull BinaryKind binaryKind, - @Nonnull List<InputVFile> binaries) { - for (InputVElement subFile : vDir.list()) { - if (subFile.isVDir()) { - fillBinaries((InputVDir) subFile, binaryKind, binaries); - } else { - InputVFile vFile = (InputVFile) subFile; - if (binaryKind.isBinaryFile(vFile)) { - binaries.add(vFile); - } - } - } - } + public abstract int getSupportedMinorMin(); } diff --git a/jack/src/com/android/jack/library/InputLibrary.java b/jack/src/com/android/jack/library/InputLibrary.java index 5c81e65..23738f1 100644 --- a/jack/src/com/android/jack/library/InputLibrary.java +++ b/jack/src/com/android/jack/library/InputLibrary.java @@ -16,7 +16,6 @@ package com.android.jack.library; -import com.android.sched.util.location.HasLocation; import com.android.sched.vfs.InputRootVDir; import com.android.sched.vfs.InputVFile; import com.android.sched.vfs.VPath; @@ -29,7 +28,7 @@ import javax.annotation.Nonnull; /** * Library used as input. */ -public interface InputLibrary extends HasLocation { +public interface InputLibrary extends Library { @Nonnull public InputRootVDir getInputVDir(); @@ -45,4 +44,8 @@ public interface InputLibrary extends HasLocation { @Nonnull public InputVFile getBinary(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) throws BinaryDoesNotExistException; + + @Override + @Nonnull + public InputLibraryLocation getLocation(); } diff --git a/jack/src/com/android/jack/library/JackLibrary.java b/jack/src/com/android/jack/library/JackLibrary.java index 5b1fd1a..b85a8a1 100644 --- a/jack/src/com/android/jack/library/JackLibrary.java +++ b/jack/src/com/android/jack/library/JackLibrary.java @@ -20,36 +20,30 @@ import com.android.sched.vfs.VPath; import javax.annotation.Nonnull; + /** * Common interface for Jack libraries used as input and as output. */ -public interface JackLibrary { +public interface JackLibrary extends Library { @Nonnull - public static final String KEY_LIB_MAJOR_VERSION = "lib.version.major"; - - @Nonnull - public static final String KEY_LIB_MINOR_VERSION = "lib.version.minor"; - - @Nonnull - public static final String KEY_LIB_EMITTER = "lib.emitter"; + public static final String LIBRARY_PROPERTIES = "jack.properties"; @Nonnull - public static final String KEY_LIB_EMITTER_VERSION = "lib.emitter.version"; + public static final VPath LIBRARY_PROPERTIES_VPATH = new VPath(LIBRARY_PROPERTIES, '/'); @Nonnull - public static final String KEY_JAYCE = "jayce"; + public static final String KEY_LIB_MAJOR_VERSION = "lib.version.major"; @Nonnull - public static final String KEY_JAYCE_MAJOR_VERSION = "jayce.version.major"; + public static final String KEY_LIB_MINOR_VERSION = "lib.version.minor"; @Nonnull - public static final String KEY_JAYCE_MINOR_VERSION = "jayce.version.minor"; + public static final String KEY_LIB_EMITTER = "lib.emitter"; @Nonnull - public static final String LIBRARY_PROPERTIES = "jack.properties"; + public static final String KEY_LIB_EMITTER_VERSION = "lib.emitter.version"; @Nonnull - public static final VPath LIBRARY_PROPERTIES_VPATH = new VPath(LIBRARY_PROPERTIES, '/'); - + public String getProperty(@Nonnull String key) throws LibraryFormatException; } diff --git a/jack/src/com/android/jack/library/JackLibraryFactory.java b/jack/src/com/android/jack/library/JackLibraryFactory.java new file mode 100644 index 0000000..93bb6f5 --- /dev/null +++ b/jack/src/com/android/jack/library/JackLibraryFactory.java @@ -0,0 +1,132 @@ +/* + * 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.library; + +import com.android.jack.LibraryException; +import com.android.jack.library.v0001.OutputJackLibraryImpl; +import com.android.sched.util.log.LoggerFactory; +import com.android.sched.vfs.InputRootVDir; +import com.android.sched.vfs.InputVFile; +import com.android.sched.vfs.OutputVDir; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + +/** + * Factory to instantiate {@link JackLibrary}. + */ +public abstract class JackLibraryFactory { + + @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + public static final int DEFAULT_MAJOR_VERSION = 1; + + @Nonnull + private static final String VERSION_FORMAT = "%04d"; + + @Nonnull + public static String getVersionString(@Nonnegative int version) { + return String.format(VERSION_FORMAT, Integer.valueOf(version)); + } + + @Nonnull + public static InputJackLibrary getInputLibrary(@Nonnull InputRootVDir vdir) + throws LibraryException { + Properties libraryProperties = loadLibraryProperties(vdir); + String majorVersion = getMajorVersionAsString(vdir, libraryProperties); + + InputJackLibrary inputJackLibrary = (InputJackLibrary) instantiateConstructorWithParameters( + vdir, "com.android.jack.library.v" + majorVersion + ".InputJackLibraryImpl", + new Class[] {InputRootVDir.class, Properties.class}, new Object[] {vdir, libraryProperties}, + String.valueOf(majorVersion)); + + return inputJackLibrary; + } + + @Nonnull + public static OutputJackLibrary getOutputLibrary(@Nonnull OutputVDir vdir, + @Nonnull String emitterId, @Nonnull String emitterVersion) { + return new OutputJackLibraryImpl(vdir, emitterId, emitterVersion); + } + + private static String getMajorVersionAsString(@Nonnull InputRootVDir vdir, + @Nonnull Properties libraryProperties) throws LibraryFormatException { + try { + return (getVersionString( + Integer.parseInt((String) libraryProperties.get(JackLibrary.KEY_LIB_MAJOR_VERSION)))); + } catch (NumberFormatException e) { + logger.log(Level.SEVERE, "Fails to parse the property " + JackLibrary.KEY_LIB_MAJOR_VERSION + + " from the library " + vdir, e); + throw new LibraryFormatException(vdir.getLocation()); + } + } + + @Nonnull + private static Properties loadLibraryProperties(@Nonnull InputRootVDir vdir) + throws NotJackLibraryException { + Properties libraryProperties = new Properties(); + + try { + InputVFile libProp = vdir.getInputVFile(JackLibrary.LIBRARY_PROPERTIES_VPATH); + libraryProperties.load(libProp.openRead()); + } catch (IOException e) { + logger.log(Level.SEVERE, "Fails to read " + + JackLibrary.LIBRARY_PROPERTIES_VPATH.getPathAsString('/') + " from " + + vdir, e); + throw new NotJackLibraryException(vdir.getLocation()); + } + + return libraryProperties; + } + + @Nonnull + private static Object instantiateConstructorWithParameters(@Nonnull InputRootVDir vdir, + @Nonnull String className, @Nonnull Class<?>[] parameterTypes, + @Nonnull Object[] parameterInstances, @Nonnull String version) + throws LibraryVersionException { + Object constructorInstance = null; + try { + Class<?> libraryReaderClass = Class.forName(className); + Constructor<?> constructor = libraryReaderClass.getConstructor(parameterTypes); + constructorInstance = constructor.newInstance(parameterInstances); + } catch (SecurityException e) { + throw new AssertionError(); + } catch (IllegalArgumentException e) { + throw new AssertionError("Illegal argument for library constructor for version " + version); + } catch (ClassNotFoundException e) { + throw new LibraryVersionException( + "Library " + vdir + " has an unsupported version " + version); + } catch (NoSuchMethodException e) { + throw new AssertionError("Library constructor not found for version " + version); + } catch (InstantiationException e) { + throw new AssertionError("Problem instantiating a library for version " + version); + } catch (IllegalAccessException e) { + throw new AssertionError("Problem accessing library constructor for version " + version); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } + return constructorInstance; + } +} diff --git a/jack/src/com/android/jack/library/Library.java b/jack/src/com/android/jack/library/Library.java new file mode 100644 index 0000000..aa5abd4 --- /dev/null +++ b/jack/src/com/android/jack/library/Library.java @@ -0,0 +1,29 @@ +/* + * 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.library; + +import com.android.sched.util.location.HasLocation; + +/** + * Common interface for libraries used as input and as output. + */ +public interface Library extends HasLocation { + + public int getMinorVersion() throws LibraryFormatException; + + public int getMajorVersion(); +} diff --git a/jack/src/com/android/jack/library/LibraryFormatException.java b/jack/src/com/android/jack/library/LibraryFormatException.java index 6ec6954..ec0d512 100644 --- a/jack/src/com/android/jack/library/LibraryFormatException.java +++ b/jack/src/com/android/jack/library/LibraryFormatException.java @@ -16,18 +16,29 @@ package com.android.jack.library; -import com.android.jack.JackFileException; +import com.android.jack.LibraryException; +import com.android.sched.util.location.Location; import javax.annotation.Nonnull; /** * Exception representing a problem related to the library format. */ -public class LibraryFormatException extends JackFileException { +public class LibraryFormatException extends LibraryException { private static final long serialVersionUID = 1L; - public LibraryFormatException(@Nonnull Throwable cause) { - super("Invalid library: " + cause.getMessage()); + @Nonnull + private final Location location; + + public LibraryFormatException(@Nonnull Location location) { + super(); + this.location = location; + } + + @Override + @Nonnull + public String getMessage() { + return location.getDescription() + " is an invalid library"; } } diff --git a/jack/src/com/android/jack/library/LibraryIOException.java b/jack/src/com/android/jack/library/LibraryIOException.java new file mode 100644 index 0000000..1b94d89 --- /dev/null +++ b/jack/src/com/android/jack/library/LibraryIOException.java @@ -0,0 +1,44 @@ +/* + * 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.library; + +import com.android.jack.LibraryException; +import com.android.sched.util.location.Location; + +import javax.annotation.Nonnull; + +/** + * Exception representing a problem related to an io during library access. + */ +public class LibraryIOException extends LibraryException { + + private static final long serialVersionUID = 1L; + + @Nonnull + private final Location location; + + public LibraryIOException(@Nonnull Location location, @Nonnull Throwable cause) { + super(cause); + this.location = location; + } + + @Override + @Nonnull + public String getMessage() { + return location.getDescription() + " is an invalid library: " + getCause().getMessage(); + } +} diff --git a/jack/src/com/android/jack/library/LibraryReadingException.java b/jack/src/com/android/jack/library/LibraryReadingException.java new file mode 100644 index 0000000..4b5fba8 --- /dev/null +++ b/jack/src/com/android/jack/library/LibraryReadingException.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.library; + +import com.android.jack.reporting.ReportableException; + +import javax.annotation.Nonnull; + +/** + * A {@link ReportableException} that occurs during the library reading phase. + */ +public class LibraryReadingException extends ReportableException { + + private static final long serialVersionUID = 1L; + + public LibraryReadingException(@Nonnull Throwable cause) { + super(cause); + } + + @Override + @Nonnull + public String getMessage() { + return "Error during the library reading phase: " + getCause().getMessage(); + } + + @Override + @Nonnull + public ProblemLevel getDefaultProblemLevel() { + return ProblemLevel.ERROR; + } +} diff --git a/jack/src/com/android/jack/library/LibraryVersionException.java b/jack/src/com/android/jack/library/LibraryVersionException.java new file mode 100644 index 0000000..6f01ce5 --- /dev/null +++ b/jack/src/com/android/jack/library/LibraryVersionException.java @@ -0,0 +1,33 @@ +/* + * 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.library; + +import com.android.jack.LibraryException; + +import javax.annotation.Nonnull; + +/** + * Exception representing a problem related to library version. + */ +public class LibraryVersionException extends LibraryException { + + private static final long serialVersionUID = 1L; + + public LibraryVersionException(@Nonnull String message) { + super(message); + } +} diff --git a/jack/src/com/android/jack/library/NotJackLibraryException.java b/jack/src/com/android/jack/library/NotJackLibraryException.java new file mode 100644 index 0000000..99030a1 --- /dev/null +++ b/jack/src/com/android/jack/library/NotJackLibraryException.java @@ -0,0 +1,44 @@ +/* + * 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.library; + +import com.android.jack.LibraryException; +import com.android.sched.util.location.Location; + +import javax.annotation.Nonnull; + +/** + * Exception representing that a location is not a Jack library. + */ +public class NotJackLibraryException extends LibraryException { + + private static final long serialVersionUID = 1L; + + @Nonnull + private final Location location; + + public NotJackLibraryException(@Nonnull Location location) { + super(); + this.location = location; + } + + @Override + @Nonnull + public String getMessage() { + return location.getDescription() + " is not a jack library"; + } +} diff --git a/jack/src/com/android/jack/library/OutputJackLibrary.java b/jack/src/com/android/jack/library/OutputJackLibrary.java index 979e8f0..e2c32de 100644 --- a/jack/src/com/android/jack/library/OutputJackLibrary.java +++ b/jack/src/com/android/jack/library/OutputJackLibrary.java @@ -16,104 +16,15 @@ package com.android.jack.library; -import com.android.jack.Jack; -import com.android.jack.backend.jayce.JayceFileImporter; -import com.android.jack.jayce.JayceWriter; -import com.android.jack.jayce.v0002.Version; -import com.android.sched.util.file.CannotCreateFileException; -import com.android.sched.vfs.OutputVDir; -import com.android.sched.vfs.OutputVFile; -import com.android.sched.vfs.SequentialOutputVDir; -import com.android.sched.vfs.VPath; - -import java.io.IOException; import java.util.Properties; -import javax.annotation.Nonnull; /** - * Jack library generated by Jack. + * Abstract class representing an output jack library. */ -public class OutputJackLibrary implements OutputLibrary, JackLibrary { - - @Nonnull - private final OutputVDir outputVDir; - - @Nonnull - private final OutputLibraryLocation location = new OutputLibraryLocation() { - @Override - @Nonnull - public String getDescription() { - return outputVDir.getLocation().getDescription(); - } - - @Override - @Nonnull - public OutputLibrary getOutputLibrary() { - return OutputJackLibrary.this; - } - - @Override - public final boolean equals(Object obj) { - return obj instanceof OutputLibraryLocation - && ((OutputLibraryLocation) obj).getOutputLibrary().equals(getOutputLibrary()); - } - - @Override - public final int hashCode() { - return OutputJackLibrary.this.hashCode(); - } - }; - - public OutputJackLibrary(@Nonnull OutputVDir outputVDir) { - this.outputVDir = outputVDir; - } - - @Override - @Nonnull - public OutputVFile getJayceOutputVFile(@Nonnull VPath typePath) throws CannotCreateFileException { - return outputVDir.createOutputVFile( - new VPath(typePath.getPathAsString('/') + JayceFileImporter.JAYCE_FILE_EXTENSION, '/')); - } - - @Override - public boolean needsSequentialWriting() { - return outputVDir instanceof SequentialOutputVDir; - } - - @Override - @Nonnull - public OutputVFile getBinaryOutputVFile(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) - throws CannotCreateFileException { - return outputVDir.createOutputVFile( - new VPath(typePath.getPathAsString('/') + binaryKind.getFileExtension(), '/')); - } - - @Override - @Nonnull - public OutputLibraryLocation getLocation() { - return location; - } - - @Override - public void close() throws LibraryWritingException { - Properties jackLibraryProperties = new Properties(); - jackLibraryProperties.put(KEY_LIB_EMITTER, "jack"); - jackLibraryProperties.put(KEY_LIB_EMITTER_VERSION, Jack.getVersionString()); - jackLibraryProperties.put(KEY_LIB_MAJOR_VERSION, String.valueOf(JackLibraryVersion.MAJOR)); - jackLibraryProperties.put(KEY_LIB_MINOR_VERSION, String.valueOf(JackLibraryVersion.MINOR)); - jackLibraryProperties.put(KEY_JAYCE, String.valueOf(true)); - jackLibraryProperties.put(KEY_JAYCE_MAJOR_VERSION, - String.valueOf(JayceWriter.DEFAULT_MAJOR_VERSION)); - jackLibraryProperties.put(KEY_JAYCE_MINOR_VERSION, String.valueOf(Version.CURRENT_MINOR)); +public abstract class OutputJackLibrary extends CommonJackLibrary implements OutputLibrary { - try { - OutputVFile libraryPropertiesOut = outputVDir.createOutputVFile(LIBRARY_PROPERTIES_VPATH); - jackLibraryProperties.store(libraryPropertiesOut.openWrite(), "Library properties"); - } catch (CannotCreateFileException e) { - throw new LibraryWritingException(e); - } catch (IOException e) { - throw new LibraryWritingException(e); - } + public OutputJackLibrary(Properties libraryProperties) { + super(libraryProperties); } } diff --git a/jack/src/com/android/jack/library/OutputLibrary.java b/jack/src/com/android/jack/library/OutputLibrary.java index fe0bc06..01c5482 100644 --- a/jack/src/com/android/jack/library/OutputLibrary.java +++ b/jack/src/com/android/jack/library/OutputLibrary.java @@ -17,7 +17,6 @@ package com.android.jack.library; import com.android.sched.util.file.CannotCreateFileException; -import com.android.sched.util.location.HasLocation; import com.android.sched.vfs.OutputVFile; import com.android.sched.vfs.VPath; @@ -26,7 +25,7 @@ import javax.annotation.Nonnull; /** * Library generated by Jack. */ -public interface OutputLibrary extends HasLocation { +public interface OutputLibrary extends Library { public boolean needsSequentialWriting(); @@ -38,4 +37,8 @@ public interface OutputLibrary extends HasLocation { throws CannotCreateFileException; public void close() throws LibraryWritingException; + + @Override + @Nonnull + public OutputLibraryLocation getLocation(); } diff --git a/jack/src/com/android/jack/library/v0000/InputJackLibraryImpl.java b/jack/src/com/android/jack/library/v0000/InputJackLibraryImpl.java new file mode 100644 index 0000000..26488ab --- /dev/null +++ b/jack/src/com/android/jack/library/v0000/InputJackLibraryImpl.java @@ -0,0 +1,192 @@ +/* + * 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.library.v0000; + +import com.android.jack.Jack; +import com.android.jack.library.BinaryDoesNotExistException; +import com.android.jack.library.BinaryKind; +import com.android.jack.library.InputJackLibrary; +import com.android.jack.library.InputLibrary; +import com.android.jack.library.InputLibraryLocation; +import com.android.jack.library.LibraryFormatException; +import com.android.jack.library.NotBinaryException; +import com.android.sched.util.file.NotFileOrDirectoryException; +import com.android.sched.util.log.LoggerFactory; +import com.android.sched.vfs.InputRootVDir; +import com.android.sched.vfs.InputVDir; +import com.android.sched.vfs.InputVElement; +import com.android.sched.vfs.InputVFile; +import com.android.sched.vfs.VPath; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Nonnull; + +/** + * Jack library used as input. + */ +public class InputJackLibraryImpl extends InputJackLibrary { + + @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + @Nonnull + private final InputRootVDir libraryVDir; + + @Nonnull + private final InputLibraryLocation location = new InputLibraryLocation() { + + @Override + @Nonnull + public String getDescription() { + return libraryVDir.getLocation().getDescription(); + } + + @Override + public int hashCode() { + return InputJackLibraryImpl.this.hashCode(); + } + + @Override + @Nonnull + public InputLibrary getInputLibrary() { + return InputJackLibraryImpl.this; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof InputLibraryLocation + && ((InputLibraryLocation) obj).getInputLibrary().equals(getInputLibrary()); + } + }; + + @Nonnull + private final Set<BinaryKind> binaryKinds = new HashSet<BinaryKind>(1); + + public InputJackLibraryImpl(@Nonnull InputRootVDir libraryVDir, + @Nonnull Properties libraryProperties) { + super(libraryProperties); + this.libraryVDir = libraryVDir; + fillBinaryKinds(libraryVDir); + } + + @Override + @Nonnull + public InputLibraryLocation getLocation() { + return location; + } + + @Override + @Nonnull + public Collection<BinaryKind> getBinaryKinds() { + return Jack.getUnmodifiableCollections().getUnmodifiableCollection(binaryKinds); + } + + @Override + public boolean hasBinary(@Nonnull BinaryKind binaryKind) { + return binaryKinds.contains(binaryKind); + } + + @Override + @Nonnull + public List<InputVFile> getBinaries(@Nonnull BinaryKind binaryKind) { + List<InputVFile> binaries = new ArrayList<InputVFile>(); + fillBinaries(libraryVDir, binaryKind, binaries); + return binaries; + } + + @Override + @Nonnull + public InputVFile getBinary(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) + throws BinaryDoesNotExistException { + try { + return libraryVDir.getInputVFile( + new VPath(typePath.getPathAsString('/') + BinaryKind.DEX.getFileExtension(), '/')); + } catch (NotFileOrDirectoryException e) { + throw new BinaryDoesNotExistException(getLocation(), typePath, binaryKind); + } + } + + @Override + @Nonnull + public InputRootVDir getInputVDir() { + return libraryVDir; + } + + private void fillBinaryKinds(@Nonnull InputVDir vDir) { + for (InputVElement subFile : vDir.list()) { + if (subFile.isVDir()) { + fillBinaryKinds((InputVDir) subFile); + } else { + try { + binaryKinds.add(BinaryKind.getBinaryKind((InputVFile) subFile)); + } catch (NotBinaryException e) { + // Ok, nothing to do + } + } + } + } + + private void fillBinaries(@Nonnull InputVDir vDir, @Nonnull BinaryKind binaryKind, + @Nonnull List<InputVFile> binaries) { + for (InputVElement subFile : vDir.list()) { + if (subFile.isVDir()) { + fillBinaries((InputVDir) subFile, binaryKind, binaries); + } else { + InputVFile vFile = (InputVFile) subFile; + if (binaryKind.isBinaryFile(vFile)) { + binaries.add(vFile); + } + } + } + } + + @Override + public int getMinorVersion() throws LibraryFormatException { + int minor; + try { + minor = Integer.parseInt(getProperty(KEY_LIB_MINOR_VERSION)); + } catch (NumberFormatException e) { + logger.log(Level.SEVERE, "Fails to parse the property " + KEY_LIB_MINOR_VERSION + + " from " + getLocation().getDescription(), e); + throw new LibraryFormatException(getLocation()); + } + return minor; + } + + @Override + public int getMajorVersion() { + return Version.MAJOR; + } + + @Override + public int getSupportedMinorMin() { + return Version.MINOR_MIN; + } + + @Override + public int getSupportedMinor() { + return Version.MINOR; + } +} diff --git a/jack/src/com/android/jack/library/v0000/OutputJackLibraryImpl.java b/jack/src/com/android/jack/library/v0000/OutputJackLibraryImpl.java new file mode 100644 index 0000000..d6b7a93 --- /dev/null +++ b/jack/src/com/android/jack/library/v0000/OutputJackLibraryImpl.java @@ -0,0 +1,131 @@ +/* + * 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.library.v0000; + +import com.android.jack.backend.dex.DexProperties; +import com.android.jack.backend.jayce.JayceFileImporter; +import com.android.jack.library.BinaryKind; +import com.android.jack.library.LibraryIOException; +import com.android.jack.library.OutputJackLibrary; +import com.android.jack.library.OutputLibrary; +import com.android.jack.library.OutputLibraryLocation; +import com.android.sched.util.file.CannotCreateFileException; +import com.android.sched.vfs.OutputVDir; +import com.android.sched.vfs.OutputVFile; +import com.android.sched.vfs.SequentialOutputVDir; +import com.android.sched.vfs.VPath; + +import java.io.IOException; +import java.util.Properties; + +import javax.annotation.Nonnull; + +/** + * Jack library generated by Jack. + */ +public class OutputJackLibraryImpl extends OutputJackLibrary { + + @Nonnull + private final OutputVDir outputVDir; + + @Nonnull + private final OutputLibraryLocation location = new OutputLibraryLocation() { + @Override + @Nonnull + public String getDescription() { + return outputVDir.getLocation().getDescription(); + } + + @Override + @Nonnull + public OutputLibrary getOutputLibrary() { + return OutputJackLibraryImpl.this; + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof OutputLibraryLocation + && ((OutputLibraryLocation) obj).getOutputLibrary().equals(getOutputLibrary()); + } + + @Override + public final int hashCode() { + return OutputJackLibraryImpl.this.hashCode(); + } + }; + + public OutputJackLibraryImpl(@Nonnull OutputVDir outputVDir, @Nonnull String emitterId, + @Nonnull String emitterVersion) { + super(new Properties()); + this.outputVDir = outputVDir; + putProperty(KEY_LIB_EMITTER, emitterId); + putProperty(KEY_LIB_EMITTER_VERSION, emitterVersion); + putProperty(KEY_LIB_MAJOR_VERSION, String.valueOf(getMajorVersion())); + putProperty(KEY_LIB_MINOR_VERSION, String.valueOf(getMinorVersion())); + } + + @Override + @Nonnull + public OutputVFile getJayceOutputVFile(@Nonnull VPath typePath) throws CannotCreateFileException { + return outputVDir.createOutputVFile( + new VPath(typePath.getPathAsString('/') + JayceFileImporter.JAYCE_FILE_EXTENSION, '/')); + } + + @Override + public boolean needsSequentialWriting() { + return outputVDir instanceof SequentialOutputVDir; + } + + @Override + @Nonnull + public OutputVFile getBinaryOutputVFile(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) + throws CannotCreateFileException { + if (binaryKind == BinaryKind.DEX) { + putProperty(DexProperties.KEY_DEX, String.valueOf(true)); + } + return outputVDir.createOutputVFile( + new VPath(typePath.getPathAsString('/') + binaryKind.getFileExtension(), '/')); + } + + @Override + @Nonnull + public OutputLibraryLocation getLocation() { + return location; + } + + @Override + public void close() { + try { + OutputVFile libraryPropertiesOut = outputVDir.createOutputVFile(LIBRARY_PROPERTIES_VPATH); + libraryProperties.store(libraryPropertiesOut.openWrite(), "Library properties"); + } catch (CannotCreateFileException e) { + throw new LibraryIOException(getLocation(), e); + } catch (IOException e) { + throw new LibraryIOException(getLocation(), e); + } + } + + @Override + public int getMinorVersion() { + return Version.MINOR; + } + + @Override + public int getMajorVersion() { + return Version.MAJOR; + } +} diff --git a/jack/src/com/android/jack/library/JackLibraryVersion.java b/jack/src/com/android/jack/library/v0000/Version.java index b53064a..cee7f24 100644 --- a/jack/src/com/android/jack/library/JackLibraryVersion.java +++ b/jack/src/com/android/jack/library/v0000/Version.java @@ -14,14 +14,16 @@ * limitations under the License. */ -package com.android.jack.library; +package com.android.jack.library.v0000; /** * Library version. */ -public class JackLibraryVersion { +public class Version { - public static final int MAJOR = 0; + public static final int MINOR_MIN = 0; public static final int MINOR = 0; + + public static final int MAJOR = 0; } diff --git a/jack/src/com/android/jack/library/v0001/InputJackLibraryImpl.java b/jack/src/com/android/jack/library/v0001/InputJackLibraryImpl.java new file mode 100644 index 0000000..d36dbed --- /dev/null +++ b/jack/src/com/android/jack/library/v0001/InputJackLibraryImpl.java @@ -0,0 +1,192 @@ +/* + * 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.library.v0001; + +import com.android.jack.Jack; +import com.android.jack.library.BinaryDoesNotExistException; +import com.android.jack.library.BinaryKind; +import com.android.jack.library.InputJackLibrary; +import com.android.jack.library.InputLibrary; +import com.android.jack.library.InputLibraryLocation; +import com.android.jack.library.LibraryFormatException; +import com.android.jack.library.NotBinaryException; +import com.android.sched.util.file.NotFileOrDirectoryException; +import com.android.sched.util.log.LoggerFactory; +import com.android.sched.vfs.InputRootVDir; +import com.android.sched.vfs.InputVDir; +import com.android.sched.vfs.InputVElement; +import com.android.sched.vfs.InputVFile; +import com.android.sched.vfs.VPath; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Nonnull; + +/** + * Jack library used as input. + */ +public class InputJackLibraryImpl extends InputJackLibrary { + + @Nonnull + private static Logger logger = LoggerFactory.getLogger(); + + @Nonnull + private final InputRootVDir libraryVDir; + + @Nonnull + private final InputLibraryLocation location = new InputLibraryLocation() { + + @Override + @Nonnull + public String getDescription() { + return libraryVDir.getLocation().getDescription(); + } + + @Override + public int hashCode() { + return InputJackLibraryImpl.this.hashCode(); + } + + @Override + @Nonnull + public InputLibrary getInputLibrary() { + return InputJackLibraryImpl.this; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof InputLibraryLocation + && ((InputLibraryLocation) obj).getInputLibrary().equals(getInputLibrary()); + } + }; + + @Nonnull + private final Set<BinaryKind> binaryKinds = new HashSet<BinaryKind>(1); + + public InputJackLibraryImpl(@Nonnull InputRootVDir libraryVDir, + @Nonnull Properties libraryProperties) { + super(libraryProperties); + this.libraryVDir = libraryVDir; + fillBinaryKinds(libraryVDir); + } + + @Override + @Nonnull + public InputLibraryLocation getLocation() { + return location; + } + + @Override + @Nonnull + public Collection<BinaryKind> getBinaryKinds() { + return Jack.getUnmodifiableCollections().getUnmodifiableCollection(binaryKinds); + } + + @Override + public boolean hasBinary(@Nonnull BinaryKind binaryKind) { + return binaryKinds.contains(binaryKind); + } + + @Override + @Nonnull + public List<InputVFile> getBinaries(@Nonnull BinaryKind binaryKind) { + List<InputVFile> binaries = new ArrayList<InputVFile>(); + fillBinaries(libraryVDir, binaryKind, binaries); + return binaries; + } + + @Override + @Nonnull + public InputVFile getBinary(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) + throws BinaryDoesNotExistException { + try { + return libraryVDir.getInputVFile( + new VPath(typePath.getPathAsString('/') + BinaryKind.DEX.getFileExtension(), '/')); + } catch (NotFileOrDirectoryException e) { + throw new BinaryDoesNotExistException(getLocation(), typePath, binaryKind); + } + } + + @Override + @Nonnull + public InputRootVDir getInputVDir() { + return libraryVDir; + } + + private void fillBinaryKinds(@Nonnull InputVDir vDir) { + for (InputVElement subFile : vDir.list()) { + if (subFile.isVDir()) { + fillBinaryKinds((InputVDir) subFile); + } else { + try { + binaryKinds.add(BinaryKind.getBinaryKind((InputVFile) subFile)); + } catch (NotBinaryException e) { + // Ok, nothing to do + } + } + } + } + + private void fillBinaries(@Nonnull InputVDir vDir, @Nonnull BinaryKind binaryKind, + @Nonnull List<InputVFile> binaries) { + for (InputVElement subFile : vDir.list()) { + if (subFile.isVDir()) { + fillBinaries((InputVDir) subFile, binaryKind, binaries); + } else { + InputVFile vFile = (InputVFile) subFile; + if (binaryKind.isBinaryFile(vFile)) { + binaries.add(vFile); + } + } + } + } + + @Override + public int getMinorVersion() throws LibraryFormatException { + int minor; + try { + minor = Integer.parseInt(getProperty(KEY_LIB_MINOR_VERSION)); + } catch (NumberFormatException e) { + logger.log(Level.SEVERE, "Fails to parse the property " + KEY_LIB_MINOR_VERSION + + " from " + getLocation().getDescription(), e); + throw new LibraryFormatException(getLocation()); + } + return minor; + } + + @Override + public int getMajorVersion() { + return Version.MAJOR; + } + + @Override + public int getSupportedMinorMin() { + return Version.MINOR_MIN; + } + + @Override + public int getSupportedMinor() { + return Version.MINOR; + } +} diff --git a/jack/src/com/android/jack/library/v0001/OutputJackLibraryImpl.java b/jack/src/com/android/jack/library/v0001/OutputJackLibraryImpl.java new file mode 100644 index 0000000..e84644f --- /dev/null +++ b/jack/src/com/android/jack/library/v0001/OutputJackLibraryImpl.java @@ -0,0 +1,142 @@ +/* + * 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.library.v0001; + +import com.android.jack.backend.dex.DexProperties; +import com.android.jack.backend.jayce.JayceFileImporter; +import com.android.jack.library.BinaryKind; +import com.android.jack.library.LibraryIOException; +import com.android.jack.library.OutputJackLibrary; +import com.android.jack.library.OutputLibrary; +import com.android.jack.library.OutputLibraryLocation; +import com.android.sched.util.file.CannotCreateFileException; +import com.android.sched.vfs.OutputVDir; +import com.android.sched.vfs.OutputVFile; +import com.android.sched.vfs.SequentialOutputVDir; +import com.android.sched.vfs.VPath; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Properties; + +import javax.annotation.Nonnull; + +/** + * Jack library generated by Jack. + */ +public class OutputJackLibraryImpl extends OutputJackLibrary { + + @Nonnull + private final OutputVDir outputVDir; + + @Nonnull + private final OutputLibraryLocation location = new OutputLibraryLocation() { + @Override + @Nonnull + public String getDescription() { + return outputVDir.getLocation().getDescription(); + } + + @Override + @Nonnull + public OutputLibrary getOutputLibrary() { + return OutputJackLibraryImpl.this; + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof OutputLibraryLocation + && ((OutputLibraryLocation) obj).getOutputLibrary().equals(getOutputLibrary()); + } + + @Override + public final int hashCode() { + return OutputJackLibraryImpl.this.hashCode(); + } + }; + + public OutputJackLibraryImpl(@Nonnull OutputVDir outputVDir, @Nonnull String emitterId, + @Nonnull String emitterVersion) { + super(new Properties()); + this.outputVDir = outputVDir; + putProperty(KEY_LIB_EMITTER, emitterId); + putProperty(KEY_LIB_EMITTER_VERSION, emitterVersion); + putProperty(KEY_LIB_MAJOR_VERSION, String.valueOf(getMajorVersion())); + putProperty(KEY_LIB_MINOR_VERSION, String.valueOf(getMinorVersion())); + } + + @Override + @Nonnull + public OutputVFile getJayceOutputVFile(@Nonnull VPath typePath) throws CannotCreateFileException { + return outputVDir.createOutputVFile( + new VPath(typePath.getPathAsString('/') + JayceFileImporter.JAYCE_FILE_EXTENSION, '/')); + } + + @Override + public boolean needsSequentialWriting() { + return outputVDir instanceof SequentialOutputVDir; + } + + @Override + @Nonnull + public OutputVFile getBinaryOutputVFile(@Nonnull VPath typePath, @Nonnull BinaryKind binaryKind) + throws CannotCreateFileException { + if (binaryKind == BinaryKind.DEX) { + putProperty(DexProperties.KEY_DEX, String.valueOf(true)); + } + return outputVDir.createOutputVFile( + new VPath(typePath.getPathAsString('/') + binaryKind.getFileExtension(), '/')); + } + + @Override + @Nonnull + public OutputLibraryLocation getLocation() { + return location; + } + + @Override + public void close() { + OutputStream os = null; + try { + OutputVFile libraryPropertiesOut = outputVDir.createOutputVFile(LIBRARY_PROPERTIES_VPATH); + os = libraryPropertiesOut.openWrite(); + libraryProperties.store(os, "Library properties"); + } catch (CannotCreateFileException e) { + throw new LibraryIOException(getLocation(), e); + } catch (IOException e) { + throw new LibraryIOException(getLocation(), e); + } finally { + if (os != null) { + try { + os.close(); + } catch (IOException e) { + throw new LibraryIOException(getLocation(), e); + } + } + } + } + + @Override + public int getMinorVersion() { + return Version.MINOR; + } + + @Override + public int getMajorVersion() { + return Version.MAJOR; + } +} diff --git a/jack/src/com/android/jack/library/v0001/Version.java b/jack/src/com/android/jack/library/v0001/Version.java new file mode 100644 index 0000000..9a57ef7 --- /dev/null +++ b/jack/src/com/android/jack/library/v0001/Version.java @@ -0,0 +1,29 @@ +/* + * 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.library.v0001; + +/** + * Library version. + */ +public class Version { + + public static final int MINOR_MIN = 0; + + public static final int MINOR = 0; + + public static final int MAJOR = 1; +} |