Code drop from //branches/cupcake/...@124589

This commit is contained in:
The Android Open Source Project
2008-12-17 18:04:04 -08:00
parent 5c11852110
commit e943f2fd8e
659 changed files with 47382 additions and 9976 deletions

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="lib" path="androidprefs.jar"/>
<classpathentry kind="lib" path="sdkstats.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>common</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -1,22 +0,0 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Android Common Plugin
Bundle-SymbolicName: com.android.ide.eclipse.common;singleton:=true
Bundle-Version: 0.8.1.qualifier
Bundle-ClassPath: .,
sdkstats.jar,
androidprefs.jar
Bundle-Vendor: The Android Open Source Project
Eclipse-LazyStart: true
Export-Package: com.android.ide.eclipse.common,
com.android.ide.eclipse.common.project,
com.android.ide.eclipse.common.resources
Require-Bundle: org.eclipse.core.resources,
org.eclipse.core.runtime,
org.eclipse.jdt.core,
org.eclipse.ui.console,
org.eclipse.ui,
org.eclipse.jdt.ui,
org.eclipse.jface.text,
org.eclipse.ui.editors
Bundle-Activator: com.android.ide.eclipse.common.CommonPlugin

View File

@@ -1,224 +0,0 @@
*Eclipse Public License - v 1.0*
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
*1. DEFINITIONS*
"Contribution" means:
a) in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and
are distributed by that particular Contributor. A Contribution
'originates' from a Contributor if it was added to the Program by such
Contributor itself or anyone acting on such Contributor's behalf.
Contributions do not include additions to the Program which: (i) are
separate modules of software distributed in conjunction with the Program
under their own license agreement, and (ii) are not derivative works of
the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which
are necessarily infringed by the use or sale of its Contribution alone
or when combined with the Program.
"Program" means the Contributions distributed in accordance with this
Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
*2. GRANT OF RIGHTS*
a) Subject to the terms of this Agreement, each Contributor hereby
grants Recipient a non-exclusive, worldwide, royalty-free copyright
license to reproduce, prepare derivative works of, publicly display,
publicly perform, distribute and sublicense the Contribution of such
Contributor, if any, and such derivative works, in source code and
object code form.
b) Subject to the terms of this Agreement, each Contributor hereby
grants Recipient a non-exclusive, worldwide, royalty-free patent license
under Licensed Patents to make, use, sell, offer to sell, import and
otherwise transfer the Contribution of such Contributor, if any, in
source code and object code form. This patent license shall apply to the
combination of the Contribution and the Program if, at the time the
Contribution is added by the Contributor, such addition of the
Contribution causes such combination to be covered by the Licensed
Patents. The patent license shall not apply to any other combinations
which include the Contribution. No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the
licenses to its Contributions set forth herein, no assurances are
provided by any Contributor that the Program does not infringe the
patent or other intellectual property rights of any other entity. Each
Contributor disclaims any liability to Recipient for claims brought by
any other entity based on infringement of intellectual property rights
or otherwise. As a condition to exercising the rights and licenses
granted hereunder, each Recipient hereby assumes sole responsibility to
secure any other intellectual property rights needed, if any. For
example, if a third party patent license is required to allow Recipient
to distribute the Program, it is Recipient's responsibility to acquire
that license before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright
license set forth in this Agreement.
*3. REQUIREMENTS*
A Contributor may choose to distribute the Program in object code form
under its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties
and conditions, express and implied, including warranties or conditions
of title and non-infringement, and implied warranties or conditions of
merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and
consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are
offered by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable
manner on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained
within the Program.
Each Contributor must identify itself as the originator of its
Contribution, if any, in a manner that reasonably allows subsequent
Recipients to identify the originator of the Contribution.
*4. COMMERCIAL DISTRIBUTION*
Commercial distributors of software may accept certain responsibilities
with respect to end users, business partners and the like. While this
license is intended to facilitate the commercial use of the Program, the
Contributor who includes the Program in a commercial product offering
should do so in a manner which does not create potential liability for
other Contributors. Therefore, if a Contributor includes the Program in
a commercial product offering, such Contributor ("Commercial
Contributor") hereby agrees to defend and indemnify every other
Contributor ("Indemnified Contributor") against any losses, damages and
costs (collectively "Losses") arising from claims, lawsuits and other
legal actions brought by a third party against the Indemnified
Contributor to the extent caused by the acts or omissions of such
Commercial Contributor in connection with its distribution of the
Program in a commercial product offering. The obligations in this
section do not apply to any claims or Losses relating to any actual or
alleged intellectual property infringement. In order to qualify, an
Indemnified Contributor must: a) promptly notify the Commercial
Contributor in writing of such claim, and b) allow the Commercial
Contributor to control, and cooperate with the Commercial Contributor
in, the defense and any related settlement negotiations. The Indemnified
Contributor may participate in any such claim at its own expense.
For example, a Contributor might include the Program in a commercial
product offering, Product X. That Contributor is then a Commercial
Contributor. If that Commercial Contributor then makes performance
claims, or offers warranties related to Product X, those performance
claims and warranties are such Commercial Contributor's responsibility
alone. Under this section, the Commercial Contributor would have to
defend claims against the other Contributors related to those
performance claims and warranties, and if a court requires any other
Contributor to pay any damages as a result, the Commercial Contributor
must pay those damages.
*5. NO WARRANTY*
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
A PARTICULAR PURPOSE. Each Recipient is solely responsible for
determining the appropriateness of using and distributing the Program
and assumes all risks associated with its exercise of rights under this
Agreement , including but not limited to the risks and costs of program
errors, compliance with applicable laws, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
*6. DISCLAIMER OF LIABILITY*
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*7. GENERAL*
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this Agreement, and without further action
by the parties hereto, such provision shall be reformed to the minimum
extent necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including
a cross-claim or counterclaim in a lawsuit) alleging that the Program
itself (excluding combinations of the Program with other software or
hardware) infringes such Recipient's patent(s), then such Recipient's
rights granted under Section 2(b) shall terminate as of the date such
litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails
to comply with any of the material terms or conditions of this Agreement
and does not cure such failure in a reasonable period of time after
becoming aware of such noncompliance. If all Recipient's rights under
this Agreement terminate, Recipient agrees to cease use and distribution
of the Program as soon as reasonably practicable. However, Recipient's
obligations under this Agreement and any licenses granted by Recipient
relating to the Program shall continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement,
but in order to avoid inconsistency the Agreement is copyrighted and may
only be modified in the following manner. The Agreement Steward reserves
the right to publish new versions (including revisions) of this
Agreement from time to time. No one other than the Agreement Steward has
the right to modify this Agreement. The Eclipse Foundation is the
initial Agreement Steward. The Eclipse Foundation may assign the
responsibility to serve as the Agreement Steward to a suitable separate
entity. Each new version of the Agreement will be given a distinguishing
version number. The Program (including Contributions) may always be
distributed subject to the version of the Agreement under which it was
received. In addition, after a new version of the Agreement is
published, Contributor may elect to distribute the Program (including
its Contributions) under the new version. Except as expressly stated in
Sections 2(a) and 2(b) above, Recipient receives no rights or licenses
to the intellectual property of any Contributor under this Agreement,
whether expressly, by implication, estoppel or otherwise. All rights in
the Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to
this Agreement will bring a legal action under this Agreement more than
one year after the cause of action arose. Each party waives its rights
to a jury trial in any resulting litigation.

View File

@@ -1,7 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
sdkstats.jar,\
plugin.xml,\
androidprefs.jar

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension
id="com.android.ide.eclipse.common.xmlProblem"
name="XML Problem"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.problemmarker"/>
<super type="org.eclipse.core.resources.textmarker"/>
<persistent value="true"/>
</extension>
<extension
id="com.android.ide.eclipse.common.aaptProblem"
name="aapt Problem"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.problemmarker"/>
<super type="org.eclipse.core.resources.textmarker"/>
<persistent value="true"/>
</extension>
<extension
id="com.android.ide.eclipse.common.aidlProblem"
name="aidl Problem"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.problemmarker"/>
<super type="org.eclipse.core.resources.textmarker"/>
<persistent value="true"/>
</extension>
<extension
id="com.android.ide.eclipse.common.androidProblem"
name="Android Problem"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.problemmarker"/>
<super type="org.eclipse.core.resources.textmarker"/>
<persistent value="true"/>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
category="com.android.ide.eclipse.preferences.main"
class="com.android.ide.eclipse.common.preferences.UsagePreferencePage"
id="com.android.ide.eclipse.common.preferences.UsagePreferencePage"
name="Usage Stats"/>
</extension>
</plugin>

View File

@@ -1,340 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common;
import java.io.File;
/**
* Constant definition class.<br>
* <br>
* Most constants have a prefix defining the content.
* <ul>
* <li><code>WS_</code> Workspace path constant. Those are absolute paths,
* from the project root.</li>
* <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
* <li><code>FN_</code> File name constant.</li>
* <li><code>FD_</code> Folder name constant.</li>
* <li><code>MARKER_</code> Resource Marker Ids constant.</li>
* <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
* <li><code>DOT_</code> File extension constant. This start with a dot.</li>
* <li><code>RE_</code> Regexp constant.</li>
* <li><code>NS_</code> Namespace constant.</li>
* <li><code>CLASS_</code> Fully qualified class name.</li>
* </ul>
*
*/
public class AndroidConstants {
/** The Editors Plugin ID */
public static final String EDITORS_PLUGIN_ID = "com.android.ide.eclipse.editors"; // $NON-NLS-1$
/** Nature of android projects */
public final static String NATURE = "com.android.ide.eclipse.adt.AndroidNature"; //$NON-NLS-1$
public final static int PLATFORM_UNKNOWN = 0;
public final static int PLATFORM_LINUX = 1;
public final static int PLATFORM_WINDOWS = 2;
public final static int PLATFORM_DARWIN = 3;
/**
* Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
*/
public final static int CURRENT_PLATFORM = currentPlatform();
/** Separator for workspace path, i.e. "/". */
public final static String WS_SEP = "/"; //$NON-NLS-1$
/** Separator character for workspace path, i.e. '/'. */
public final static char WS_SEP_CHAR = '/';
/** Extension of the Application package Files, i.e. "apk". */
public final static String EXT_ANDROID_PACKAGE = "apk"; //$NON-NLS-1$
/** Extension of java files, i.e. "java" */
public final static String EXT_JAVA = "java"; //$NON-NLS-1$
/** Extension of compiled java files, i.e. "class" */
public final static String EXT_CLASS = "class"; //$NON-NLS-1$
/** Extension of xml files, i.e. "xml" */
public final static String EXT_XML = "xml"; //$NON-NLS-1$
/** Extension of jar files, i.e. "jar" */
public final static String EXT_JAR = "jar"; //$NON-NLS-1$
/** Extension of aidl files, i.e. "aidl" */
public final static String EXT_AIDL = "aidl"; //$NON-NLS-1$
private final static String DOT = "."; //$NON-NLS-1$
/** Dot-Extension of the Application package Files, i.e. ".apk". */
public final static String DOT_ANDROID_PACKAGE = DOT + EXT_ANDROID_PACKAGE;
/** Dot-Extension of java files, i.e. ".java" */
public final static String DOT_JAVA = DOT + EXT_JAVA;
/** Dot-Extension of compiled java files, i.e. ".class" */
public final static String DOT_CLASS = DOT + EXT_CLASS;
/** Dot-Extension of xml files, i.e. ".xml" */
public final static String DOT_XML = DOT + EXT_XML;
/** Dot-Extension of jar files, i.e. ".jar" */
public final static String DOT_JAR = DOT + EXT_JAR;
/** Dot-Extension of aidl files, i.e. ".aidl" */
public final static String DOT_AIDL = DOT + EXT_AIDL;
/** Name of the manifest file, i.e. "AndroidManifest.xml". */
public static final String FN_ANDROID_MANIFEST = "AndroidManifest.xml"; //$NON-NLS-1$
/** Name of the framework library, i.e. "android.jar" */
public static final String FN_FRAMEWORK_LIBRARY = "android.jar"; //$NON-NLS-1$
/** Name of the layout attributes, i.e. "attrs.xml" */
public static final String FN_ATTRS_XML = "attrs.xml"; //$NON-NLS-1$
/** Name of the layout attributes, i.e. "attrs_manifest.xml" */
public static final String FN_ATTRS_MANIFEST_XML = "attrs_manifest.xml"; //$NON-NLS-1$
/** framework aidl import file */
public static final String FN_FRAMEWORK_AIDL = "framework.aidl"; //$NON-NLS-1$
/** layoutlib.jar file */
public static final String FN_LAYOUTLIB_JAR = "layoutlib.jar"; //$NON-NLS-1$
/** dex.jar file */
public static final String FN_DX_JAR = "dx.jar"; //$NON-NLS-1$
/** Name of the android sources directory */
public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$
/** Resource java class filename, i.e. "R.java" */
public final static String FN_RESOURCE_CLASS = "R.java"; //$NON-NLS-1$
/** Resource class file filename, i.e. "R.class" */
public final static String FN_COMPILED_RESOURCE_CLASS = "R.class"; //$NON-NLS-1$
/** Manifest java class filename, i.e. "Manifest.java" */
public final static String FN_MANIFEST_CLASS = "Manifest.java"; //$NON-NLS-1$
/** Dex conversion output filname, i.e. "classes.dex" */
public final static String FN_CLASSES_DEX = "classes.dex"; //$NON-NLS-1$
/** Temporary packaged resources file name, i.e. "resources.ap_" */
public final static String FN_RESOURCES_AP_ = "resources.ap_"; //$NON-NLS-1$
/** build properties file */
public final static String FN_BUILD_PROP = "build.prop"; //$NON-NLS-1$
/** plugin properties file */
public final static String FN_PLUGIN_PROP = "plugin.prop"; //$NON-NLS-1$
public final static String FN_ADB = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"adb.exe" : "adb"; //$NON-NLS-1$ //$NON-NLS-2$
public final static String FN_AAPT = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"aapt.exe" : "aapt"; //$NON-NLS-1$ //$NON-NLS-2$
public final static String FN_AIDL = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"aidl.exe" : "aidl"; //$NON-NLS-1$ //$NON-NLS-2$
public final static String FN_EMULATOR = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"emulator.exe" : "emulator"; //$NON-NLS-1$ //$NON-NLS-2$
public final static String FN_TRACEVIEW = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"traceview.exe" : "traceview"; //$NON-NLS-1$ //$NON-NLS-2$
/** Skin layout file */
public final static String FN_LAYOUT = "layout";//$NON-NLS-1$
/** Resources folder name, i.e. "res". */
public final static String FD_RESOURCES = "res"; //$NON-NLS-1$
/** Assets folder name, i.e. "assets" */
public final static String FD_ASSETS = "assets"; //$NON-NLS-1$
/** Default source folder name, i.e. "src" */
public final static String FD_SOURCES = "src"; //$NON-NLS-1$
/** Default bin folder name, i.e. "bin" */
public final static String FD_BINARIES = "bin"; //$NON-NLS-1$
/** Default anim resource folder name, i.e. "anim" */
public final static String FD_ANIM = "anim"; //$NON-NLS-1$
/** Default color resource folder name, i.e. "color" */
public final static String FD_COLOR = "color"; //$NON-NLS-1$
/** Default drawable resource folder name, i.e. "drawable" */
public final static String FD_DRAWABLE = "drawable"; //$NON-NLS-1$
/** Default layout resource folder name, i.e. "layout" */
public final static String FD_LAYOUT = "layout"; //$NON-NLS-1$
/** Default menu resource folder name, i.e. "menu" */
public final static String FD_MENU = "menu"; //$NON-NLS-1$
/** Default values resource folder name, i.e. "values" */
public final static String FD_VALUES = "values"; //$NON-NLS-1$
/** Default xml resource folder name, i.e. "xml" */
public final static String FD_XML = "xml"; //$NON-NLS-1$
/** Default raw resource folder name, i.e. "raw" */
public final static String FD_RAW = "raw"; //$NON-NLS-1$
/** Name of the tools folder. */
public final static String FD_TOOLS = "tools"; //$NON-NLS-1$
/** Name of the libs folder. */
public final static String FD_LIBS = "lib"; //$NON-NLS-1$
/** Name of the docs folder. */
public final static String FD_DOCS = "docs"; //$NON-NLS-1$
/** Name of the images folder. */
public final static String FD_IMAGES = "images"; //$NON-NLS-1$
/** Name of the skins folder. */
public final static String FD_SKINS = "skins"; //$NON-NLS-1$
/** Name of the samples folder. */
public final static String FD_SAMPLES = "samples"; //$NON-NLS-1$
/** Name of the folder containing the default framework resources. */
public final static String FD_DEFAULT_RES = "default"; //$NON-NLS-1$
/** SDK font folder name, i.e. "fonts" */
public final static String FD_FONTS = "fonts"; //$NON-NLS-1$
/** Absolute path of the workspace root, i.e. "/" */
public final static String WS_ROOT = WS_SEP;
/** Absolute path of the resource folder, eg "/res".<br> This is a workspace path. */
public final static String WS_RESOURCES = WS_SEP + FD_RESOURCES;
/** Absolute path of the resource folder, eg "/assets".<br> This is a workspace path. */
public final static String WS_ASSETS = WS_SEP + FD_ASSETS;
/** Leaf of the javaDoc folder. Does not start with a separator. */
public final static String WS_JAVADOC_FOLDER_LEAF = FD_DOCS + "/reference"; //$NON-NLS-1$
/** Path of the documentation directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_DOCS_FOLDER = FD_DOCS + File.separator;
/** Path of the tools directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_TOOLS_FOLDER = FD_TOOLS + File.separator;
/** Path of the samples directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_SAMPLES_FOLDER = FD_SAMPLES + File.separator;
/** Path of the lib directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_LIBS_FOLDER =
OS_SDK_TOOLS_FOLDER + FD_LIBS + File.separator;
/** Path of the resources directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_RESOURCES_FOLDER =
OS_SDK_LIBS_FOLDER + FD_RESOURCES + File.separator;
/** Path of the resources directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_FONTS_FOLDER =
OS_SDK_LIBS_FOLDER + FD_FONTS + File.separator;
/** Path of the skin directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_SKINS_FOLDER =
OS_SDK_LIBS_FOLDER + FD_IMAGES + File.separator + FD_SKINS + File.separator;
/** Path of the attrs.xml file relative to the sdk folder. */
public final static String OS_SDK_ATTRS_XML =
OS_SDK_RESOURCES_FOLDER + File.separator + FD_DEFAULT_RES + File.separator +
FD_VALUES + File.separator + FN_ATTRS_XML;
/** Path of the attrs_manifest.xml file relative to the sdk folder. */
public final static String OS_SDK_ATTRS_MANIFEST_XML =
OS_SDK_RESOURCES_FOLDER + File.separator + FD_DEFAULT_RES + File.separator +
FD_VALUES + File.separator + FN_ATTRS_MANIFEST_XML;
/** Path of the layoutlib.jar file relative to the sdk folder. */
public final static String OS_SDK_LIBS_LAYOUTLIB_JAR =
OS_SDK_LIBS_FOLDER + FN_LAYOUTLIB_JAR;
/** Path of the dx.jar file relative to the sdk folder. */
public final static String OS_SDK_LIBS_DX_JAR =
OS_SDK_LIBS_FOLDER + FN_DX_JAR;
/** Regexp for single dot */
public final static String RE_DOT = "\\."; //$NON-NLS-1$
/** Regexp for java extension, i.e. "\.java$" */
public final static String RE_JAVA_EXT = "\\.java$"; //$NON-NLS-1$
/** Regexp for aidl extension, i.e. "\.aidl$" */
public final static String RE_AIDL_EXT = "\\.aidl$"; //$NON-NLS-1$
/** Namespace for the resource XML, i.e. "http://schemas.android.com/apk/res/android" */
public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android"; //$NON-NLS-1$
/** Namespace pattern for the custom resource XML, i.e. "http://schemas.android.com/apk/res/%s" */
public final static String NS_CUSTOM_RESOURCES = "http://schemas.android.com/apk/res/%1$s"; //$NON-NLS-1$
/** aapt marker error. */
public final static String MARKER_AAPT = CommonPlugin.PLUGIN_ID + ".aaptProblem"; //$NON-NLS-1$
/** XML marker error. */
public final static String MARKER_XML = CommonPlugin.PLUGIN_ID + ".xmlProblem"; //$NON-NLS-1$
/** aidl marker error. */
public final static String MARKER_AIDL = CommonPlugin.PLUGIN_ID + ".aidlProblem"; //$NON-NLS-1$
/** android marker error */
public final static String MARKER_ANDROID = CommonPlugin.PLUGIN_ID + ".androidProblem"; //$NON-NLS-1$
/** Name for the "type" marker attribute */
public final static String MARKER_ATTR_TYPE = "android.type"; //$NON-NLS-1$
/** Name for the "class" marker attribute */
public final static String MARKER_ATTR_CLASS = "android.class"; //$NON-NLS-1$
/** activity value for marker attribute "type" */
public final static String MARKER_ATTR_TYPE_ACTIVITY = "activity"; //$NON-NLS-1$
/** service value for marker attribute "type" */
public final static String MARKER_ATTR_TYPE_SERVICE = "service"; //$NON-NLS-1$
/** receiver value for marker attribute "type" */
public final static String MARKER_ATTR_TYPE_RECEIVER = "receiver"; //$NON-NLS-1$
/** provider value for marker attribute "type" */
public final static String MARKER_ATTR_TYPE_PROVIDER = "provider"; //$NON-NLS-1$
public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$
public final static String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$
public final static String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$
public final static String CLASS_CONTENTPROVIDER = "android.content.ContentProvider"; //$NON-NLS-1$
public final static String CLASS_INSTRUMENTATION = "android.app.Instrumentation"; //$NON-NLS-1$
public final static String CLASS_BUNDLE = "android.os.Bundle"; //$NON-NLS-1$
public final static String CLASS_R = "android.R"; //$NON-NLS-1$
public final static String CLASS_MANIFEST_PERMISSION = "android.Manifest$permission"; //$NON-NLS-1$
public final static String CLASS_INTENT = "android.content.Intent"; //$NON-NLS-1$
public final static String CLASS_CONTEXT = "android.content.Context"; //$NON-NLS-1$
public final static String CLASS_VIEW = "android.view.View"; //$NON-NLS-1$
public final static String CLASS_VIEWGROUP = "android.view.ViewGroup"; //$NON-NLS-1$
public final static String CLASS_LAYOUTPARAMS = "LayoutParams"; //$NON-NLS-1$
public final static String CLASS_VIEWGROUP_LAYOUTPARAMS =
CLASS_VIEWGROUP + "$" + CLASS_LAYOUTPARAMS; //$NON-NLS-1$
public final static String CLASS_FRAMELAYOUT = "FrameLayout"; //$NON-NLS-1$
public final static String CLASS_PREFERENCE = "android.preference.Preference"; //$NON-NLS-1$
public final static String CLASS_PREFERENCE_SCREEN = "PreferenceScreen"; //$NON-NLS-1$
public final static String CLASS_PREFERENCES =
"android.preference." + CLASS_PREFERENCE_SCREEN; //$NON-NLS-1$
public final static String CLASS_PREFERENCEGROUP = "android.preference.PreferenceGroup"; //$NON-NLS-1$
public final static String CLASS_BRIDGE = "com.android.layoutlib.bridge.Bridge"; //$NON-NLS-1$
/**
* Prefered compiler level, i.e. "1.5".
*/
public final static String COMPILER_COMPLIANCE_PREFERRED = "1.5"; //$NON-NLS-1$
/**
* List of valid compiler level, i.e. "1.5" and "1.6"
*/
public final static String[] COMPILER_COMPLIANCE = {
"1.5", //$NON-NLS-1$
"1.6", //$NON-NLS-1$
};
/** The base URL where to find the Android class & manifest documentation */
public static final String CODESITE_BASE_URL = "http://code.google.com/android"; //$NON-NLS-1$
/**
* Returns current platform
*
* @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
*/
private static int currentPlatform() {
String os = System.getProperty("os.name"); //$NON-NLS-1$
if (os.startsWith("Mac OS")) { //$NON-NLS-1$
return PLATFORM_DARWIN;
} else if (os.startsWith("Windows")) { //$NON-NLS-1$
return PLATFORM_WINDOWS;
} else if (os.startsWith("Linux")) { //$NON-NLS-1$
return PLATFORM_LINUX;
}
return PLATFORM_UNKNOWN;
}
}

View File

@@ -1,165 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class CommonPlugin extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.android.ide.eclipse.common"; // $NON-NLS-1$
// The shared instance
private static CommonPlugin sPlugin;
// The global android console
private MessageConsole mAndroidConsole;
/**
* The constructor
*/
public CommonPlugin() {
// pass
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static CommonPlugin getDefault() {
return sPlugin;
}
/** Returns the global android console */
public MessageConsole getAndroidConsole() {
return mAndroidConsole;
}
/**
* The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
* method refreshes the plug-in actions. Subclasses may extend this method,
* but must send super <b>first</b>.
*
* {@inheritDoc}
*/
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
sPlugin = this;
/*
* WARNING: think before adding any initialization here as plugins are dynamically
* started and since no UI is being displayed by this plugin, it'll only start when
* another plugin accesses some of its code.
*/
// set the default android console.
mAndroidConsole = new MessageConsole("Android", null); //$NON-NLS-1$
ConsolePlugin.getDefault().getConsoleManager().addConsoles(
new IConsole[] { mAndroidConsole });
}
/**
* The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
* method saves this plug-in's preference and dialog stores and shuts down
* its image registry (if they are in use). Subclasses may extend this
* method, but must send super <b>last</b>. A try-finally statement should
* be used where necessary to ensure that <code>super.shutdown()</code> is
* always done.
*
* {@inheritDoc}
*/
@Override
public void stop(BundleContext context) throws Exception {
sPlugin = null;
super.stop(context);
}
/**
* Logs a message to the default Eclipse log.
*
* @param severity One of IStatus' severity codes: OK, ERROR, INFO, WARNING or CANCEL.
* @param format The format string, like for String.format().
* @param args The arguments for the format string, like for String.format().
*/
public static void log(int severity, String format, Object ... args) {
String message = String.format(format, args);
Status status = new Status(severity, PLUGIN_ID, message);
getDefault().getLog().log(status);
}
/**
* Logs an exception to the default Eclipse log.
* <p/>
* The status severity is always set to ERROR.
*
* @param exception The exception to log. Its call trace will be recorded.
* @param format The format string, like for String.format().
* @param args The arguments for the format string, like for String.format().
*/
public static void log(Throwable exception, String format, Object ... args) {
String message = String.format(format, args);
Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
getDefault().getLog().log(status);
}
private static Display getDisplay() {
IWorkbench bench = sPlugin.getWorkbench();
if (bench!=null) {
return bench.getDisplay();
}
return null;
}
/**
* Display a yes/no question dialog box. This dialog is opened synchronously in the ui thread,
* therefore this message can be called from any thread.
* @param title The title of the dialog box
* @param message The error message
* @return true if OK was clicked.
*/
public final static boolean displayPrompt(final String title, final String message) {
// get the current Display and Shell
final Display display = getDisplay();
// we need to ask the user what he wants to do.
final Boolean[] wrapper = new Boolean[] { new Boolean(false) };
display.syncExec(new Runnable() {
public void run() {
Shell shell = display.getActiveShell();
wrapper[0] = new Boolean(MessageDialog.openQuestion(shell, title, message));
}
});
return wrapper[0].booleanValue();
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
/**
* Helpers for Eclipse UI related stuff.
*/
public final class EclipseUiHelper {
/** View Id for the default Eclipse Content Outline view. */
public static final String CONTENT_OUTLINE_VIEW_ID = "org.eclipse.ui.views.ContentOutline";
/** View Id for the default Eclipse Property Sheet view. */
public static final String PROPERTY_SHEET_VIEW_ID = "org.eclipse.ui.views.PropertySheet";
/** This class never gets instantiated. */
private EclipseUiHelper() {
}
/**
* Shows the corresponding view.
* <p/>
* Silently fails in case of error.
*
* @param viewId One of {@link #CONTENT_OUTLINE_VIEW_ID}, {@link #PROPERTY_SHEET_VIEW_ID}.
* @param activate True to force activate (i.e. takes focus), false to just make visible (i.e.
* does not steal focus.)
*/
public static void showView(String viewId, boolean activate) {
IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (win != null) {
IWorkbenchPage page = win.getActivePage();
if (page != null) {
try {
IViewPart part = page.showView(viewId,
null /* secondaryId */,
activate ? page.VIEW_ACTIVATE : page.VIEW_VISIBLE);
} catch (PartInitException e) {
// ignore
}
}
}
}
}

View File

@@ -1,21 +0,0 @@
package com.android.ide.eclipse.common;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "com.android.ide.eclipse.common.messages"; //$NON-NLS-1$
public static String Console_Data_Project_Tag;
public static String Console_Date_Tag;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common;
import com.android.sdkstats.SdkStatsService;
import org.osgi.framework.Version;
/**
* Helper class to access the ping usage stat server.
*/
public class SdkStatsHelper {
/**
* Pings the usage start server.
* @param pluginName the name of the plugin to appear in the stats
* @param pluginVersion the {@link Version} of the plugin.
*/
public static void pingUsageServer(String pluginName, Version pluginVersion) {
String versionString = String.format("%1$d.%2$d.%3$d", pluginVersion.getMajor(),
pluginVersion.getMinor(), pluginVersion.getMicro());
SdkStatsService.ping(pluginName, versionString);
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common;
import org.eclipse.ui.console.MessageConsoleStream;
import java.util.Calendar;
/**
* Stream helper class.
*/
public class StreamHelper {
/**
* Prints messages, associated with a project to the specified stream
* @param stream The stream to write to
* @param tag The tag associated to the message. Can be null
* @param objects The objects to print through their toString() method (or directly for
* {@link String} objects.
*/
public static synchronized void printToStream(MessageConsoleStream stream, String tag,
Object... objects) {
String dateTag = getMessageTag(tag);
for (Object obj : objects) {
stream.print(dateTag);
if (obj instanceof String) {
stream.println((String)obj);
} else {
stream.println(obj.toString());
}
}
}
/**
* Creates a string containing the current date/time, and the tag
* @param tag The tag associated to the message. Can be null
* @return The dateTag
*/
public static String getMessageTag(String tag) {
Calendar c = Calendar.getInstance();
if (tag == null) {
return String.format(Messages.Console_Date_Tag, c);
}
return String.format(Messages.Console_Data_Project_Tag, c, tag);
}
}

View File

@@ -1,2 +0,0 @@
Console_Date_Tag=[%1$tF %1$tT]
Console_Data_Project_Tag=[%1$tF %1$tT - %2$s]

View File

@@ -1,123 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.preferences;
import com.android.sdkstats.SdkStatsService;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import java.io.IOException;
public class UsagePreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private BooleanFieldEditor mOptInCheckBox;
public UsagePreferencePage() {
}
public void init(IWorkbench workbench) {
// pass
}
@Override
protected Control createContents(Composite parent) {
Composite top = new Composite(parent, SWT.NONE);
top.setLayout(new GridLayout(1, false));
top.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Link text = new Link(top, SWT.WRAP);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = 200;
text.setLayoutData(gd);
text.setText(SdkStatsService.BODY_TEXT);
text.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
SdkStatsService.openUrl(event.text);
}
});
mOptInCheckBox = new BooleanFieldEditor(SdkStatsService.PING_OPT_IN,
SdkStatsService.CHECKBOX_TEXT, top);
mOptInCheckBox.setPage(this);
mOptInCheckBox.setPreferenceStore(SdkStatsService.getPreferenceStore());
mOptInCheckBox.load();
return top;
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performCancel()
*/
@Override
public boolean performCancel() {
mOptInCheckBox.load();
return super.performCancel();
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performDefaults()
*/
@Override
protected void performDefaults() {
mOptInCheckBox.loadDefault();
super.performDefaults();
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performOk()
*/
@Override
public boolean performOk() {
save();
return super.performOk();
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performApply()
*/
@Override
protected void performApply() {
save();
super.performApply();
}
private void save() {
try {
PreferenceStore store = SdkStatsService.getPreferenceStore();
if (store != null) {
store.setValue(SdkStatsService.PING_OPT_IN, mOptInCheckBox.getBooleanValue());
store.save();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,241 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.xml.sax.InputSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
/**
* Utility class that manages the AndroidManifest.xml file.
* <p/>
* All the get method work by XPath. Repeated calls to those may warrant using
* {@link AndroidManifestParser} instead.
*/
public class AndroidManifestHelper {
private IFile mManifestIFile;
private File mManifestFile;
private XPath mXPath;
/**
* Creates an AndroidManifest based on an existing Eclipse {@link IProject} object.
* </p>
* Use {@link #exists()} to check if the manifest file really exists in the project.
*
* @param project The project to search for the manifest.
*/
public AndroidManifestHelper(IProject project) {
mXPath = AndroidXPathFactory.newXPath();
mManifestIFile = getManifest(project);
}
/**
* Creates an AndroidManifest based on a file path.
* <p/>
* Use {@link #exists()} to check if the manifest file really exists.
*
* @param osManifestFilePath the os path to the AndroidManifest.xml file.
*/
public AndroidManifestHelper(String osManifestFilePath) {
mXPath = AndroidXPathFactory.newXPath();
mManifestFile = new File(osManifestFilePath);
}
/**
* Returns the underlying {@link IFile} for the android manifest XML file, if found in the
* given Eclipse project.
*
* Always return null if the constructor that takes an {@link IProject} was NOT called.
*
* @return The IFile for the androidManifest.xml or null if no such file could be found.
*/
public IFile getManifestIFile() {
return mManifestIFile;
}
/**
* Returns the underlying {@link File} for the android manifest XML file.
*/
public File getManifestFile() {
if (mManifestIFile != null) {
return mManifestIFile.getLocation().toFile();
}
return mManifestFile;
}
/**
* Returns the package name defined in the manifest file.
*
* @return A String object with the package or null if any error happened.
*/
public String getPackageName() {
try {
return getPackageNameInternal(mXPath, getSource());
} catch (XPathExpressionException e1) {
// If the XPath failed to evaluate, we'll return null.
} catch (Exception e) {
// if this happens this is due to the resource being out of sync.
// so we must refresh it and do it again
// for any other kind of exception we must return null as well;
}
return null;
}
/**
* Returns the i-th activity defined in the manifest file.
*
* @param manifest The manifest's IFile object.
* @param index The 1-based index of the activity to return.
* @param xpath An optional xpath object. If null is provided a new one will
* be created.
* @return A String object with the activity or null if any error happened.
*/
public String getActivityName(int index) {
try {
return getActivityNameInternal(index, mXPath, getSource());
} catch (XPathExpressionException e1) {
// If the XPath failed to evaluate, we'll return null.
} catch (Exception e) {
// if this happens this is due to the resource being out of sync.
// so we must refresh it and do it again
// for any other kind of exception we must return null as well;
}
return null;
}
/**
* Returns an IFile object representing the manifest for the specified
* project.
*
* @param project The project containing the manifest file.
* @return An IFile object pointing to the manifest or null if the manifest
* is missing.
*/
public static IFile getManifest(IProject project) {
IResource r = project.findMember(AndroidConstants.WS_SEP
+ AndroidConstants.FN_ANDROID_MANIFEST);
if (r == null || r.exists() == false || (r instanceof IFile) == false) {
return null;
}
return (IFile) r;
}
/**
* Combines a java package, with a class value from the manifest to make a fully qualified
* class name
* @param javaPackage the java package from the manifest.
* @param className the class name from the manifest.
* @return the fully qualified class name.
*/
public static String combinePackageAndClassName(String javaPackage, String className) {
if (className == null || className.length() == 0) {
return javaPackage;
}
if (javaPackage == null || javaPackage.length() == 0) {
return className;
}
// the class name can be a subpackage (starts with a '.'
// char), a simple class name (no dot), or a full java package
boolean startWithDot = (className.charAt(0) == '.');
boolean hasDot = (className.indexOf('.') != -1);
if (startWithDot || hasDot == false) {
// add the concatenation of the package and class name
if (startWithDot) {
return javaPackage + className;
} else {
return javaPackage + '.' + className;
}
} else {
// just add the class as it should be a fully qualified java name.
return className;
}
}
/**
* Returns true either if an androidManifest.xml file was found in the project
* or if the given file path exists.
*/
public boolean exists() {
if (mManifestIFile != null) {
return mManifestIFile.exists();
} else if (mManifestFile != null) {
return mManifestFile.exists();
}
return false;
}
/**
* Returns an InputSource for XPath.
*
* @throws FileNotFoundException if file does not exist.
* @throws CoreException if the {@link IFile} does not exist.
*/
private InputSource getSource() throws FileNotFoundException, CoreException {
if (mManifestIFile != null) {
return new InputSource(mManifestIFile.getContents());
} else if (mManifestFile != null) {
return new InputSource(new FileReader(mManifestFile));
}
return null;
}
/**
* Performs the actual XPath evaluation to get the package name.
* Extracted so that we can share it with AndroidManifestFromProject.
*/
private static String getPackageNameInternal(XPath xpath, InputSource source)
throws XPathExpressionException {
return xpath.evaluate("/manifest/@package", source); //$NON-NLS-1$
}
/**
* Performs the actual XPath evaluation to get the activity name.
* Extracted so that we can share it with AndroidManifestFromProject.
*/
private static String getActivityNameInternal(int index, XPath xpath, InputSource source)
throws XPathExpressionException {
return xpath.evaluate("/manifest/application/activity[" //$NON-NLS-1$
+ index
+ "]/@" //$NON-NLS-1$
+ AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$
source);
}
}

View File

@@ -1,632 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.XmlErrorHandler.XmlErrorListener;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaProject;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class AndroidManifestParser {
private final static String ATTRIBUTE_PACKAGE = "package"; //$NON-NLS-1$
private final static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
private final static String ATTRIBUTE_PROCESS = "process"; //$NON-NLS-$
private final static String ATTRIBUTE_DEBUGGABLE = "debuggable"; //$NON-NLS-$
private final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
private final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
private final static String NODE_ACTIVITY = "activity"; //$NON-NLS-1$
private final static String NODE_SERVICE = "service"; //$NON-NLS-1$
private final static String NODE_RECEIVER = "receiver"; //$NON-NLS-1$
private final static String NODE_PROVIDER = "provider"; //$NON-NLS-1$
private final static String NODE_INTENT = "intent-filter"; //$NON-NLS-1$
private final static String NODE_ACTION = "action"; //$NON-NLS-1$
private final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
private final static int LEVEL_MANIFEST = 0;
private final static int LEVEL_APPLICATION = 1;
private final static int LEVEL_ACTIVITY = 2;
private final static int LEVEL_INTENT_FILTER = 3;
private final static int LEVEL_CATEGORY = 4;
private final static String ACTION_MAIN = "android.intent.action.MAIN"; //$NON-NLS-1$
private final static String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; //$NON-NLS-1$
private static class ManifestHandler extends XmlErrorHandler {
//--- data read from the parsing
/** Application package */
private String mPackage;
/** List of all activities */
private final ArrayList<String> mActivities = new ArrayList<String>();
/** Launcher activity */
private String mLauncherActivity = null;
/** list of process names declared by the manifest */
private Set<String> mProcesses = null;
/** debuggable attribute value. If null, the attribute is not present. */
private Boolean mDebuggable = null;
//--- temporary data/flags used during parsing
private IJavaProject mJavaProject;
private boolean mGatherData = false;
private boolean mMarkErrors = false;
private int mCurrentLevel = 0;
private int mValidLevel = 0;
private boolean mFoundMainAction = false;
private boolean mFoundLauncherCategory = false;
private String mCurrentActivity = null;
private Locator mLocator;
/**
*
* @param manifestFile
* @param errorListener
* @param gatherData
* @param javaProject
* @param markErrors
*/
ManifestHandler(IFile manifestFile, XmlErrorListener errorListener,
boolean gatherData, IJavaProject javaProject, boolean markErrors) {
super(manifestFile, errorListener);
mGatherData = gatherData;
mJavaProject = javaProject;
mMarkErrors = markErrors;
}
/**
* Returns the package defined in the manifest, if found.
* @return The package name or null if not found.
*/
String getPackage() {
return mPackage;
}
/**
* Returns the list of activities found in the manifest.
* @return An array of fully qualified class names, or empty if no activity were found.
*/
String[] getActivities() {
return mActivities.toArray(new String[mActivities.size()]);
}
/**
* Returns the name of one activity found in the manifest, that is configured to show
* up in the HOME screen.
* @return the fully qualified name of a HOME activity or null if none were found.
*/
String getLauncherActivity() {
return mLauncherActivity;
}
/**
* Returns the list of process names declared by the manifest.
*/
String[] getProcesses() {
if (mProcesses != null) {
return mProcesses.toArray(new String[mProcesses.size()]);
}
return new String[0];
}
/**
* Returns the debuggable attribute value or null if it is not set.
*/
Boolean getDebuggable() {
return mDebuggable;
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
*/
@Override
public void setDocumentLocator(Locator locator) {
mLocator = locator;
super.setDocumentLocator(locator);
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String,
* java.lang.String, org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
try {
if (mGatherData == false) {
return;
}
// if we're at a valid level
if (mValidLevel == mCurrentLevel) {
String processName;
switch (mValidLevel) {
case LEVEL_MANIFEST:
if (NODE_MANIFEST.equals(localName)) {
// lets get the package name.
mPackage = getAttributeValue(attributes, ATTRIBUTE_PACKAGE,
false /* hasNamespace */);
mValidLevel++;
}
break;
case LEVEL_APPLICATION:
if (NODE_APPLICATION.equals(localName)) {
processName = getAttributeValue(attributes, ATTRIBUTE_PROCESS,
true /* hasNamespace */);
if (processName != null) {
addProcessName(processName);
}
String debuggable = getAttributeValue(attributes,
ATTRIBUTE_DEBUGGABLE, true /* hasNamespace*/);
if (debuggable != null) {
mDebuggable = Boolean.parseBoolean(debuggable);
}
mValidLevel++;
}
break;
case LEVEL_ACTIVITY:
if (NODE_ACTIVITY.equals(localName)) {
processActivityNode(attributes);
mValidLevel++;
} else if (NODE_SERVICE.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_SERVICE);
mValidLevel++;
} else if (NODE_RECEIVER.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_BROADCASTRECEIVER);
mValidLevel++;
} else if (NODE_PROVIDER.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
mValidLevel++;
}
break;
case LEVEL_INTENT_FILTER:
// only process this level if we are in an activity
if (mCurrentActivity != null && NODE_INTENT.equals(localName)) {
// if we're at the intent level, lets reset some flag to
// be used when parsing the children
mFoundMainAction = false;
mFoundLauncherCategory = false;
mValidLevel++;
}
break;
case LEVEL_CATEGORY:
if (mCurrentActivity != null && mLauncherActivity == null) {
if (NODE_ACTION.equals(localName)) {
// get the name attribute
if (ACTION_MAIN.equals(
getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */))) {
mFoundMainAction = true;
}
} else if (NODE_CATEGORY.equals(localName)) {
if (CATEGORY_LAUNCHER.equals(
getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */))) {
mFoundLauncherCategory = true;
}
}
// no need to increase mValidLevel as we don't process anything
// below this level.
}
break;
}
}
mCurrentLevel++;
} finally {
super.startElement(uri, localName, name, attributes);
}
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String,
* java.lang.String)
*/
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
try {
if (mGatherData == false) {
return;
}
// decrement the levels.
if (mValidLevel == mCurrentLevel) {
mValidLevel--;
}
mCurrentLevel--;
// if we're at a valid level
// process the end of the element
if (mValidLevel == mCurrentLevel) {
switch (mValidLevel) {
case LEVEL_ACTIVITY:
mCurrentActivity = null;
break;
case LEVEL_INTENT_FILTER:
// if we found both a main action and a launcher category, this is our
// launcher activity!
if (mCurrentActivity != null &&
mFoundMainAction && mFoundLauncherCategory) {
mLauncherActivity = mCurrentActivity;
}
break;
default:
break;
}
}
} finally {
super.endElement(uri, localName, name);
}
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
*/
@Override
public void error(SAXParseException e) throws SAXException {
if (mMarkErrors) {
super.error(e);
}
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
*/
@Override
public void fatalError(SAXParseException e) throws SAXException {
if (mMarkErrors) {
super.fatalError(e);
}
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
*/
@Override
public void warning(SAXParseException e) throws SAXException {
if (mMarkErrors) {
super.warning(e);
}
}
/**
* Processes the activity node.
* @param attributes the attributes for the activity node.
* @throws CoreException
*/
private void processActivityNode(Attributes attributes) {
// lets get the activity name, and add it to the list
String activityName = getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */);
if (activityName != null) {
mCurrentActivity = AndroidManifestHelper.combinePackageAndClassName(mPackage,
activityName);
mActivities.add(mCurrentActivity);
if (mMarkErrors) {
checkClass(mCurrentActivity, AndroidConstants.CLASS_ACTIVITY,
true /* testVisibility */);
}
} else {
// no activity found! Aapt will output an error,
// so we don't have to do anything
mCurrentActivity = activityName;
}
String processName = getAttributeValue(attributes, ATTRIBUTE_PROCESS,
true /* hasNamespace */);
if (processName != null) {
addProcessName(processName);
}
}
/**
* Processes the service/receiver/provider nodes.
* @param attributes the attributes for the activity node.
* @param superClassName the fully qualified name of the super class that this
* node is representing
* @throws CoreException
*/
private void processNode(Attributes attributes, String superClassName) {
// lets get the class name, and check it if required.
String serviceName = getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */);
if (serviceName != null) {
serviceName = AndroidManifestHelper.combinePackageAndClassName(mPackage,
serviceName);
if (mMarkErrors) {
checkClass(serviceName, superClassName, false /* testVisibility */);
}
}
String processName = getAttributeValue(attributes, ATTRIBUTE_PROCESS,
true /* hasNamespace */);
if (processName != null) {
addProcessName(processName);
}
}
/**
* Checks that a class is valid and can be used in the Android Manifest.
* <p/>
* Errors are put as {@link IMarker} on the manifest file.
* @param className the fully qualified name of the class to test.
* @param superClassName the fully qualified name of the class it is supposed to extend.
* @param testVisibility if <code>true</code>, the method will check the visibility of
* the class or of its constructors.
*/
private void checkClass(String className, String superClassName, boolean testVisibility) {
// we need to check the validity of the activity.
String result = BaseProjectHelper.testClassForManifest(mJavaProject,
className, superClassName, testVisibility);
if (result != BaseProjectHelper.TEST_CLASS_OK) {
// get the line number
int line = mLocator.getLineNumber();
// mark the file
IMarker marker = BaseProjectHelper.addMarker(getFile(),
AndroidConstants.MARKER_ANDROID,
result, line, IMarker.SEVERITY_ERROR);
// add custom attributes to be used by the manifest editor.
if (marker != null) {
try {
marker.setAttribute(AndroidConstants.MARKER_ATTR_TYPE,
AndroidConstants.MARKER_ATTR_TYPE_ACTIVITY);
marker.setAttribute(AndroidConstants.MARKER_ATTR_CLASS, className);
} catch (CoreException e) {
}
}
}
}
/**
* Searches through the attributes list for a particular one and returns its value.
* @param attributes the attribute list to search through
* @param attributeName the name of the attribute to look for.
* @param hasNamespace Indicates whether the attribute has an android namespace.
* @return a String with the value or null if the attribute was not found.
* @see AndroidConstants#NS_RESOURCES
*/
private String getAttributeValue(Attributes attributes, String attributeName,
boolean hasNamespace) {
int count = attributes.getLength();
for (int i = 0 ; i < count ; i++) {
if (attributeName.equals(attributes.getLocalName(i)) &&
((hasNamespace &&
AndroidConstants.NS_RESOURCES.equals(attributes.getURI(i))) ||
(hasNamespace == false && attributes.getURI(i).length() == 0))) {
return attributes.getValue(i);
}
}
return null;
}
private void addProcessName(String processName) {
if (mProcesses == null) {
mProcesses = new TreeSet<String>();
}
mProcesses.add(processName);
}
}
private static SAXParserFactory sParserFactory;
private final String mJavaPackage;
private final String[] mActivities;
private final String mLauncherActivity;
private final String[] mProcesses;
private final Boolean mDebuggable;
static {
sParserFactory = SAXParserFactory.newInstance();
sParserFactory.setNamespaceAware(true);
}
/**
* Parses the Android Manifest, and returns an object containing
* the result of the parsing.
* @param javaProject The java project.
* @param manifestFile the {@link IFile} representing the manifest file.
* @param errorListener
* @param gatherData indicates whether the parsing will extract data from the manifest.
* @param markErrors indicates whether the error found during parsing should put a
* marker on the file. For class validation errors to put a marker, <code>gatherData</code>
* must be set to <code>true</code>
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
*/
public static AndroidManifestParser parse(IJavaProject javaProject, IFile manifestFile,
XmlErrorListener errorListener, boolean gatherData, boolean markErrors)
throws CoreException {
try {
SAXParser parser = sParserFactory.newSAXParser();
ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
errorListener, gatherData, javaProject, markErrors);
parser.parse(new InputSource(manifestFile.getContents()), manifestHandler);
// get the result from the handler
return new AndroidManifestParser(manifestHandler.getPackage(),
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
manifestHandler.getProcesses(), manifestHandler.getDebuggable());
} catch (ParserConfigurationException e) {
} catch (SAXException e) {
} catch (IOException e) {
} finally {
}
return null;
}
/**
* Parses the Android Manifest for the specified project, and returns an object containing
* the result of the parsing.
* @param javaProject The java project. Required if <var>markErrors</var> is <code>true</code>
* @param errorListener the {@link XmlErrorListener} object being notified of the presence
* of errors. Optional.
* @param gatherData indicates whether the parsing will extract data from the manifest.
* @param markErrors indicates whether the error found during parsing should put a
* marker on the file. For class validation errors to put a marker, <code>gatherData</code>
* must be set to <code>true</code>
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
*/
public static AndroidManifestParser parse(IJavaProject javaProject,
XmlErrorListener errorListener, boolean gatherData, boolean markErrors)
throws CoreException {
try {
SAXParser parser = sParserFactory.newSAXParser();
IFile manifestFile = AndroidManifestHelper.getManifest(javaProject.getProject());
if (manifestFile != null) {
ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
errorListener, gatherData, javaProject, markErrors);
parser.parse(new InputSource(manifestFile.getContents()), manifestHandler);
// get the result from the handler
return new AndroidManifestParser(manifestHandler.getPackage(),
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
manifestHandler.getProcesses(), manifestHandler.getDebuggable());
}
} catch (ParserConfigurationException e) {
} catch (SAXException e) {
} catch (IOException e) {
} finally {
}
return null;
}
/**
* Parses the manifest file, collects data, and checks for errors.
* @param javaProject The java project. Required.
* @param manifestFile
* @param errorListener the {@link XmlErrorListener} object being notified of the presence
* of errors. Optional.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
* @see {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)}
*/
public static AndroidManifestParser parseForError(IJavaProject javaProject, IFile manifestFile,
XmlErrorListener errorListener) throws CoreException {
return parse(javaProject, manifestFile, errorListener, true, true);
}
/**
* Parses the manifest file, and collects data.
* @param manifestFile
* @param errorListener the {@link XmlErrorListener} object being notified of the presence
* of errors. Optional.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
* @see {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)}
*/
public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException {
return parse(null /* javaProject */, manifestFile, null /* errorListener */,
true /* gatherData */, false /* markErrors */);
}
/**
* Returns the package defined in the manifest, if found.
* @return The package name or null if not found.
*/
public String getPackage() {
return mJavaPackage;
}
/**
* Returns the list of activities found in the manifest.
* @return An array of fully qualified class names, or empty if no activity were found.
*/
public String[] getActivities() {
return mActivities;
}
/**
* Returns the name of one activity found in the manifest, that is configured to show
* up in the HOME screen.
* @return the fully qualified name of a HOME activity or null if none were found.
*/
public String getLauncherActivity() {
return mLauncherActivity;
}
/**
* Returns the list of process names declared by the manifest.
*/
public String[] getProcesses() {
return mProcesses;
}
/**
* Returns the debuggable attribute value or <code>null</code> if it is not set.
*/
public Boolean getDebuggable() {
return mDebuggable;
}
/**
* Private constructor to enforce using
* {@link #parse(IJavaProject, XmlErrorListener, boolean, boolean)},
* {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)},
* or {@link #parseForError(IJavaProject, IFile, XmlErrorListener)} to get an
* {@link AndroidManifestParser} object.
* @param javaPackage the package parsed from the manifest.
* @param activities the list of activities parsed from the manifest.
* @param launcherActivity the launcher activity parser from the manifest.
* @param processes the list of custom processes declared in the manifest.
* @param debuggable the debuggable attribute.
*/
private AndroidManifestParser(String javaPackage, String[] activities,
String launcherActivity, String[] processes, Boolean debuggable) {
mJavaPackage = javaPackage;
mActivities = activities;
mLauncherActivity = launcherActivity;
mProcesses = processes;
mDebuggable = debuggable;
}
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
/**
* XPath factory with automatic support for the android namespace.
*/
public class AndroidXPathFactory {
public final static String DEFAULT_NS_PREFIX = "android"; //$NON-NLS-1$
private final static XPathFactory sFactory = XPathFactory.newInstance();
/** Namespace context for Android resource XML files. */
private static class AndroidNamespaceContext implements NamespaceContext {
private String mAndroidPrefix;
/**
* Construct the context with the prefix associated with the android namespace.
* @param prefix the Prefix
*/
public AndroidNamespaceContext(String androidPrefix) {
mAndroidPrefix = androidPrefix;
}
public String getNamespaceURI(String prefix) {
if (prefix != null) {
if (prefix.equals(mAndroidPrefix)) {
return AndroidConstants.NS_RESOURCES;
}
}
return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String namespaceURI) {
// This isn't necessary for our use.
assert false;
return null;
}
public Iterator<?> getPrefixes(String namespaceURI) {
// This isn't necessary for our use.
assert false;
return null;
}
}
/**
* Creates a new XPath object, specifying which prefix in the query is used for the
* android namespace.
* @param prefix The namespace prefix.
*/
public static XPath newXPath(String androidPrefix) {
XPath xpath = sFactory.newXPath();
xpath.setNamespaceContext(new AndroidNamespaceContext(androidPrefix));
return xpath;
}
/**
* Creates a new XPath object using the default prefix for the android namespace.
* @see #DEFAULT_NS_PREFIX
*/
public static XPath newXPath() {
return newXPath(DEFAULT_NS_PREFIX);
}
}

View File

@@ -1,420 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.CommonPlugin;
import com.android.ide.eclipse.common.project.XmlErrorHandler.XmlErrorListener;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.actions.OpenJavaPerspectiveAction;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import java.util.ArrayList;
/**
* Utility methods to manipulate projects.
*/
public final class BaseProjectHelper {
public static final String TEST_CLASS_OK = null;
/**
* returns a list of source classpath for a specified project
* @param javaProject
* @return a list of path relative to the workspace root.
*/
public static ArrayList<IPath> getSourceClasspaths(IJavaProject javaProject) {
ArrayList<IPath> sourceList = new ArrayList<IPath>();
IClasspathEntry[] classpaths = javaProject.readRawClasspath();
if (classpaths != null) {
for (IClasspathEntry e : classpaths) {
if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
sourceList.add(e.getPath());
}
}
}
return sourceList;
}
/**
* Adds a marker to a file on a specific line
* @param file the file to be marked
* @param markerId The id of the marker to add.
* @param message the message associated with the mark
* @param lineNumber the line number where to put the mark
* @param severity the severity of the marker.
* @return the IMarker that was added or null if it failed to add one.
*/
public final static IMarker addMarker(IResource file, String markerId,
String message, int lineNumber, int severity) {
try {
IMarker marker = file.createMarker(markerId);
marker.setAttribute(IMarker.MESSAGE, message);
marker.setAttribute(IMarker.SEVERITY, severity);
if (lineNumber == -1) {
lineNumber = 1;
}
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
// on Windows, when adding a marker to a project, it takes a refresh for the marker
// to show. In order to fix this we're forcing a refresh of elements receiving
// markers (and only the element, not its children), to force the marker display.
file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
return marker;
} catch (CoreException e) {
CommonPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'",
markerId, file.getFullPath());
}
return null;
}
/**
* Adds a marker to a resource.
* @param file the file to be marked
* @param markerId The id of the marker to add.
* @param message the message associated with the mark
* @param lineNumber the line number where to put the mark
* @param severity the severity of the marker.
* @return the IMarker that was added or null if it failed to add one.
*/
public final static IMarker addMarker(IResource resource, String markerId,
String message, int severity) {
try {
IMarker marker = resource.createMarker(markerId);
marker.setAttribute(IMarker.MESSAGE, message);
marker.setAttribute(IMarker.SEVERITY, severity);
// on Windows, when adding a marker to a project, it takes a refresh for the marker
// to show. In order to fix this we're forcing a refresh of elements receiving
// markers (and only the element, not its children), to force the marker display.
resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
return marker;
} catch (CoreException e) {
CommonPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'",
markerId, resource.getFullPath());
}
return null;
}
/**
* Tests that a class name is valid for usage in the manifest.
* <p/>
* This tests the class existence, that it can be instantiated (ie it must not be abstract,
* nor non static if enclosed), and that it extends the proper super class (not necessarily
* directly)
* @param javaProject the {@link IJavaProject} containing the class.
* @param className the fully qualified name of the class to test.
* @param superClassName the fully qualified name of the expected super class.
* @param testVisibility if <code>true</code>, the method will check the visibility of the class
* or of its constructors.
* @return {@link #TEST_CLASS_OK} or an error message.
*/
public final static String testClassForManifest(IJavaProject javaProject, String className,
String superClassName, boolean testVisibility) {
try {
// replace $ by .
String javaClassName = className.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
// look for the IType object for this class
IType type = javaProject.findType(javaClassName);
if (type != null && type.exists()) {
// test that the class is not abstract
int flags = type.getFlags();
if (Flags.isAbstract(flags)) {
return String.format("%1$s is abstract", className);
}
// test whether the class is public or not.
if (testVisibility && Flags.isPublic(flags) == false) {
// if its not public, it may have a public default constructor,
// which would then be fine.
IMethod basicConstructor = type.getMethod(type.getElementName(), new String[0]);
if (basicConstructor != null && basicConstructor.exists()) {
int constructFlags = basicConstructor.getFlags();
if (Flags.isPublic(constructFlags) == false) {
return String.format(
"%1$s or its default constructor must be public for the system to be able to instantiate it",
className);
}
} else {
return String.format(
"%1$s must be public, or the system will not be able to instantiate it.",
className);
}
}
// If it's enclosed, test that it's static. If its declaring class is enclosed
// as well, test that it is also static, and public.
IType declaringType = type;
do {
IType tmpType = declaringType.getDeclaringType();
if (tmpType != null) {
if (tmpType.exists()) {
flags = declaringType.getFlags();
if (Flags.isStatic(flags) == false) {
return String.format("%1$s is enclosed, but not static",
declaringType.getFullyQualifiedName());
}
flags = tmpType.getFlags();
if (testVisibility && Flags.isPublic(flags) == false) {
return String.format("%1$s is not public",
tmpType.getFullyQualifiedName());
}
} else {
// if it doesn't exist, we need to exit so we may as well mark it null.
tmpType = null;
}
}
declaringType = tmpType;
} while (declaringType != null);
// test the class inherit from the specified super class.
// get the type hierarchy
ITypeHierarchy hierarchy = type.newSupertypeHierarchy(new NullProgressMonitor());
// if the super class is not the reference class, it may inherit from
// it so we get its supertype. At some point it will be null and we
// will stop
IType superType = type;
boolean foundProperSuperClass = false;
while ((superType = hierarchy.getSuperclass(superType)) != null &&
superType.exists()) {
if (superClassName.equals(superType.getFullyQualifiedName())) {
foundProperSuperClass = true;
}
}
// didn't find the proper superclass? return false.
if (foundProperSuperClass == false) {
return String.format("%1$s does not extend %2$s", className, superClassName);
}
return TEST_CLASS_OK;
} else {
return String.format("Class %1$s does not exist", className);
}
} catch (JavaModelException e) {
return String.format("%1$s: %2$s", className, e.getMessage());
}
}
/**
* Parses the manifest file for errors.
* <p/>
* This starts by removing the current XML marker, and then parses the xml for errors, both
* of XML type and of Android type (checking validity of class files).
* @param manifestFile
* @param errorListener
* @throws CoreException
*/
public static AndroidManifestParser parseManifestForError(IFile manifestFile,
XmlErrorListener errorListener) throws CoreException {
// remove previous markers
if (manifestFile.exists()) {
manifestFile.deleteMarkers(AndroidConstants.MARKER_XML, true, IResource.DEPTH_ZERO);
manifestFile.deleteMarkers(AndroidConstants.MARKER_ANDROID, true, IResource.DEPTH_ZERO);
}
// and parse
return AndroidManifestParser.parseForError(
BaseProjectHelper.getJavaProject(manifestFile.getProject()),
manifestFile, errorListener);
}
/**
* Returns the {@link IJavaProject} for a {@link IProject} object.
* <p/>
* This checks if the project has the Java Nature first.
* @param project
* @return the IJavaProject or null if the project couldn't be created or if the project
* does not have the Java Nature.
* @throws CoreException
*/
public static IJavaProject getJavaProject(IProject project) throws CoreException {
if (project != null && project.hasNature(JavaCore.NATURE_ID)) {
return JavaCore.create(project);
}
return null;
}
/**
* Reveals a specific line in the source file defining a specified class,
* for a specific project.
* @param project
* @param className
* @param line
*/
public static void revealSource(IProject project, String className, int line) {
// in case the type is enclosed, we need to replace the $ with .
className = className.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS2$
// get the java project
IJavaProject javaProject = JavaCore.create(project);
try {
// look for the IType matching the class name.
IType result = javaProject.findType(className);
if (result != null && result.exists()) {
// before we show the type in an editor window, we make sure the current
// workbench page has an editor area (typically the ddms perspective doesn't).
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
if (page.isEditorAreaVisible() == false) {
// no editor area? we open the java perspective.
new OpenJavaPerspectiveAction().run();
}
IEditorPart editor = JavaUI.openInEditor(result);
if (editor instanceof ITextEditor) {
// get the text editor that was just opened.
ITextEditor textEditor = (ITextEditor)editor;
IEditorInput input = textEditor.getEditorInput();
// get the location of the line to show.
IDocumentProvider documentProvider = textEditor.getDocumentProvider();
IDocument document = documentProvider.getDocument(input);
IRegion lineInfo = document.getLineInformation(line - 1);
// select and reveal the line.
textEditor.selectAndReveal(lineInfo.getOffset(), lineInfo.getLength());
}
}
} catch (JavaModelException e) {
} catch (PartInitException e) {
} catch (BadLocationException e) {
}
}
/**
* Returns the list of android-flagged projects. This list contains projects that are opened
* in the workspace and that are flagged as android project (through the android nature)
* @return an array of IJavaProject, which can be empty if no projects match.
*/
public static IJavaProject[] getAndroidProjects() {
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IJavaModel javaModel = JavaCore.create(workspaceRoot);
return getAndroidProjects(javaModel);
}
/**
* Returns the list of android-flagged projects for the specified java Model.
* This list contains projects that are opened in the workspace and that are flagged as android
* project (through the android nature)
* @param javaModel the Java Model object corresponding for the current workspace root.
* @return an array of IJavaProject, which can be empty if no projects match.
*/
public static IJavaProject[] getAndroidProjects(IJavaModel javaModel) {
// get the java projects
IJavaProject[] javaProjectList = null;
try {
javaProjectList = javaModel.getJavaProjects();
}
catch (JavaModelException jme) {
return new IJavaProject[0];
}
// temp list to build the android project array
ArrayList<IJavaProject> androidProjectList = new ArrayList<IJavaProject>();
// loop through the projects and add the android flagged projects to the temp list.
for (IJavaProject javaProject : javaProjectList) {
// get the workspace project object
IProject project = javaProject.getProject();
// check if it's an android project based on its nature
try {
if (project.hasNature(AndroidConstants.NATURE)) {
androidProjectList.add(javaProject);
}
} catch (CoreException e) {
// this exception, thrown by IProject.hasNature(), means the project either doesn't
// exist or isn't opened. So, in any case we just skip it (the exception will
// bypass the ArrayList.add()
}
}
// return the android projects list.
return androidProjectList.toArray(new IJavaProject[androidProjectList.size()]);
}
/**
* Returns the {@link IFolder} representing the output for the project.
* <p>
* The project must be a java project and be opened, or the method will return null.
* @param project the {@link IProject}
* @return an IFolder item or null.
*/
public final static IFolder getOutputFolder(IProject project) {
try {
if (project.isOpen() && project.hasNature(JavaCore.NATURE_ID)) {
// get a java project from the normal project object
IJavaProject javaProject = JavaCore.create(project);
IPath path = javaProject.getOutputLocation();
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
IResource outputResource = wsRoot.findMember(path);
if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
return (IFolder)outputResource;
}
}
} catch (JavaModelException e) {
// Let's do nothing and return null
} catch (CoreException e) {
// Let's do nothing and return null
}
return null;
}
}

View File

@@ -1,188 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.JarEntry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Export helper for project.
*/
public final class ExportHelper {
private static IExportCallback sCallback;
public interface IExportCallback {
void startExportWizard(IProject project);
}
public static void setCallback(IExportCallback callback) {
sCallback = callback;
}
public static void startExportWizard(IProject project) {
if (sCallback != null) {
sCallback.startExportWizard(project);
}
}
/**
* Exports an <b>unsigned</b> version of the application created by the given project.
* @param project the project to export
*/
public static void exportProject(IProject project) {
Shell shell = Display.getCurrent().getActiveShell();
// get the java project to get the output directory
IFolder outputFolder = BaseProjectHelper.getOutputFolder(project);
if (outputFolder != null) {
IPath binLocation = outputFolder.getLocation();
// make the full path to the package
String fileName = project.getName() + AndroidConstants.DOT_ANDROID_PACKAGE;
File file = new File(binLocation.toOSString() + File.separator + fileName);
if (file.exists() == false || file.isFile() == false) {
MessageDialog.openInformation(Display.getCurrent().getActiveShell(),
"Android IDE Plug-in",
String.format("Failed to export %1$s: %2$s doesn't exist!",
project.getName(), file.getPath()));
return;
}
// ok now pop up the file save window
FileDialog fileDialog = new FileDialog(shell, SWT.SAVE);
fileDialog.setText("Export Project");
fileDialog.setFileName(fileName);
String saveLocation = fileDialog.open();
if (saveLocation != null) {
// get the stream from the original file
ZipInputStream zis = null;
ZipOutputStream zos = null;
FileInputStream input = null;
FileOutputStream output = null;
try {
input = new FileInputStream(file);
zis = new ZipInputStream(input);
// get an output stream into the new file
File saveFile = new File(saveLocation);
output = new FileOutputStream(saveFile);
zos = new ZipOutputStream(output);
} catch (FileNotFoundException e) {
// only the input/output stream are throwing this exception.
// so we only have to close zis if output is the one that threw.
if (zis != null) {
try {
zis.close();
} catch (IOException e1) {
// pass
}
}
MessageDialog.openInformation(shell, "Android IDE Plug-in",
String.format("Failed to export %1$s: %2$s doesn't exist!",
project.getName(), file.getPath()));
return;
}
try {
ZipEntry entry;
byte[] buffer = new byte[4096];
while ((entry = zis.getNextEntry()) != null) {
String name = entry.getName();
// do not take directories or anything inside the META-INF folder since
// we want to strip the signature.
if (entry.isDirectory() || name.startsWith("META-INF/")) { //$NON-NL1$
continue;
}
ZipEntry newEntry;
// Preserve the STORED method of the input entry.
if (entry.getMethod() == JarEntry.STORED) {
newEntry = new JarEntry(entry);
} else {
// Create a new entry so that the compressed len is recomputed.
newEntry = new JarEntry(name);
}
// add the entry to the jar archive
zos.putNextEntry(newEntry);
// read the content of the entry from the input stream, and write it into the archive.
int count;
while ((count = zis.read(buffer)) != -1) {
zos.write(buffer, 0, count);
}
// close the entry for this file
zos.closeEntry();
zis.closeEntry();
}
} catch (IOException e) {
MessageDialog.openInformation(shell, "Android IDE Plug-in",
String.format("Failed to export %1$s: %2$s",
project.getName(), e.getMessage()));
} finally {
try {
zos.close();
} catch (IOException e) {
// pass
}
try {
zis.close();
} catch (IOException e) {
// pass
}
}
}
} else {
MessageDialog.openInformation(shell, "Android IDE Plug-in",
String.format("Failed to export %1$s: Could not get project output location",
project.getName()));
}
}
}

View File

@@ -1,110 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
/**
* Helper class to deal with displaying a project choosing dialog that lists only the
* projects with the Android nature.
*/
public class ProjectChooserHelper {
private final Shell mParentShell;
/**
* List of current android projects. Since the dialog is modal, we'll just get
* the list once on-demand.
*/
private IJavaProject[] mAndroidProjects;
public ProjectChooserHelper(Shell parentShell) {
mParentShell = parentShell;
}
/**
* Displays a project chooser dialog which lists all available projects with the Android nature.
* <p/>
* The list of project is built from Android flagged projects currently opened in the workspace.
*
* @param projectName If non null and not empty, represents the name of an Android project
* that will be selected by default.
* @return the project chosen by the user in the dialog, or null if the dialog was canceled.
*/
public IJavaProject chooseJavaProject(String projectName) {
ILabelProvider labelProvider = new JavaElementLabelProvider(
JavaElementLabelProvider.SHOW_DEFAULT);
ElementListSelectionDialog dialog = new ElementListSelectionDialog(
mParentShell, labelProvider);
dialog.setTitle("Project Selection");
dialog.setMessage("Select a project to constrain your search.");
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IJavaModel javaModel = JavaCore.create(workspaceRoot);
// set the elements in the dialog. These are opened android projects.
dialog.setElements(getAndroidProjects(javaModel));
// look for the project matching the given project name
IJavaProject javaProject = null;
if (projectName != null && projectName.length() > 0) {
javaProject = javaModel.getJavaProject(projectName);
}
// if we found it, we set the initial selection in the dialog to this one.
if (javaProject != null) {
dialog.setInitialSelections(new Object[] { javaProject });
}
// open the dialog and return the object selected if OK was clicked, or null otherwise
if (dialog.open() == Window.OK) {
return (IJavaProject)dialog.getFirstResult();
}
return null;
}
/**
* Returns the list of Android projects.
* <p/>
* Because this list can be time consuming, this class caches the list of project.
* It is recommended to call this method instead of
* {@link BaseProjectHelper#getAndroidProjects()}.
*
* @param javaModel the java model. Can be null.
*/
public IJavaProject[] getAndroidProjects(IJavaModel javaModel) {
if (mAndroidProjects == null) {
if (javaModel == null) {
mAndroidProjects = BaseProjectHelper.getAndroidProjects();
} else {
mAndroidProjects = BaseProjectHelper.getAndroidProjects(javaModel);
}
}
return mAndroidProjects;
}
}

View File

@@ -1,102 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* XML error handler used by the parser to report errors/warnings.
*/
public class XmlErrorHandler extends DefaultHandler {
/** file being parsed */
private IFile mFile;
/** link to the delta visitor, to set the xml error flag */
private XmlErrorListener mErrorListener;
/**
* Classes which implement this interface provide a method that deals
* with XML errors.
*/
public interface XmlErrorListener {
/**
* Sent when an XML error is detected.
*/
public void errorFound();
}
public static class BasicXmlErrorListener implements XmlErrorListener {
public boolean mHasXmlError = false;
public void errorFound() {
mHasXmlError = true;
}
}
public XmlErrorHandler(IFile file, XmlErrorListener errorListener) {
mFile = file;
mErrorListener = errorListener;
}
/**
* Xml Error call back
* @param exception the parsing exception
*/
@Override
public void error(SAXParseException exception) throws SAXException {
if (mErrorListener != null) {
mErrorListener.errorFound();
}
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
exception.getLineNumber(), IMarker.SEVERITY_ERROR);
}
/**
* Xml Fatal Error call back
* @param exception the parsing exception
*/
@Override
public void fatalError(SAXParseException exception)
throws SAXException {
if (mErrorListener != null) {
mErrorListener.errorFound();
}
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
exception.getLineNumber(), IMarker.SEVERITY_ERROR);
}
/**
* Xml Warning call back
* @param exception the parsing exception
*/
@Override
public void warning(SAXParseException exception) throws SAXException {
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
exception.getLineNumber(), IMarker.SEVERITY_WARNING);
}
protected final IFile getFile() {
return mFile;
}
}

View File

@@ -1,461 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
import com.android.ide.eclipse.common.CommonPlugin;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo.Format;
import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
import org.eclipse.core.runtime.IStatus;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
/**
* Parser for attributes description files.
*/
public final class AttrsXmlParser {
private Document mDocument;
private String mOsAttrsXmlPath;
// all attributes that have the same name are supposed to have the same
// parameters so we'll keep a cache of them to avoid processing them twice.
private HashMap<String, AttributeInfo> mAttributeMap;
/** Map of all attribute names for a given element */
private HashMap<String, DeclareStyleableInfo> mStyleMap;
/** Map of all (constant, value) pairs for attributes of format enum or flag.
* E.g. for attribute name=gravity, this tells us there's an enum/flag called "center"
* with value 0x11.
*/
private Map<String, Map<String, Integer>> mEnumFlagValues;
/**
* Creates a new {@link AttrsXmlParser}, set to load things from the given
* XML file. Nothing has been parsed yet. Callers should call {@link #preload()}
* next.
*/
public AttrsXmlParser(String osAttrsXmlPath) {
this(osAttrsXmlPath, null /* inheritableAttributes */);
}
/**
* Creates a new {@link AttrsXmlParser} set to load things from the given
* XML file. If inheritableAttributes is non-null, it must point to a preloaded
* {@link AttrsXmlParser} which attributes will be used for this one. Since
* already defined attributes are not modifiable, they are thus "inherited".
*/
public AttrsXmlParser(String osAttrsXmlPath, AttrsXmlParser inheritableAttributes) {
mOsAttrsXmlPath = osAttrsXmlPath;
// styles are not inheritable.
mStyleMap = new HashMap<String, DeclareStyleableInfo>();
if (inheritableAttributes == null) {
mAttributeMap = new HashMap<String, AttributeInfo>();
mEnumFlagValues = new HashMap<String, Map<String,Integer>>();
} else {
mAttributeMap = new HashMap<String, AttributeInfo>(inheritableAttributes.mAttributeMap);
mEnumFlagValues = new HashMap<String, Map<String,Integer>>(
inheritableAttributes.mEnumFlagValues);
}
}
/**
* @return The OS path of the attrs.xml file parsed
*/
public String getOsAttrsXmlPath() {
return mOsAttrsXmlPath;
}
/**
* Preloads the document, parsing all attributes and declared styles.
*
* @return Self, for command chaining.
*/
public AttrsXmlParser preload() {
Document doc = getDocument();
if (doc == null) {
CommonPlugin.log(IStatus.WARNING, "Failed to find %1$s", //$NON-NLS-1$
mOsAttrsXmlPath);
return this;
}
Node res = doc.getFirstChild();
while (res != null &&
res.getNodeType() != Node.ELEMENT_NODE &&
!res.getNodeName().equals("resources")) { //$NON-NLS-1$
res = res.getNextSibling();
}
if (res == null) {
CommonPlugin.log(IStatus.WARNING, "Failed to find a <resources> node in %1$s", //$NON-NLS-1$
mOsAttrsXmlPath);
return this;
}
parseResources(res);
return this;
}
/**
* Loads all attributes & javadoc for the view class info based on the class name.
*/
public void loadViewAttributes(ViewClassInfo info) {
if (getDocument() != null) {
String xmlName = info.getShortClassName();
DeclareStyleableInfo style = mStyleMap.get(xmlName);
if (style != null) {
info.setAttributes(style.getAttributes());
info.setJavaDoc(style.getJavaDoc());
}
}
}
/**
* Loads all attributes for the layout data info based on the class name.
*/
public void loadLayoutParamsAttributes(LayoutParamsInfo info) {
if (getDocument() != null) {
// Transforms "LinearLayout" and "LayoutParams" into "LinearLayout_Layout".
String xmlName = String.format("%1$s_%2$s", //$NON-NLS-1$
info.getViewLayoutClass().getShortClassName(),
info.getShortClassName());
xmlName = xmlName.replaceFirst("Params$", ""); //$NON-NLS-1$ //$NON-NLS-2$
DeclareStyleableInfo style = mStyleMap.get(xmlName);
if (style != null) {
info.setAttributes(style.getAttributes());
}
}
}
/**
* Returns a list of all decleare-styleable found in the xml file.
*/
public Map<String, DeclareStyleableInfo> getDeclareStyleableList() {
return Collections.unmodifiableMap(mStyleMap);
}
/**
* Returns a map of all enum and flag constants sorted by parent attribute name.
* The map is attribute_name => (constant_name => integer_value).
*/
public Map<String, Map<String, Integer>> getEnumFlagValues() {
return mEnumFlagValues;
}
//-------------------------
/**
* Creates an XML document from the attrs.xml OS path.
* May return null if the file doesn't exist or cannot be parsed.
*/
private Document getDocument() {
if (mDocument == null) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(false);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
mDocument = builder.parse(new File(mOsAttrsXmlPath));
} catch (ParserConfigurationException e) {
CommonPlugin.log(e, "Failed to create XML document builder for %1$s", //$NON-NLS-1$
mOsAttrsXmlPath);
} catch (SAXException e) {
CommonPlugin.log(e, "Failed to parse XML document %1$s", //$NON-NLS-1$
mOsAttrsXmlPath);
} catch (IOException e) {
CommonPlugin.log(e, "Failed to read XML document %1$s", //$NON-NLS-1$
mOsAttrsXmlPath);
}
}
return mDocument;
}
/**
* Finds all the <declare-styleable> and <attr> nodes in the top <resources> node.
*/
private void parseResources(Node res) {
Node lastComment = null;
for (Node node = res.getFirstChild(); node != null; node = node.getNextSibling()) {
switch (node.getNodeType()) {
case Node.COMMENT_NODE:
lastComment = node;
break;
case Node.ELEMENT_NODE:
if (node.getNodeName().equals("declare-styleable")) { //$NON-NLS-1$
Node nameNode = node.getAttributes().getNamedItem("name"); //$NON-NLS-1$
if (nameNode != null) {
String name = nameNode.getNodeValue();
Node parentNode = node.getAttributes().getNamedItem("parent"); //$NON-NLS-1$
String parents = parentNode == null ? null : parentNode.getNodeValue();
if (name != null && !mStyleMap.containsKey(name)) {
DeclareStyleableInfo style = parseDeclaredStyleable(name, node);
if (parents != null) {
style.setParents(parents.split("[ ,|]")); //$NON-NLS-1$
}
mStyleMap.put(name, style);
if (lastComment != null) {
style.setJavaDoc(formatJavadoc(lastComment.getNodeValue()));
}
}
}
} else if (node.getNodeName().equals("attr")) { //$NON-NLS-1$
parseAttr(node, lastComment);
}
lastComment = null;
break;
}
}
}
/**
* Parses an <attr> node and convert it into an {@link AttributeInfo} if it is valid.
*/
private AttributeInfo parseAttr(Node attrNode, Node lastComment) {
AttributeInfo info = null;
Node nameNode = attrNode.getAttributes().getNamedItem("name"); //$NON-NLS-1$
if (nameNode != null) {
String name = nameNode.getNodeValue();
if (name != null) {
info = mAttributeMap.get(name);
// If the attribute is unknown yet, parse it.
// If the attribute is know but its format is unknown, parse it too.
if (info == null || info.getFormats().length == 0) {
info = parseAttributeTypes(attrNode, name);
if (info != null) {
mAttributeMap.put(name, info);
}
} else if (lastComment != null) {
info = new AttributeInfo(info);
}
if (info != null) {
if (lastComment != null) {
info.setJavaDoc(formatJavadoc(lastComment.getNodeValue()));
}
}
}
}
return info;
}
/**
* Finds all the attributes for a particular style node,
* e.g. a declare-styleable of name "TextView" or "LinearLayout_Layout".
*
* @param styleName The name of the declare-styleable node
* @param declareStyleableNode The declare-styleable node itself
*/
private DeclareStyleableInfo parseDeclaredStyleable(String styleName,
Node declareStyleableNode) {
ArrayList<AttributeInfo> attrs = new ArrayList<AttributeInfo>();
Node lastComment = null;
for (Node node = declareStyleableNode.getFirstChild();
node != null;
node = node.getNextSibling()) {
switch (node.getNodeType()) {
case Node.COMMENT_NODE:
lastComment = node;
break;
case Node.ELEMENT_NODE:
if (node.getNodeName().equals("attr")) { //$NON-NLS-1$
AttributeInfo info = parseAttr(node, lastComment);
if (info != null) {
attrs.add(info);
}
}
lastComment = null;
break;
}
}
return new DeclareStyleableInfo(styleName, attrs.toArray(new AttributeInfo[attrs.size()]));
}
/**
* Returns the {@link AttributeInfo} for a specific <attr> XML node.
* This gets the javadoc, the type, the name and the enum/flag values if any.
* <p/>
* The XML node is expected to have the following attributes:
* <ul>
* <li>"name", which is mandatory. The node is skipped if this is missing.</li>
* <li>"format".</li>
* </ul>
* The format may be one type or two types (e.g. "reference|color").
* An extra format can be implied: "enum" or "flag" are not specified in the "format" attribute,
* they are implicitely stated by the presence of sub-nodes <enum> or <flag>.
* <p/>
* By design, <attr> nodes of the same name MUST have the same type.
* Attribute nodes are thus cached by name and reused as much as possible.
* When reusing a node, it is duplicated and its javadoc reassigned.
*/
private AttributeInfo parseAttributeTypes(Node attrNode, String name) {
TreeSet<AttributeInfo.Format> formats = new TreeSet<AttributeInfo.Format>();
String[] enumValues = null;
String[] flagValues = null;
Node attrFormat = attrNode.getAttributes().getNamedItem("format"); //$NON-NLS-1$
if (attrFormat != null) {
for (String f : attrFormat.getNodeValue().split("\\|")) { //$NON-NLS-1$
try {
Format format = AttributeInfo.Format.valueOf(f.toUpperCase());
// enum and flags are handled differently right below
if (format != null &&
format != AttributeInfo.Format.ENUM &&
format != AttributeInfo.Format.FLAG) {
formats.add(format);
}
} catch (IllegalArgumentException e) {
CommonPlugin.log(e, "Unknown format name '%s' in <attr name=\"%s\">, file '%s'.", //$NON-NLS-1$
f, name, getOsAttrsXmlPath());
}
}
}
// does this <attr> have <enum> children?
enumValues = parseEnumFlagValues(attrNode, "enum", name); //$NON-NLS-1$
if (enumValues != null) {
formats.add(AttributeInfo.Format.ENUM);
}
// does this <attr> have <flag> children?
flagValues = parseEnumFlagValues(attrNode, "flag", name); //$NON-NLS-1$
if (flagValues != null) {
formats.add(AttributeInfo.Format.FLAG);
}
AttributeInfo info = new AttributeInfo(name,
formats.toArray(new AttributeInfo.Format[formats.size()]));
info.setEnumValues(enumValues);
info.setFlagValues(flagValues);
return info;
}
/**
* Given an XML node that represents an <attr> node, this method searches
* if the node has any children nodes named "target" (e.g. "enum" or "flag").
* Such nodes must have a "name" attribute.
* <p/>
* If "attrNode" is null, look for any <attr> that has the given attrNode
* and the requested children nodes.
* <p/>
* This method collects all the possible names of these children nodes and
* return them.
*
* @param attrNode The <attr> XML node
* @param filter The child node to look for, either "enum" or "flag".
* @param attrName The value of the name attribute of <attr>
*
* @return Null if there are no such children nodes, otherwise an array of length >= 1
* of all the names of these children nodes.
*/
private String[] parseEnumFlagValues(Node attrNode, String filter, String attrName) {
ArrayList<String> names = null;
for (Node child = attrNode.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(filter)) {
Node nameNode = child.getAttributes().getNamedItem("name"); //$NON-NLS-1$
if (nameNode == null) {
CommonPlugin.log(IStatus.WARNING,
"Missing name attribute in <attr name=\"%s\"><%s></attr>", //$NON-NLS-1$
attrName, filter);
} else {
if (names == null) {
names = new ArrayList<String>();
}
String name = nameNode.getNodeValue();
names.add(name);
Node valueNode = child.getAttributes().getNamedItem("value"); //$NON-NLS-1$
if (valueNode == null) {
CommonPlugin.log(IStatus.WARNING,
"Missing value attribute in <attr name=\"%s\"><%s name=\"%s\"></attr>", //$NON-NLS-1$
attrName, filter, name);
} else {
String value = valueNode.getNodeValue();
try {
int i = value.startsWith("0x") ?
Integer.parseInt(value.substring(2), 16 /* radix */) :
Integer.parseInt(value);
Map<String, Integer> map = mEnumFlagValues.get(attrName);
if (map == null) {
map = new HashMap<String, Integer>();
mEnumFlagValues.put(attrName, map);
}
map.put(name, Integer.valueOf(i));
} catch(NumberFormatException e) {
CommonPlugin.log(e,
"Value in <attr name=\"%s\"><%s name=\"%s\" value=\"%s\"></attr> is not a valid decimal or hexadecimal", //$NON-NLS-1$
attrName, filter, name, value);
}
}
}
}
}
return names == null ? null : names.toArray(new String[names.size()]);
}
/**
* Formats the javadoc.
* Only keeps the first sentence.
* Removes and simplifies links and references.
*/
private String formatJavadoc(String comment) {
if (comment == null) {
return null;
}
// sanitize & collapse whitespace
comment = comment.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
// take everything up to the first dot that is followed by a space or the end of the line.
// I love regexps :-). For the curious, the regexp is:
// - start of line
// - ignore whitespace
// - group:
// - everything, not greedy
// - non-capturing group (?: )
// - end of string
// or
// - not preceded by a letter, a dot and another letter (for "i.e" and "e.g" )
// (<! non-capturing zero-width negative look-behind)
// - a dot
// - followed by a space (?= non-capturing zero-width positive look-ahead)
// - anything else is ignored
comment = comment.replaceFirst("^\\s*(.*?(?:$|(?<![a-zA-Z]\\.[a-zA-Z])\\.(?=\\s))).*", "$1"); //$NON-NLS-1$ //$NON-NLS-2$
return comment;
}
}

View File

@@ -1,163 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
/**
* Information needed to represent a View or ViewGroup (aka Layout) item
* in the layout hierarchy, as extracted from the main android.jar and the
* associated attrs.xml.
*/
public class DeclareStyleableInfo {
/** The style name, never null. */
private String mStyleName;
/** Attributes for this view or view group. Can be empty but never null. */
private AttributeInfo[] mAttributes;
/** Short javadoc. Can be null. */
private String mJavaDoc;
/** Optional name of the parents stylable. Can be null. */
private String[] mParents;
public static class AttributeInfo {
/** XML Name of the attribute */
private String mName;
public enum Format {
STRING,
BOOLEAN,
INTEGER,
FLOAT,
REFERENCE,
COLOR,
DIMENSION,
FRACTION,
ENUM,
FLAG,
}
/** Formats of the attribute. Cannot be null. Should have at least one format. */
private Format[] mFormats;
/** Values for enum. null for other types. */
private String[] mEnumValues;
/** Values for flag. null for other types. */
private String[] mFlagValues;
/** Short javadoc */
private String mJavaDoc;
/**
* @param name The XML Name of the attribute
* @param formats The formats of the attribute. Cannot be null.
* Should have at least one format.
*/
public AttributeInfo(String name, Format[] formats) {
mName = name;
mFormats = formats;
}
public AttributeInfo(AttributeInfo info) {
mName = info.mName;
mFormats = info.mFormats;
mEnumValues = info.mEnumValues;
mFlagValues = info.mFlagValues;
mJavaDoc = info.mJavaDoc;
}
/** Returns the XML Name of the attribute */
public String getName() {
return mName;
}
/** Returns the formats of the attribute. Cannot be null.
* Should have at least one format. */
public Format[] getFormats() {
return mFormats;
}
/** Returns the values for enums. null for other types. */
public String[] getEnumValues() {
return mEnumValues;
}
/** Returns the values for flags. null for other types. */
public String[] getFlagValues() {
return mFlagValues;
}
/** Returns a short javadoc */
public String getJavaDoc() {
return mJavaDoc;
}
/** Sets the values for enums. null for other types. */
public void setEnumValues(String[] values) {
mEnumValues = values;
}
/** Sets the values for flags. null for other types. */
public void setFlagValues(String[] values) {
mFlagValues = values;
}
/** Sets a short javadoc */
public void setJavaDoc(String javaDoc) {
mJavaDoc = javaDoc;
}
}
// --------
/**
* Creates a new {@link DeclareStyleableInfo}.
*
* @param styleName The name of the style. Should not be empty nor null.
* @param attributes The initial list of attributes. Can be null.
*/
public DeclareStyleableInfo(String styleName, AttributeInfo[] attributes) {
mStyleName = styleName;
mAttributes = attributes == null ? new AttributeInfo[0] : attributes;
}
/** Returns style name */
public String getStyleName() {
return mStyleName;
}
/** Returns the attributes for this view or view group. Maybe empty but not null. */
public AttributeInfo[] getAttributes() {
return mAttributes;
}
/** Sets the list of attributes for this View or ViewGroup. */
public void setAttributes(AttributeInfo[] attributes) {
mAttributes = attributes;
}
/** Returns a short javadoc */
public String getJavaDoc() {
return mJavaDoc;
}
/** Sets the javadoc. */
public void setJavaDoc(String javaDoc) {
mJavaDoc = javaDoc;
}
/** Sets the name of the parents styleable. Can be null. */
public void setParents(String[] parents) {
mParents = parents;
}
/** Returns the name of the parents styleable. Can be null. */
public String[] getParents() {
return mParents;
}
}

View File

@@ -1,318 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.CommonPlugin;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Map;
/**
* This is a communication between different plugins that don't know each other. It allows one
* plugin to provide detailed information about the framework resources to another plugin.
*/
public class FrameworkResourceManager {
private static String[] sBooleanValues = new String[] {
"true", //$NON-NLS-1$
"false", //$NON-NLS-1$
};
private static FrameworkResourceManager sThis = new FrameworkResourceManager();
private ArrayList<Runnable> mResourcesChangeListeners = new ArrayList<Runnable>();
private Hashtable<String, String[]> mAttributeValues;
private IResourceRepository mSystemResourceRepository;
private ViewClassInfo[] mLayoutViewsInfo;
private ViewClassInfo[] mLayoutGroupsInfo;
private ViewClassInfo[] mPreferencesInfo;
private ViewClassInfo[] mPreferenceGroupsInfo;
private Map<String, DeclareStyleableInfo> mXmlMenuMap;
private Map<String, DeclareStyleableInfo> mXmlSearchableMap;
private Map<String, DeclareStyleableInfo> mManifestMap;
/** Flags indicating whether we have some resources */
private boolean mHasResources = false;
private String mLayoutLibLocation;
private String mFrameworkResourcesLocation;
private Map<String, Map<String, Integer>> mEnumValueMap;
private String mFrameworkFontsLocation;
private String mDocBaseUrl;
/**
* Creates a new Framework Resource Manager.
*
* mAttributeValues is a map { key => list [ values ] }.
* The key for the map is "(element-xml-name,attribute-namespace:attribute-xml-local-name)".
* The attribute namespace prefix must be:
* - "android" for AndroidConstants.NS_RESOURCES
* - "xmlns" for the XMLNS URI.
*/
private FrameworkResourceManager() {
/* TODO Attempt to load those values from android.jar */
mAttributeValues = new Hashtable<String, String[]>();
mAttributeValues.put("(manifest,xmlns:android)", new String[] { //$NON-NLS-1$
AndroidConstants.NS_RESOURCES
});
mAttributeValues.put("(permission,android:protectionLevel)", new String[] { //$NON-NLS-1$
"application", //$NON-NLS-1$
"system" //$NON-NLS-1$
});
mAttributeValues.put("(application,android:persistent)", new String[] { //$NON-NLS-1$
"true", //$NON-NLS-1$
"false", //$NON-NLS-1$
});
mAttributeValues.put("(activity,android:clearOnBackground)", sBooleanValues); //$NON-NLS-1$
mAttributeValues.put("(activity,android:configChanges)", new String[] { //$NON-NLS-1$
"fontScale", //$NON-NLS-1$
"mcc", //$NON-NLS-1$
"mnc", //$NON-NLS-1$
"locale", //$NON-NLS-1$
"touchscreen", //$NON-NLS-1$
"keyboard", //$NON-NLS-1$
"keyboardHidden", //$NON-NLS-1$
"navigation", //$NON-NLS-1$
"orientation", //$NON-NLS-1$
});
mAttributeValues.put("(activity,android:launchMode)", new String[] { //$NON-NLS-1$
"multiple", //$NON-NLS-1$
"singleTop", //$NON-NLS-1$
"singleTask", //$NON-NLS-1$
"singleInstance" //$NON-NLS-1$
});
mAttributeValues.put("(activity,android:stateNotNeeded)", sBooleanValues); //$NON-NLS-1$
mAttributeValues.put("(provider,android:syncable)", sBooleanValues); //$NON-NLS-1$
mAttributeValues.put("(provider,android:multiprocess)", sBooleanValues); //$NON-NLS-1$
mAttributeValues.put("(instrumentation,android:functionalTest)", sBooleanValues); //$NON-NLS-1$
mAttributeValues.put("(instrumentation,android:handleProfiling)", sBooleanValues); //$NON-NLS-1$
}
/**
* Returns the {@link FrameworkResourceManager} instance.
*/
public static FrameworkResourceManager getInstance() {
return sThis;
}
/**
* Sets the resources and notifies the listeners
* @param documentationBaseUrl
*/
public synchronized void setResources(IResourceRepository systemResourceRepository,
ViewClassInfo[] layoutViewsInfo,
ViewClassInfo[] layoutGroupsInfo,
ViewClassInfo[] preferencesInfo,
ViewClassInfo[] preferenceGroupsInfo,
Map<String, DeclareStyleableInfo> xmlMenuMap,
Map<String, DeclareStyleableInfo> xmlSearchableMap,
Map<String, DeclareStyleableInfo> manifestMap,
Map<String, Map<String, Integer>> enumValueMap,
String[] permissionValues,
String[] activityIntentActionValues,
String[] broadcastIntentActionValues,
String[] serviceIntentActionValues,
String[] intentCategoryValues,
String documentationBaseUrl) {
mSystemResourceRepository = systemResourceRepository;
mLayoutViewsInfo = layoutViewsInfo;
mLayoutGroupsInfo = layoutGroupsInfo;
mPreferencesInfo = preferencesInfo;
mPreferenceGroupsInfo = preferenceGroupsInfo;
mXmlMenuMap = xmlMenuMap;
mXmlSearchableMap = xmlSearchableMap;
mManifestMap = manifestMap;
mEnumValueMap = enumValueMap;
mDocBaseUrl = documentationBaseUrl;
setPermissions(permissionValues);
setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues,
serviceIntentActionValues, intentCategoryValues);
mHasResources = true;
notifyFrameworkResourcesChangeListeners();
}
public synchronized IResourceRepository getSystemResources() {
return mSystemResourceRepository;
}
public synchronized String[] getValues(String elementName, String attributeName) {
String key = String.format("(%1$s,%2$s)", elementName, attributeName); //$NON-NLS-1$
return mAttributeValues.get(key);
}
public synchronized String[] getValues(String elementName, String attributeName,
String greatGrandParentElementName) {
if (greatGrandParentElementName != null) {
String key = String.format("(%1$s,%2$s,%3$s)", greatGrandParentElementName, //$NON-NLS-1$
elementName, attributeName);
String[] values = mAttributeValues.get(key);
if (values != null) {
return values;
}
}
return getValues(elementName, attributeName);
}
public synchronized String[] getValues(String key) {
return mAttributeValues.get(key);
}
public synchronized ViewClassInfo[] getLayoutViewsInfo() {
return mLayoutViewsInfo;
}
public synchronized ViewClassInfo[] getLayoutGroupsInfo() {
return mLayoutGroupsInfo;
}
public synchronized ViewClassInfo[] getPreferencesInfo() {
return mPreferencesInfo;
}
public synchronized ViewClassInfo[] getPreferenceGroupsInfo() {
return mPreferenceGroupsInfo;
}
public synchronized Map<String, DeclareStyleableInfo> getXmlMenuDefinitions() {
return mXmlMenuMap;
}
public synchronized Map<String, DeclareStyleableInfo> getXmlSearchableDefinitions() {
return mXmlSearchableMap;
}
public synchronized Map<String, DeclareStyleableInfo> getManifestDefinitions() {
return mManifestMap;
}
public String getDocumentationBaseUrl() {
return mDocBaseUrl == null ? AndroidConstants.CODESITE_BASE_URL : mDocBaseUrl;
}
/**
* Sets the permission values
* @param permissionValues the list of permissions
*/
private void setPermissions(String[] permissionValues) {
setValues("(uses-permission,android:name)", permissionValues); //$NON-NLS-1$
setValues("(application,android:permission)", permissionValues); //$NON-NLS-1$
setValues("(activity,android:permission)", permissionValues); //$NON-NLS-1$
setValues("(receiver,android:permission)", permissionValues); //$NON-NLS-1$
setValues("(service,android:permission)", permissionValues); //$NON-NLS-1$
setValues("(provider,android:permission)", permissionValues); //$NON-NLS-1$
}
private void setIntentFilterActionsAndCategories(String[] activityIntentActions,
String[] broadcastIntentActions, String[] serviceIntentActions,
String[] intentCategoryValues) {
setValues("(activity,action,android:name)", activityIntentActions); //$NON-NLS-1$
setValues("(receiver,action,android:name)", broadcastIntentActions); //$NON-NLS-1$
setValues("(service,action,android:name)", serviceIntentActions); //$NON-NLS-1$
setValues("(category,android:name)", intentCategoryValues); //$NON-NLS-1$
}
/**
* Sets a (name, values) pair in the hash map.
* <p/>
* If the name is already present in the map, it is first removed.
* @param name the name associated with the values.
* @param values The values to add.
*/
private void setValues(String name, String[] values) {
mAttributeValues.remove(name);
mAttributeValues.put(name, values);
}
/**
* Called by the ADT plugin when the SDK path has changed.
* This stores the path locally and then notifies all attached listeners.
*/
private void notifyFrameworkResourcesChangeListeners() {
for (Runnable listener : mResourcesChangeListeners) {
try {
listener.run();
} catch (Exception e) {
CommonPlugin.log(e, "IPathChangedListener failed."); //$NON-NLS-1$
}
}
}
/** Adds a new listener that listens to framework resources changes.
* <p/>If resources have already been set, then the listener is automatically notified. */
public synchronized void addFrameworkResourcesChangeListener(Runnable listener) {
if (listener != null && mResourcesChangeListeners.indexOf(listener) == -1) {
mResourcesChangeListeners.add(listener);
if (mHasResources) {
listener.run();
}
}
}
/** Removes a framework resources changes listener.
* <p/>Safe to call with null or with the same value. */
public synchronized void removeFrameworkResourcesChangeListener(Runnable listener) {
mResourcesChangeListeners.remove(listener);
}
public void setLayoutLibLocation(String osLocation) {
mLayoutLibLocation = osLocation;
}
public String getLayoutLibLocation() {
return mLayoutLibLocation;
}
public void setFrameworkResourcesLocation(String osLocation) {
mFrameworkResourcesLocation = osLocation;
}
public String getFrameworkResourcesLocation() {
return mFrameworkResourcesLocation;
}
public Map<String, Map<String, Integer>> getEnumValueMap() {
return mEnumValueMap;
}
public void setFrameworkFontLocation(String osLocation) {
mFrameworkFontsLocation = osLocation;
}
public String getFrameworkFontLocation() {
return mFrameworkFontsLocation;
}
}

View File

@@ -1,28 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
/**
* Classes which implements this interface provides a method indicating the state of a resource of
* type {@link ResourceType#ID}.
*/
public interface IIdResourceItem {
/**
* Returns whether the ID resource has been declared inline inside another resource XML file.
*/
public boolean isDeclaredInline();
}

View File

@@ -1,29 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
/**
* Classes which implement this interface provide a method that deals with
* a path change.
*/
public interface IPathChangedListener {
/**
* Sent when the location of the android sdk directory changed.
* @param osPath The new android sdk directory location.
*/
public void pathChanged(String osPath);
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
/**
* A repository of resources. This allows access to the resource by {@link ResourceType}.
*/
public interface IResourceRepository {
/**
* Returns the present {@link ResourceType}s in the project.
* @return an array containing all the type of resources existing in the project.
*/
public abstract ResourceType[] getAvailableResourceTypes();
/**
* Returns an array of the existing resource for the specified type.
* @param type the type of the resources to return
*/
public abstract ResourceItem[] getResources(ResourceType type);
/**
* Returns whether resources of the specified type are present.
* @param type the type of the resources to check.
*/
public abstract boolean hasResources(ResourceType type);
/**
* Returns whether the repository is a system repository.
*/
public abstract boolean isSystemRepository();
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
/**
* Base class representing a Resource Item, as returned by a {@link IResourceRepository}.
*/
public class ResourceItem implements Comparable<ResourceItem> {
private final String mName;
/**
* Constructs a new ResourceItem
* @param name the name of the resource as it appears in the XML and R.java files.
*/
public ResourceItem(String name) {
mName = name;
}
/**
* Returns the name of the resource item.
*/
public final String getName() {
return mName;
}
/**
* Compares the {@link ResourceItem} to another.
* @param other the ResourceItem to be compared to.
*/
public int compareTo(ResourceItem other) {
return mName.compareTo(other.mName);
}
}

View File

@@ -1,102 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
/**
* Enum representing a type of compiled resource.
*/
public enum ResourceType {
ANIM("anim", "Animation"), //$NON-NLS-1$
ARRAY("array", "Array"), //$NON-NLS-1$
ATTR("attr", "Attr"), //$NON-NLS-1$
COLOR("color", "Color"), //$NON-NLS-1$
DIMEN("dimen", "Dimension"), //$NON-NLS-1$
DRAWABLE("drawable", "Drawable"), //$NON-NLS-1$
ID("id", "ID"), //$NON-NLS-1$
LAYOUT("layout", "Layout"), //$NON-NLS-1$
MENU("menu", "Menu"), //$NON-NLS-1$
RAW("raw", "Raw"), //$NON-NLS-1$
STRING("string", "String"), //$NON-NLS-1$
STYLE("style", "Style"), //$NON-NLS-1$
STYLEABLE("styleable", "Styleable"), //$NON-NLS-1$
XML("xml", "XML"); //$NON-NLS-1$
private String mName;
private String mDisplayName;
ResourceType(String name, String displayName) {
mName = name;
mDisplayName = displayName;
}
/**
* Returns the resource type name, as used by XML files.
*/
public String getName() {
return mName;
}
/**
* Returns a translated display name for the resource type.
*/
public String getDisplayName() {
return mDisplayName;
}
/**
* Returns the enum by its name as it appears in the XML or the R class.
* @param name name of the resource
* @return the matching {@link ResourceType} or <code>null</code> if no match was found.
*/
public static ResourceType getEnum(String name) {
for (ResourceType rType : values()) {
if (rType.mName.equals(name)) {
return rType;
}
}
return null;
}
/**
* Returns a formatted string usable in an XML to use the specified {@link ResourceItem}.
* @param resourceItem The resource item.
* @param system Whether this is a system resource or a project resource.
* @return a string in the format @[type]/[name]
*/
public String getXmlString(ResourceItem resourceItem, boolean system) {
if (this == ID && resourceItem instanceof IIdResourceItem) {
IIdResourceItem idResource = (IIdResourceItem)resourceItem;
if (idResource.isDeclaredInline()) {
return (system?"@android:":"@+") + mName + "/" + resourceItem.getName(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
return (system?"@android:":"@") + mName + "/" + resourceItem.getName(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* Returns an array with all the names defined by this enum.
*/
public static String[] getNames() {
ResourceType[] values = values();
String[] names = new String[values.length];
for (int i = values.length - 1; i >= 0; --i) {
names[i] = values[i].getName();
}
return names;
}
}

View File

@@ -1,159 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
*
* 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.common.resources;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
/**
* Information needed to represent a View or ViewGroup (aka Layout) item
* in the layout hierarchy, as extracted from the main android.jar and the
* associated attrs.xml.
*/
public class ViewClassInfo {
/** Is this a layout class (i.e. ViewGroup) or just a view? */
private boolean mIsLayout;
/** FQCN e.g. android.view.View, never null. */
private String mCanonicalClassName;
/** Short class name, e.g. View, never null. */
private String mShortClassName;
/** Super class. Can be null. */
private ViewClassInfo mSuperClass;
/** Short javadoc. Can be null. */
private String mJavaDoc;
/** Attributes for this view or view group. Can be empty but never null. */
private AttributeInfo[] mAttributes;
public static class LayoutParamsInfo {
/** Short class name, e.g. LayoutData, never null. */
private String mShortClassName;
/** ViewLayout class info owning this layout data */
private ViewClassInfo mViewLayoutClass;
/** Super class. Can be null. */
private LayoutParamsInfo mSuperClass;
/** Layout Data Attributes for layout classes. Can be empty but not null. */
private AttributeInfo[] mAttributes;
public LayoutParamsInfo(ViewClassInfo enclosingViewClassInfo,
String shortClassName, LayoutParamsInfo superClassInfo) {
mShortClassName = shortClassName;
mViewLayoutClass = enclosingViewClassInfo;
mSuperClass = superClassInfo;
mAttributes = new AttributeInfo[0];
}
/** Returns short class name, e.g. "LayoutData" */
public String getShortClassName() {
return mShortClassName;
}
/** Returns the ViewLayout class info enclosing this layout data. Cannot null. */
public ViewClassInfo getViewLayoutClass() {
return mViewLayoutClass;
}
/** Returns the super class info. Can be null. */
public LayoutParamsInfo getSuperClass() {
return mSuperClass;
}
/** Returns the LayoutData attributes. Can be empty but not null. */
public AttributeInfo[] getAttributes() {
return mAttributes;
}
/** Sets the LayoutData attributes. Can be empty but not null. */
public void setAttributes(AttributeInfo[] attributes) {
mAttributes = attributes;
}
}
/** Layout data info for a layout class. Null for all non-layout classes and always
* non-null for a layout class. */
public LayoutParamsInfo mLayoutData;
// --------
public ViewClassInfo(boolean isLayout, String canonicalClassName, String shortClassName) {
mIsLayout = isLayout;
mCanonicalClassName = canonicalClassName;
mShortClassName = shortClassName;
mAttributes = new AttributeInfo[0];
}
/** Returns whether this is a layout class (i.e. ViewGroup) or just a View */
public boolean isLayout() {
return mIsLayout;
}
/** Returns FQCN e.g. "android.view.View" */
public String getCanonicalClassName() {
return mCanonicalClassName;
}
/** Returns short class name, e.g. "View" */
public String getShortClassName() {
return mShortClassName;
}
/** Returns the super class. Can be null. */
public ViewClassInfo getSuperClass() {
return mSuperClass;
}
/** Returns a short javadoc */
public String getJavaDoc() {
return mJavaDoc;
}
/** Returns the attributes for this view or view group. Maybe empty but not null. */
public AttributeInfo[] getAttributes() {
return mAttributes;
}
/** Returns the LayoutData info for layout classes. Null for non-layout view classes. */
public LayoutParamsInfo getLayoutData() {
return mLayoutData;
}
/**
* Sets a link on the info of the super class of this View or ViewGroup.
* <p/>
* The super class info must be of the same kind (i.e. group to group or view to view)
* except for the top ViewGroup which links to the View info.
* <p/>
* The super class cannot be null except for the top View info.
*/
public void setSuperClass(ViewClassInfo superClass) {
mSuperClass = superClass;
}
/** Sets the javadoc for this View or ViewGroup. */
public void setJavaDoc(String javaDoc) {
mJavaDoc = javaDoc;
}
/** Sets the list of attributes for this View or ViewGroup. */
public void setAttributes(AttributeInfo[] attributes) {
mAttributes = attributes;
}
/**
* Sets the {@link LayoutParamsInfo} for layout classes.
* Does nothing for non-layout view classes.
*/
public void setLayoutParams(LayoutParamsInfo layoutData) {
if (mIsLayout) {
mLayoutData = layoutData;
}
}
}