Home | History | Annotate | Download | only in xml
      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