aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-12-11 14:59:27 -0800
committerTor Norbye <tnorbye@google.com>2014-12-11 23:18:02 +0000
commitffe624dfdd009a42bd52357fd2045793015e4ec1 (patch)
tree616f09044f74167838b37ff614dc8bade4e5357c /eclipse
parentd3f8c8121e9fd6cfd2736eed92062ede63b19a67 (diff)
downloadsdk-ffe624dfdd009a42bd52357fd2045793015e4ec1.zip
sdk-ffe624dfdd009a42bd52357fd2045793015e4ec1.tar.gz
sdk-ffe624dfdd009a42bd52357fd2045793015e4ec1.tar.bz2
82393: Fix template instantiation in ADT
First, implement a couple of new freemarker methods required by the templates. Second, switch the manifest merger over to the new Manifest merger. Change-Id: I26200d0a861ebddd4c4c92ebbba418ccb88fcb20 (cherry picked from commit d7d481fa5e19353d1636f4df8b9bf875539bbc81)
Diffstat (limited to 'eclipse')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapePropertyValueMethod.java64
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmHasDependencyMethod.java49
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java55
4 files changed, 169 insertions, 3 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapePropertyValueMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapePropertyValueMethod.java
new file mode 100644
index 0000000..c6dc704
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapePropertyValueMethod.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ide.eclipse.adt.internal.wizards.templates;
+
+import com.android.utils.SdkUtils;
+import freemarker.template.SimpleScalar;
+import freemarker.template.TemplateMethodModel;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Properties;
+
+/** Escapes a property value (such that its syntax is valid in a Java properties file */
+public class FmEscapePropertyValueMethod implements TemplateMethodModel {
+ @Override
+ public TemplateModel exec(List args) throws TemplateModelException {
+ if (args.size() != 1) {
+ throw new TemplateModelException("Wrong arguments");
+ }
+
+ // Slow, stupid implementation, but is 100% compatible with Java's property file implementation
+ Properties properties = new Properties();
+ String value = args.get(0).toString();
+ properties.setProperty("k", value); // key doesn't matter
+ StringWriter writer = new StringWriter();
+ String escaped;
+ try {
+ properties.store(writer, null);
+ String s = writer.toString();
+ int end = s.length();
+
+ // Writer inserts trailing newline
+ String lineSeparator = SdkUtils.getLineSeparator();
+ if (s.endsWith(lineSeparator)) {
+ end -= lineSeparator.length();
+ }
+
+ int start = s.indexOf('=');
+ assert start != -1 : s;
+ escaped = s.substring(start + 1, end);
+ }
+ catch (IOException e) {
+ escaped = value; // shouldn't happen; we're not going to disk
+ }
+
+ return new SimpleScalar(escaped);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java
index 09fa81c..1f50161 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java
@@ -15,13 +15,13 @@
*/
package com.android.ide.eclipse.adt.internal.wizards.templates;
+import java.util.List;
+
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
-import java.util.List;
-
/**
* Method invoked by FreeMarker to extract letters from a string; this will remove
* any whitespace, punctuation and digits.
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmHasDependencyMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmHasDependencyMethod.java
new file mode 100644
index 0000000..1618969
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmHasDependencyMethod.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ide.eclipse.adt.internal.wizards.templates;
+
+import java.util.List;
+import java.util.Map;
+
+import freemarker.template.TemplateBooleanModel;
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+
+/**
+ * Method invoked by FreeMarker to check whether a given dependency is available
+ * in this module
+ */
+public class FmHasDependencyMethod implements TemplateMethodModelEx {
+ private final Map<String, Object> myParamMap;
+
+ public FmHasDependencyMethod(Map<String, Object> paramMap) {
+ myParamMap = paramMap;
+ }
+
+ @Override
+ public TemplateModel exec(List args) throws TemplateModelException {
+ if (args.size() != 1) {
+ throw new TemplateModelException("Wrong arguments");
+ }
+
+ // TODO: Try to figure out if the project has appcompat etc
+ // com.android.support:appcompat-v7
+
+ // Not yet implemented
+ return TemplateBooleanModel.FALSE;
+ }
+} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
index 8e11841..569e017 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
@@ -43,9 +43,15 @@ import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.AdtManifestMergeCallback;
import com.android.manifmerger.ManifestMerger;
+import com.android.manifmerger.ManifestMerger2;
+import com.android.manifmerger.ManifestMerger2.Invoker.Feature;
+import com.android.manifmerger.ManifestMerger2.MergeType;
import com.android.manifmerger.MergerLog;
+import com.android.manifmerger.MergingReport;
+import com.android.manifmerger.XmlDocument;
import com.android.resources.ResourceFolderType;
import com.android.utils.SdkUtils;
+import com.android.utils.StdLogger;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
@@ -351,7 +357,9 @@ class TemplateHandler {
paramMap.put("escapeXmlAttribute", new FmEscapeXmlStringMethod()); //$NON-NLS-1$
paramMap.put("escapeXmlText", new FmEscapeXmlStringMethod()); //$NON-NLS-1$
paramMap.put("escapeXmlString", new FmEscapeXmlStringMethod()); //$NON-NLS-1$
+ paramMap.put("escapePropertyValue", new FmEscapePropertyValueMethod()); //$NON-NLS-1$
paramMap.put("extractLetters", new FmExtractLettersMethod()); //$NON-NLS-1$
+ paramMap.put("hasDependency", new FmHasDependencyMethod(paramMap)); //$NON-NLS-1$
// This should be handled better: perhaps declared "required packages" as part of the
// inputs? (It would be better if we could conditionally disable template based
@@ -757,7 +765,17 @@ class TemplateHandler {
boolean ok;
String fileName = to.getName();
if (fileName.equals(SdkConstants.FN_ANDROID_MANIFEST_XML)) {
- modified = ok = mergeManifest(currentDocument, fragment);
+ if (Boolean.getBoolean("adt.use_old_manifest_merger")) {
+ modified = ok = mergeManifest(currentDocument, fragment);
+ } else {
+ XmlDocument doc = mergeManifest(currentXml, xml);
+ if (doc != null) {
+ currentDocument = doc.getXml();
+ ok = modified = true;
+ } else {
+ ok = modified = false;
+ }
+ }
} else {
// Merge plain XML files
String parentFolderName = to.getParent().getName();
@@ -924,6 +942,41 @@ class TemplateHandler {
merger.process(currentManifest, fragment);
}
+ /** Merges the given manifest fragment into the given manifest file */
+ @Nullable
+ private static XmlDocument mergeManifest(@NonNull String currentText, @NonNull String mergeText) {
+ File mergeFile = null;
+ File currentFile = null;
+ try {
+ mergeFile = File.createTempFile("manifmerge", DOT_XML);
+ currentFile = File.createTempFile("main", DOT_XML);
+ Files.write(currentText, currentFile, Charsets.UTF_8);
+ Files.write(mergeText, mergeFile, Charsets.UTF_8);
+ StdLogger logger = new StdLogger(StdLogger.Level.INFO);
+ ManifestMerger2.Invoker merger = ManifestMerger2
+ .newMerger(currentFile, logger, MergeType.APPLICATION)
+ .withFeatures(Feature.EXTRACT_FQCNS)
+ .addLibraryManifest(mergeFile);
+ MergingReport mergeReport = merger.merge();
+ if (mergeReport.getMergedDocument().isPresent()) {
+ return mergeReport.getMergedDocument().get();
+ }
+ return null;
+ } catch (IOException e) {
+ AdtPlugin.log(e, null);
+ } catch (ManifestMerger2.MergeFailureException e) {
+ AdtPlugin.log(e, null);
+ } finally {
+ if (mergeFile != null) {
+ mergeFile.delete();
+ }
+ if (currentFile != null) {
+ currentFile.delete();
+ }
+ }
+ return null;
+ }
+
/**
* Makes a backup of the given file, if it exists, by renaming it to name~
* (and removing an old name~ file if it exists)