/* * Copyright 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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.amazonaws.eclipse.android.sdk.newproject; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.ui.statushandlers.StatusManager; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import com.amazonaws.eclipse.android.sdk.AndroidSDKPlugin; public class AndroidManifestFile { private File manifestFile; private Transformer transformer; public AndroidManifestFile(IProject project) { IPath projectLocation = project.getLocation(); IPath androidManifestFile = projectLocation.append("AndroidManifest.xml"); manifestFile = androidManifestFile.toFile(); try { transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); } catch (TransformerConfigurationException e) { throw new RuntimeException("Unable to configure output transformer for Android manifest files", e); } catch (TransformerFactoryConfigurationError e) { throw new RuntimeException("Unable to configure output transformer for Android manifest files", e); } } /** * Adds an activity to the default application in the manifest: * * <activity android:name="S3UploaderActivity" * android:label="@string/app_name"> * <intent-filter> * <action android:name="android.intent.action.MAIN" /> * <category android:name="android.intent.category.LAUNCHER" /> * </intent-filter> * </activity> */ public void addSampleActivity() { try { Document doc = parse(); Node manifestElement = firstChildElement(doc, "manifest"); if (manifestElement == null) { throw new RuntimeException("No manifest element in manifest.xml"); } Node applicationElement = firstChildElement(manifestElement, "application"); if (applicationElement == null) { throw new RuntimeException("No application element in manifest.xml"); } applicationElement.appendChild(createActivityElement(doc)); StreamResult result = new StreamResult(manifestFile); transformer.transform(new DOMSource(doc), result); } catch (Exception e) { IStatus status = new Status(IStatus.ERROR, AndroidSDKPlugin.PLUGIN_ID, "Unable to update Android project manifest with settings for the AWS SDK for Android", e); StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG); } } /** * Updates the Android manifest file for the specified Android project with * customizations for building Android projects that work with AWS. * * Specifically, this method adds the following configuration: * uses-sdk android:minSdkVersion="10" * uses-permission android:name="android.permission.INTERNET" */ public void initialize() { try { Document doc = parse(); Node manifestElement = firstChildElement(doc, "manifest"); Node applicationElement = firstChildElement(manifestElement, "application"); manifestElement.removeChild(applicationElement); Element usesSdkElement = doc.createElement("uses-sdk"); usesSdkElement.setAttribute("android:minSdkVersion", "10"); manifestElement.appendChild(usesSdkElement); Element usesPermissionElement = doc.createElement("uses-permission"); usesPermissionElement.setAttribute("android:name", "android.permission.INTERNET"); manifestElement.appendChild(usesPermissionElement); // Add the application element back, so that it // comes after the uses-permission elements manifestElement.appendChild(applicationElement); StreamResult result = new StreamResult(manifestFile); transformer.transform(new DOMSource(doc), result); } catch (Exception e) { IStatus status = new Status(IStatus.ERROR, AndroidSDKPlugin.PLUGIN_ID, "Unable to update Android project manifest with settings for the AWS SDK for Android", e); StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG); } } private Document parse() { try { DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); return docBuilder.parse(manifestFile); } catch (Exception e) { throw new RuntimeException("Unable to parse Android manifest file", e); } } private Node createActivityElement(Document doc) { Element activityElement = doc.createElement("activity"); activityElement.setAttribute("android:name", "S3UploaderActivity"); activityElement.setAttribute("android:label", "@string/app_name"); Element intentFilterElement = doc.createElement("intent-filter"); Element actionElement = doc.createElement("action"); actionElement.setAttribute("android:name", "android.intent.action.MAIN"); Element categoryElement = doc.createElement("category"); categoryElement.setAttribute("android:name", "android.intent.category.LAUNCHER"); intentFilterElement.appendChild(actionElement); intentFilterElement.appendChild(categoryElement); activityElement.appendChild(intentFilterElement); return activityElement; } private Node firstChildElement(Node parent, String elementName) { for (int i = 0; i < parent.getChildNodes().getLength(); i++) { Node node = parent.getChildNodes().item(i); if (node.getNodeName().equals(elementName)) return node; } return null; } }