1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.sdklib.xml; 18 19 import com.android.sdklib.SdkConstants; 20 import com.android.sdklib.io.IAbstractFile; 21 import com.android.sdklib.io.IAbstractFolder; 22 import com.android.sdklib.io.StreamException; 23 24 import org.xml.sax.InputSource; 25 26 import javax.xml.xpath.XPath; 27 import javax.xml.xpath.XPathExpressionException; 28 29 /** 30 * Helper and Constants for the AndroidManifest.xml file. 31 * 32 */ 33 public final class AndroidManifest { 34 35 public final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$ 36 public final static String NODE_APPLICATION = "application"; //$NON-NLS-1$ 37 public final static String NODE_ACTIVITY = "activity"; //$NON-NLS-1$ 38 public final static String NODE_SERVICE = "service"; //$NON-NLS-1$ 39 public final static String NODE_RECEIVER = "receiver"; //$NON-NLS-1$ 40 public final static String NODE_PROVIDER = "provider"; //$NON-NLS-1$ 41 public final static String NODE_INTENT = "intent-filter"; //$NON-NLS-1$ 42 public final static String NODE_ACTION = "action"; //$NON-NLS-1$ 43 public final static String NODE_CATEGORY = "category"; //$NON-NLS-1$ 44 public final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$ 45 public final static String NODE_INSTRUMENTATION = "instrumentation"; //$NON-NLS-1$ 46 public final static String NODE_USES_LIBRARY = "uses-library"; //$NON-NLS-1$ 47 48 public final static String ATTRIBUTE_PACKAGE = "package"; //$NON-NLS-1$ 49 public final static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$ 50 public final static String ATTRIBUTE_PROCESS = "process"; //$NON-NLS-$ 51 public final static String ATTRIBUTE_DEBUGGABLE = "debuggable"; //$NON-NLS-$ 52 public final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$ 53 public final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$ 54 public final static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$ 55 56 /** 57 * Returns the package for a given project. 58 * @param projectFolder the folder of the project. 59 * @return the package info or null (or empty) if not found. 60 * @throws XPathExpressionException 61 * @throws StreamException If any error happens when reading the manifest. 62 */ 63 public static String getPackage(IAbstractFolder projectFolder) 64 throws XPathExpressionException, StreamException { 65 IAbstractFile file = projectFolder.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML); 66 return getPackage(file); 67 } 68 69 /** 70 * Returns the package for a given manifest. 71 * @param manifestFile the manifest to parse. 72 * @return the package info or null (or empty) if not found. 73 * @throws XPathExpressionException 74 * @throws StreamException If any error happens when reading the manifest. 75 */ 76 public static String getPackage(IAbstractFile manifestFile) 77 throws XPathExpressionException, StreamException { 78 XPath xPath = AndroidXPathFactory.newXPath(); 79 80 return xPath.evaluate( 81 "/" + NODE_MANIFEST + 82 "/@" + ATTRIBUTE_PACKAGE, 83 new InputSource(manifestFile.getContents())); 84 } 85 86 /** 87 * Combines a java package, with a class value from the manifest to make a fully qualified 88 * class name 89 * @param javaPackage the java package from the manifest. 90 * @param className the class name from the manifest. 91 * @return the fully qualified class name. 92 */ 93 public static String combinePackageAndClassName(String javaPackage, String className) { 94 if (className == null || className.length() == 0) { 95 return javaPackage; 96 } 97 if (javaPackage == null || javaPackage.length() == 0) { 98 return className; 99 } 100 101 // the class name can be a subpackage (starts with a '.' 102 // char), a simple class name (no dot), or a full java package 103 boolean startWithDot = (className.charAt(0) == '.'); 104 boolean hasDot = (className.indexOf('.') != -1); 105 if (startWithDot || hasDot == false) { 106 107 // add the concatenation of the package and class name 108 if (startWithDot) { 109 return javaPackage + className; 110 } else { 111 return javaPackage + '.' + className; 112 } 113 } else { 114 // just add the class as it should be a fully qualified java name. 115 return className; 116 } 117 } 118 119 /** 120 * Given a fully qualified activity name (e.g. com.foo.test.MyClass) and given a project 121 * package base name (e.g. com.foo), returns the relative activity name that would be used 122 * the "name" attribute of an "activity" element. 123 * 124 * @param fullActivityName a fully qualified activity class name, e.g. "com.foo.test.MyClass" 125 * @param packageName The project base package name, e.g. "com.foo" 126 * @return The relative activity name if it can be computed or the original fullActivityName. 127 */ 128 public static String extractActivityName(String fullActivityName, String packageName) { 129 if (packageName != null && fullActivityName != null) { 130 if (packageName.length() > 0 && fullActivityName.startsWith(packageName)) { 131 String name = fullActivityName.substring(packageName.length()); 132 if (name.length() > 0 && name.charAt(0) == '.') { 133 return name; 134 } 135 } 136 } 137 138 return fullActivityName; 139 } 140 } 141