1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you 5 * may not use this file except in compliance with the License. You may obtain a 6 * copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package com.android.tradefed.util.xml; 17 18 import com.android.tradefed.log.LogUtil.CLog; 19 20 import org.w3c.dom.Attr; 21 import org.w3c.dom.Document; 22 import org.w3c.dom.Element; 23 import org.w3c.dom.NodeList; 24 import org.xml.sax.SAXException; 25 import org.xml.sax.helpers.DefaultHandler; 26 27 import java.io.File; 28 import java.io.IOException; 29 30 import javax.xml.parsers.DocumentBuilder; 31 import javax.xml.parsers.DocumentBuilderFactory; 32 import javax.xml.parsers.ParserConfigurationException; 33 import javax.xml.transform.Result; 34 import javax.xml.transform.Source; 35 import javax.xml.transform.Transformer; 36 import javax.xml.transform.TransformerConfigurationException; 37 import javax.xml.transform.TransformerException; 38 import javax.xml.transform.TransformerFactory; 39 import javax.xml.transform.dom.DOMSource; 40 import javax.xml.transform.stream.StreamResult; 41 42 /** 43 * Helper class for modifying an AndroidManifest. 44 * <p/> 45 * copied from 46 * <android source>/platform/sdk/.../adt-tests/com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper. 47 * TODO: Find a way of sharing this code with adt-tests 48 */ 49 public class AndroidManifestWriter { 50 51 private final Document mDoc; 52 private final String mOsManifestFilePath; 53 54 private static final String NODE_USES_SDK = "uses-sdk"; 55 private static final String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; 56 /** Namespace for the resource XML, i.e. "http://schemas.android.com/apk/res/android" */ 57 private final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android"; 58 59 private AndroidManifestWriter(Document doc, String osManifestFilePath) { 60 mDoc = doc; 61 mOsManifestFilePath = osManifestFilePath; 62 } 63 64 /** 65 * Sets the minimum SDK version for this manifest. 66 * 67 * @param minSdkVersion - the minimim sdk version to use 68 * @return <code>true</code> on success, false otherwise 69 */ 70 public boolean setMinSdkVersion(String minSdkVersion) { 71 Element usesSdkElement = null; 72 NodeList nodeList = mDoc.getElementsByTagName(NODE_USES_SDK); 73 if (nodeList.getLength() > 0) { 74 usesSdkElement = (Element) nodeList.item(0); 75 } else { 76 usesSdkElement = mDoc.createElement(NODE_USES_SDK); 77 mDoc.getDocumentElement().appendChild(usesSdkElement); 78 } 79 Attr minSdkAttr = mDoc.createAttributeNS(NS_RESOURCES, ATTRIBUTE_MIN_SDK_VERSION); 80 String prefix = mDoc.lookupPrefix(NS_RESOURCES); 81 minSdkAttr.setPrefix(prefix); 82 minSdkAttr.setValue(minSdkVersion); 83 usesSdkElement.setAttributeNodeNS(minSdkAttr); 84 return saveXmlToFile(); 85 } 86 87 private boolean saveXmlToFile() { 88 try { 89 // Prepare the DOM document for writing 90 Source source = new DOMSource(mDoc); 91 92 // Prepare the output file 93 File file = new File(mOsManifestFilePath); 94 Result result = new StreamResult(file); 95 96 // Write the DOM document to the file 97 Transformer xformer = TransformerFactory.newInstance().newTransformer(); 98 xformer.transform(source, result); 99 } catch (TransformerConfigurationException e) { 100 CLog.e("Failed to write xml file %s", mOsManifestFilePath); 101 CLog.e(e); 102 return false; 103 } catch (TransformerException e) { 104 CLog.e("Failed to write xml file %s", mOsManifestFilePath); 105 CLog.e(e); 106 return false; 107 } 108 return true; 109 } 110 111 /** 112 * Parses the manifest file, and collects data. 113 * 114 * @param osManifestFilePath The OS path of the manifest file to parse. 115 * @return an {@link AndroidManifestWriter} or null if parsing failed 116 */ 117 public static AndroidManifestWriter parse(String osManifestFilePath) { 118 try { 119 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 120 docFactory.setNamespaceAware(true); 121 DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 122 docBuilder.setErrorHandler(new DefaultHandler()); 123 Document doc = docBuilder.parse(osManifestFilePath); 124 return new AndroidManifestWriter(doc, osManifestFilePath); 125 } catch (ParserConfigurationException e) { 126 CLog.e("Error parsing file %s", osManifestFilePath); 127 CLog.e(e); 128 return null; 129 } catch (SAXException e) { 130 CLog.e("Error parsing file %s", osManifestFilePath); 131 CLog.e(e); 132 return null; 133 } catch (IOException e) { 134 CLog.e("Error parsing file %s", osManifestFilePath); 135 CLog.e(e); 136 return null; 137 } 138 } 139 } 140