From d16b6285320be7ac0450ed48ece7881078315782 Mon Sep 17 00:00:00 2001 From: Benoit Lamarche Date: Thu, 18 Jun 2015 19:21:14 +0200 Subject: Declare CLI and let Jill implement it Change-Id: I41e09c66b690b06bf761d0e3b91059bce578d760 --- .../src/com/android/jill/api/v01/Api01Config.java | 2 +- .../src/com/android/jill/api/v01/Cli01Config.java | 59 ++++++++++++++ .../android/jill/api/v01/Cli01TranslationTask.java | 32 ++++++++ jill/src/com/android/jill/Main.java | 23 ++++-- jill/src/com/android/jill/Options.java | 36 ++++++++- .../android/jill/api/impl/JillProviderImpl.java | 9 ++- .../android/jill/api/v01/impl/Cli01ConfigImpl.java | 93 ++++++++++++++++++++++ 7 files changed, 241 insertions(+), 13 deletions(-) create mode 100644 jill-api/src/com/android/jill/api/v01/Cli01Config.java create mode 100644 jill-api/src/com/android/jill/api/v01/Cli01TranslationTask.java create mode 100644 jill/src/com/android/jill/api/v01/impl/Cli01ConfigImpl.java diff --git a/jill-api/src/com/android/jill/api/v01/Api01Config.java b/jill-api/src/com/android/jill/api/v01/Api01Config.java index b1923bd..ea1e55b 100644 --- a/jill-api/src/com/android/jill/api/v01/Api01Config.java +++ b/jill-api/src/com/android/jill/api/v01/Api01Config.java @@ -24,7 +24,7 @@ import java.io.File; import javax.annotation.Nonnull; /** -* A configuration implementation for API level 01 of Jill. +* A configuration for API level 01 of Jill. */ public interface Api01Config extends JillConfig { diff --git a/jill-api/src/com/android/jill/api/v01/Cli01Config.java b/jill-api/src/com/android/jill/api/v01/Cli01Config.java new file mode 100644 index 0000000..2396f43 --- /dev/null +++ b/jill-api/src/com/android/jill/api/v01/Cli01Config.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 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.jill.api.v01; + +import com.android.jill.api.JillConfig; + +import java.io.File; +import java.io.PrintStream; + +import javax.annotation.Nonnull; + +/** +* A configuration for CLI level 01 of Jill. +*/ +public interface Cli01Config extends JillConfig { + + /** + * Creates an instance of the {@link Cli01TranslationTask} according to this configuration. + * @param args To be handled as command line arguments. + * @return The {@link Cli01TranslationTask} + * @throws ConfigurationException + */ + @Nonnull + Cli01TranslationTask getTask(@Nonnull String[] args) throws ConfigurationException; + + /** + * Redirect Jill's error output to the given stream. + * @param standardError The stream where to write errors. + */ + void setStandardError(@Nonnull PrintStream standardError); + + /** + * Redirect Jill's standards output to the given stream. + * @param standardOutput The stream where to write non error messages. + */ + void setStandardOutput(@Nonnull PrintStream standardOutput); + + /** + * Defines Jill's working directory. + * @param workingDirectory The base directory that will be used to evaluate non absolute file + * paths. + */ + void setWorkingDirectory(@Nonnull File workingDirectory); +} + diff --git a/jill-api/src/com/android/jill/api/v01/Cli01TranslationTask.java b/jill-api/src/com/android/jill/api/v01/Cli01TranslationTask.java new file mode 100644 index 0000000..61734b9 --- /dev/null +++ b/jill-api/src/com/android/jill/api/v01/Cli01TranslationTask.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 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.jill.api.v01; + +/** + * A task allowing to run Jill once. + */ +public interface Cli01TranslationTask { + + /** + * Runs the Jill compiler. May be called only once. + * @return command line status + * @throws TranslationException If a fatal error occurred during the translation + * @throws IllegalStateException If the translation task is run more than once + */ + int run() throws TranslationException, IllegalStateException; +} + diff --git a/jill/src/com/android/jill/Main.java b/jill/src/com/android/jill/Main.java index e35ba93..172c355 100644 --- a/jill/src/com/android/jill/Main.java +++ b/jill/src/com/android/jill/Main.java @@ -52,9 +52,8 @@ public class Main { System.exit(ExitStatus.SUCCESS); } - Jill.process(options); + System.exit(runJill(System.err, options)); - System.exit(ExitStatus.SUCCESS); } catch (CmdLineException e) { if (e.getMessage() != null) { System.err.println(e.getMessage()); @@ -70,21 +69,29 @@ public class Main { System.err.println(e.getMessage()); System.exit(ExitStatus.FAILURE_USAGE); + } + + System.exit(ExitStatus.FAILURE_UNKNOWN); + } + + protected static int runJill(@Nonnull PrintStream err, @Nonnull Options options) { + try { + Jill.process(options); + } catch (JillException e) { if (options != null) { - System.err.println("Binary transformation of " + options.getBinaryFile().getName() + err.println("Binary transformation of " + options.getBinaryFile().getName() + " failed."); if (options.isVerbose()) { - e.printStackTrace(); + e.printStackTrace(err); } } else { - System.err.println("Binary transformation failed."); + err.println("Binary transformation failed."); } - System.exit(ExitStatus.FAILURE_INTERNAL); + return ExitStatus.FAILURE_INTERNAL; } - - System.exit(ExitStatus.FAILURE_UNKNOWN); + return ExitStatus.SUCCESS; } @Nonnull diff --git a/jill/src/com/android/jill/Options.java b/jill/src/com/android/jill/Options.java index 8dad09b..cfc4395 100644 --- a/jill/src/com/android/jill/Options.java +++ b/jill/src/com/android/jill/Options.java @@ -22,6 +22,7 @@ import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import java.io.File; +import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -55,6 +56,11 @@ public class Options { @Option(name = "--no-debug", usage = "disable debug info emission") protected boolean disableEmitDebugInfo = false; + @CheckForNull + private PrintStream err; + @CheckForNull + private File workingDir; + public void checkValidity() throws IllegalOptionsException { if (askForVersion() || askForHelp()) { return; @@ -85,13 +91,21 @@ public class Options { @Nonnull public File getOutput() { assert output != null; - return output; + if (workingDir != null) { + return new File(workingDir, output.getPath()); + } else { + return output; + } } @Nonnull public File getBinaryFile() { assert binaryFile != null; - return binaryFile; + if (workingDir != null) { + return new File(workingDir, binaryFile.getPath()); + } else { + return binaryFile; + } } public boolean askForVersion() { @@ -123,9 +137,25 @@ public class Options { return outputContainer; } + + public void setStandardError(@Nonnull PrintStream standardError) { + err = standardError; + } + + @CheckForNull + public PrintStream getStandardError() { + return err; + } + + public void setWorkingDirectory(@Nonnull File workingDir) { + this.workingDir = workingDir; + } + private void checkBinaryFileValidity() throws IllegalOptionsException { assert binaryFile != null; + File binaryFile = getBinaryFile(); + if (!binaryFile.exists()) { throw new IllegalOptionsException(binaryFile.getName() + " does not exists."); } @@ -150,6 +180,8 @@ public class Options { private void checkOutputDir() throws IllegalOptionsException { assert output != null; + File output = getOutput(); + if (!output.exists()) { throw new IllegalOptionsException(output.getName() + " does not exist."); } diff --git a/jill/src/com/android/jill/api/impl/JillProviderImpl.java b/jill/src/com/android/jill/api/impl/JillProviderImpl.java index 98a0978..e3f3863 100644 --- a/jill/src/com/android/jill/api/impl/JillProviderImpl.java +++ b/jill/src/com/android/jill/api/impl/JillProviderImpl.java @@ -21,7 +21,9 @@ import com.android.jill.api.ConfigNotSupportedException; import com.android.jill.api.JillConfig; import com.android.jill.api.JillProvider; import com.android.jill.api.v01.Api01Config; +import com.android.jill.api.v01.Cli01Config; import com.android.jill.api.v01.impl.Api01ConfigImpl; +import com.android.jill.api.v01.impl.Cli01ConfigImpl; import java.util.ArrayList; import java.util.Collection; @@ -42,6 +44,8 @@ public class JillProviderImpl implements JillProvider { throws ConfigNotSupportedException { if (cls == Api01Config.class) { return (T) new Api01ConfigImpl(); + } else if (cls == Cli01Config.class) { + return (T) new Cli01ConfigImpl(); } throw new ConfigNotSupportedException(cls.getName() + " are not supported"); @@ -50,14 +54,15 @@ public class JillProviderImpl implements JillProvider { @Override @Nonnull public boolean isConfigSupported(@Nonnull Class cls) { - return cls == Api01Config.class; + return cls == Api01Config.class || cls == Cli01Config.class; } @Override @Nonnull public Collection> getSupportedConfigs() { - List> result = new ArrayList>(1); + List> result = new ArrayList>(2); result.add(Api01Config.class); + result.add(Cli01Config.class); return result; } diff --git a/jill/src/com/android/jill/api/v01/impl/Cli01ConfigImpl.java b/jill/src/com/android/jill/api/v01/impl/Cli01ConfigImpl.java new file mode 100644 index 0000000..186aff0 --- /dev/null +++ b/jill/src/com/android/jill/api/v01/impl/Cli01ConfigImpl.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015 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.jill.api.v01.impl; + +import com.android.jill.Main; +import com.android.jill.Options; +import com.android.jill.api.v01.Cli01Config; +import com.android.jill.api.v01.Cli01TranslationTask; +import com.android.jill.api.v01.ConfigurationException; + +import org.kohsuke.args4j.CmdLineException; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * This class provides the version 01 implementation of Jill CLI. + */ +public class Cli01ConfigImpl implements Cli01Config { + + @CheckForNull + private PrintStream standardError; + @CheckForNull + private File workingDirectory; + + @Override + @Nonnull + public Cli01TranslationTask getTask(@Nonnull String[] args) throws ConfigurationException { + try { + Options options = Main.getOptions(args); + options.setStandardError(standardError); + options.setWorkingDirectory(workingDirectory); + return new Cli01TranslationTaskImpl(options); + } catch (CmdLineException e) { + throw new ConfigurationException(e.getMessage(), e); + } catch (IOException e) { + throw new ConfigurationException(e.getMessage(), e); + } + } + + private static class Cli01TranslationTaskImpl extends Main implements Cli01TranslationTask { + + @Nonnull + private final Options options; + + public Cli01TranslationTaskImpl(@Nonnull Options options) { + this.options = options; + } + + @Override + public int run() { + PrintStream err = options.getStandardError(); + if (err == null) { + err = System.err; + } + return runJill(err, options); + } + + } + + @Override + public void setStandardError(@Nonnull PrintStream standardError) { + this.standardError = standardError; + } + + @Override + public void setStandardOutput(@Nonnull PrintStream standardOutput) { + } + + @Override + public void setWorkingDirectory(@Nonnull File workingDirectory) { + this.workingDirectory = workingDirectory; + } +} + -- cgit v1.1