auto import from //branches/cupcake/...@137873

This commit is contained in:
The Android Open Source Project
2009-03-11 12:11:54 -07:00
parent 692ab02175
commit 243d18eb22
42 changed files with 954 additions and 671 deletions

View File

@@ -473,15 +473,6 @@
id="adt.actionSet1"
label="Android Wizards"
visible="true">
<action
class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
icon="icons/new_adt_project.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
label="New Android Project"
style="push"
toolbarPath="android_project"
tooltip="Opens a wizard to help create a new Android project">
</action>
<action
class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
icon="icons/new_xml.png"
@@ -491,6 +482,15 @@
toolbarPath="android_project"
tooltip="Opens a wizard to help create a new Android XML file">
</action>
<action
class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
icon="icons/new_adt_project.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
label="New Android Project"
style="push"
toolbarPath="android_project"
tooltip="Opens a wizard to help create a new Android project">
</action>
</actionSet>
</extension>
<extension

View File

@@ -21,7 +21,6 @@ import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.FixLaunchConfig;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.common.project.XmlErrorHandler.BasicXmlErrorListener;
@@ -272,7 +271,7 @@ public class PreCompilerBuilder extends BaseBuilder {
// get the manifest file
IFile manifest = AndroidManifestHelper.getManifest(project);
IFile manifest = AndroidManifestParser.getManifest(project);
if (manifest == null) {
String msg = String.format(Messages.s_File_Missing,
@@ -743,7 +742,7 @@ public class PreCompilerBuilder extends BaseBuilder {
// create it if needed
if (destinationFolder.exists() == false && createFolders) {
destinationFolder.create(true /*force*/, true /*local*/,
new SubProgressMonitor(monitor, 10));;
new SubProgressMonitor(monitor, 10));
}
// Build the Java file name from the aidl name.
@@ -824,7 +823,7 @@ public class PreCompilerBuilder extends BaseBuilder {
/**
* Scans a folder and fills the list of aidl files to compile.
* @param sourceFolder the root source folder.
* @param container The folder to scan.
* @param folder The folder to scan.
*/
private void scanFolderForAidl(IFolder sourceFolder, IFolder folder) {
try {

View File

@@ -176,6 +176,7 @@ public class ResourceManagerBuilder extends BaseBuilder {
"Creating 'gen' source folder for generated Java files");
genFolder.create(true /* force */, true /* local */,
new SubProgressMonitor(monitor, 10));
genFolder.setDerived(true);
}
// add it to the source folder list, if needed only (or it will throw)

View File

@@ -31,7 +31,7 @@ import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.launch.DeviceChooserDialog.DeviceChooserResponse;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkManager;
import com.android.sdklib.avd.AvdManager;
@@ -584,8 +584,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
ArrayList<IResource> array = new ArrayList<IResource>(2);
array.add(project);
AndroidManifestHelper helper = new AndroidManifestHelper(project);
IFile manifest = helper.getManifestIFile();
IFile manifest = AndroidManifestParser.getManifest(project);
if (manifest != null) {
array.add(manifest);
}

View File

@@ -36,12 +36,8 @@ import com.android.sdkuilib.AvdSelector;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
@@ -62,6 +58,12 @@ import org.eclipse.swt.widgets.Table;
import java.util.ArrayList;
/**
* A dialog that lets the user choose a device to deploy an application.
* The user can either choose an exiting running device (including running emulators)
* or start a new emulator using an Android Virtual Device configuration that matches
* the current project.
*/
public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener {
private final static int ICON_WIDTH = 16;
@@ -373,15 +375,27 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
mViewer.setContentProvider(new ContentProvider());
mViewer.setLabelProvider(new LabelProvider());
mViewer.setInput(AndroidDebugBridge.getBridge());
mViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
ISelection selection = event.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection)selection;
Object object = structuredSelection.getFirstElement();
if (object instanceof Device) {
mResponse.setDeviceToUse((Device)object);
}
mDeviceTable.addSelectionListener(new SelectionAdapter() {
/**
* Handles single-click selection on the device selector.
* {@inheritDoc}
*/
@Override
public void widgetSelected(SelectionEvent e) {
handleDeviceSelection();
}
/**
* Handles double-click selection on the device selector.
* Note that the single-click handler will probably already have been called.
* {@inheritDoc}
*/
@Override
public void widgetDefaultSelected(SelectionEvent e) {
handleDeviceSelection();
if (isOkButtonEnabled()) {
okPressed();
}
}
});
@@ -397,18 +411,14 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
layout.marginLeft = 30;
offsetComp.setLayout(layout);
mPreferredAvdSelector = new AvdSelector(offsetComp, getNonRunningAvds(), mProjectTarget,
false /*allowMultipleSelection*/);
mPreferredAvdSelector = new AvdSelector(offsetComp, getNonRunningAvds(), mProjectTarget);
mPreferredAvdSelector.setTableHeightHint(100);
mPreferredAvdSelector.setEnabled(false);
mDeviceTable.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleDeviceSelection();
}
});
mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
/**
* Handles single-click selection on the AVD selector.
* {@inheritDoc}
*/
@Override
public void widgetSelected(SelectionEvent e) {
if (mDisableAvdSelectionChange == false) {
@@ -416,6 +426,22 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
enableOkButton();
}
}
/**
* Handles double-click selection on the AVD selector.
*
* Note that the single-click handler will probably already have been called
* but the selected item can have changed in between.
*
* {@inheritDoc}
*/
@Override
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
if (isOkButtonEnabled()) {
okPressed();
}
}
});
AndroidDebugBridge.addDeviceChangeListener(this);
@@ -586,6 +612,14 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
okButton.setEnabled(mResponse.getAvdToLaunch() != null);
}
}
/**
* Returns true if the ok button is enabled.
*/
private boolean isOkButtonEnabled() {
Button okButton = getButton(IDialogConstants.OK_ID);
return okButton.isEnabled();
}
/**
* Executes the {@link Runnable} in the UI thread.

View File

@@ -178,8 +178,7 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
mPreferredAvdLabel = new Label(offsetComp, SWT.NONE);
mPreferredAvdLabel.setText("Select a preferred Android Virtual Device:");
AvdInfo[] avds = new AvdInfo[0];
mPreferredAvdSelector = new AvdSelector(offsetComp, avds,
false /*allowMultipleSelection*/);
mPreferredAvdSelector = new AvdSelector(offsetComp, avds);
mPreferredAvdSelector.setTableHeightHint(100);
mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
@Override

View File

@@ -19,9 +19,9 @@ package com.android.ide.eclipse.adt.project;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
@@ -389,18 +389,16 @@ public final class ProjectHelper {
continue;
}
AndroidManifestHelper androidManifest = new AndroidManifestHelper(p);
// check that there is indeed a manifest file.
if (androidManifest.getManifestIFile() == null) {
IFile manifestFile = AndroidManifestParser.getManifest(p);
if (manifestFile == null) {
// no file? skip this project.
continue;
}
AndroidManifestParser parser = null;
try {
parser = AndroidManifestParser.parseForData(
androidManifest.getManifestIFile());
parser = AndroidManifestParser.parseForData(manifestFile);
} catch (CoreException e) {
// skip this project.
continue;

View File

@@ -44,7 +44,7 @@ public class AndroidTargetData {
public final static int DESCRIPTOR_RESOURCES = 5;
public final static int DESCRIPTOR_SEARCHABLE = 6;
public final static int DESCRIPTOR_PREFERENCES = 7;
public final static int DESCRIPTOR_GADGET_PROVIDER = 8;
public final static int DESCRIPTOR_APPWIDGET_PROVIDER = 8;
public final static class LayoutBridge {
/** Link to the layout bridge */
@@ -158,8 +158,8 @@ public class AndroidTargetData {
return ResourcesDescriptors.getInstance();
case DESCRIPTOR_PREFERENCES:
return mXmlDescriptors.getPreferencesProvider();
case DESCRIPTOR_GADGET_PROVIDER:
return mXmlDescriptors.getGadgetProvider();
case DESCRIPTOR_APPWIDGET_PROVIDER:
return mXmlDescriptors.getAppWidgetProvider();
case DESCRIPTOR_SEARCHABLE:
return mXmlDescriptors.getSearchableProvider();
default :

View File

@@ -203,9 +203,9 @@ public final class AndroidTargetParser {
attrsManifestXmlParser);
Map<String, Map<String, Integer>> enumValueMap = attrsXmlParser.getEnumFlagValues();
Map<String, DeclareStyleableInfo> xmlGadgetMap = null;
Map<String, DeclareStyleableInfo> xmlAppWidgetMap = null;
if (mAndroidTarget.getApiVersionNumber() >= 3) {
xmlGadgetMap = collectGadgetDefinitions(attrsXmlParser);
xmlAppWidgetMap = collectAppWidgetDefinitions(attrsXmlParser);
}
if (progress.isCanceled()) {
@@ -241,7 +241,7 @@ public final class AndroidTargetParser {
XmlDescriptors xmlDescriptors = new XmlDescriptors();
xmlDescriptors.updateDescriptors(
xmlSearchableMap,
xmlGadgetMap,
xmlAppWidgetMap,
preferencesInfo,
preferenceGroupsInfo);
progress.worked(1);
@@ -611,23 +611,23 @@ public final class AndroidTargetParser {
}
/**
* Collects all gadgetProviderInfo definition information from the attrs.xml and returns it.
* Collects all appWidgetProviderInfo definition information from the attrs.xml and returns it.
*
* @param attrsXmlParser The parser of the attrs.xml file
*/
private Map<String, DeclareStyleableInfo> collectGadgetDefinitions(
private Map<String, DeclareStyleableInfo> collectAppWidgetDefinitions(
AttrsXmlParser attrsXmlParser) {
Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
for (String key : new String[] { "GadgetProviderInfo" }) { //$NON-NLS-1$
for (String key : new String[] { "AppWidgetProviderInfo" }) { //$NON-NLS-1$
if (map.containsKey(key)) {
map2.put(key, map.get(key));
} else {
AdtPlugin.log(IStatus.WARNING,
"Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
"AppWidget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
key, attrsXmlParser.getOsAttrsXmlPath());
AdtPlugin.printErrorToConsole("Android Framework Parser",
String.format("Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
String.format("AppWidget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
key, attrsXmlParser.getOsAttrsXmlPath()));
}
}

View File

@@ -24,7 +24,7 @@ package com.android.ide.eclipse.adt.wizards.newproject;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.project.ProjectProperties;
@@ -36,6 +36,7 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
@@ -821,26 +822,41 @@ public class NewProjectCreationPage extends WizardPage {
Path path = new Path(f.getPath());
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
if (!manifest.exists()) {
AndroidManifestParser manifestData = null;
try {
manifestData = AndroidManifestParser.parseForData(osPath);
} catch (CoreException e1) {
// ignore any parsing issue
}
if (manifestData == null) {
return;
}
String packageName = null;
String activityName = null;
String minSdkVersion = null;
int minSdkVersion = 0; // 0 means no minSdkVersion provided in the manifest
try {
packageName = manifest.getPackageName();
activityName = manifest.getActivityName(1);
minSdkVersion = manifest.getMinSdkVersion();
packageName = manifestData.getPackage();
minSdkVersion = manifestData.getApiLevelRequirement();
// try to get the first launcher activity. If none, just take the first activity.
activityName = manifestData.getLauncherActivity();
if (activityName == null) {
String[] activities = manifestData.getActivities();
if (activities != null && activities.length > 0) {
activityName = activities[0];
}
}
} catch (Exception e) {
// ignore exceptions
}
if (packageName != null && packageName.length() > 0) {
mPackageNameField.setText(packageName);
}
activityName = AndroidManifestParser.extractActivityName(activityName, packageName);
if (activityName != null && activityName.length() > 0) {
mInternalActivityNameUpdate = true;
@@ -917,12 +933,10 @@ public class NewProjectCreationPage extends WizardPage {
}
}
if (!foundTarget && minSdkVersion != null) {
if (!foundTarget && minSdkVersion > 0) {
try {
int sdkVersion = Integer.parseInt(minSdkVersion);
for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
if (target.getApiVersionNumber() == sdkVersion) {
if (target.getApiVersionNumber() == minSdkVersion) {
mSdkTargetSelector.setSelection(target);
foundTarget = true;
break;
@@ -945,7 +959,8 @@ public class NewProjectCreationPage extends WizardPage {
if (!foundTarget) {
mInternalMinSdkVersionUpdate = true;
mMinSdkVersionField.setText(minSdkVersion == null ? "" : minSdkVersion); //$NON-NLS-1$
mMinSdkVersionField.setText(
minSdkVersion <= 0 ? "" : Integer.toString(minSdkVersion)); //$NON-NLS-1$
mInternalMinSdkVersionUpdate = false;
}
}
@@ -1072,8 +1087,8 @@ public class NewProjectCreationPage extends WizardPage {
// Check there's an android manifest in the directory
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
if (!manifest.exists()) {
File manifestFile = new File(osPath);
if (!manifestFile.isFile()) {
return setStatus(
String.format("File %1$s not found in %2$s.",
AndroidConstants.FN_ANDROID_MANIFEST, f.getName()),
@@ -1081,15 +1096,24 @@ public class NewProjectCreationPage extends WizardPage {
}
// Parse it and check the important fields.
String packageName = manifest.getPackageName();
AndroidManifestParser manifestData;
try {
manifestData = AndroidManifestParser.parseForData(osPath);
} catch (CoreException e) {
return setStatus(
String.format("File %1$s could not be parsed.", osPath),
MSG_ERROR);
}
String packageName = manifestData.getPackage();
if (packageName == null || packageName.length() == 0) {
return setStatus(
String.format("No package name defined in %1$s.", osPath),
MSG_ERROR);
}
String activityName = manifest.getActivityName(1);
if (activityName == null || activityName.length() == 0) {
String[] activities = manifestData.getActivities();
if (activities == null || activities.length == 0) {
// This is acceptable now as long as no activity needs to be created
if (isCreateActivity()) {
return setStatus(
@@ -1097,7 +1121,7 @@ public class NewProjectCreationPage extends WizardPage {
MSG_ERROR);
}
}
// If there's already a .project, tell the user to use import instead.
if (path.append(".project").toFile().exists()) { //$NON-NLS-1$
return setStatus("An Eclipse project already exists in this directory. Consider using File > Import > Existing Project instead.",

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 mXPath.evaluate("/manifest/@package", getSource()); //$NON-NLS-1$
} 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 minSdkVersion defined in the manifest file.
*
* @return A String object with the package or null if any error happened.
*/
public String getMinSdkVersion() {
try {
return mXPath.evaluate("/manifest/uses-sdk/@" //$NON-NLS-1$
+ AndroidXPathFactory.DEFAULT_NS_PREFIX
+ ":minSdkVersion", getSource()); //$NON-NLS-1$
} 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 index The 1-based index of the activity to return.
* @return A String object with the activity or null if any error happened.
*/
public String getActivityName(int index) {
try {
return mXPath.evaluate("/manifest/application/activity[" //$NON-NLS-1$
+ index
+ "]/@" //$NON-NLS-1$
+ AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$
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;
}
}

View File

@@ -22,6 +22,8 @@ import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaProject;
import org.xml.sax.Attributes;
@@ -30,6 +32,8 @@ import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
@@ -56,6 +60,8 @@ public class AndroidManifestParser {
private final static String NODE_ACTION = "action"; //$NON-NLS-1$
private final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
private final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$
private final static String NODE_INSTRUMENTATION = "instrumentation"; //$NON-NLS-1$
private final static String NODE_USES_LIBRARY = "uses-library"; //$NON-NLS-1$
private final static int LEVEL_MANIFEST = 0;
private final static int LEVEL_APPLICATION = 1;
@@ -66,6 +72,12 @@ public class AndroidManifestParser {
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$
/**
* XML error & data handler used when parsing the AndroidManifest.xml file.
* <p/>
* This serves both as an {@link XmlErrorHandler} to report errors and as a data repository
* to collect data from the manifest.
*/
private static class ManifestHandler extends XmlErrorHandler {
//--- data read from the parsing
@@ -82,6 +94,10 @@ public class AndroidManifestParser {
private Boolean mDebuggable = null;
/** API level requirement. if 0 the attribute was not present. */
private int mApiLevelRequirement = 0;
/** List of all instrumentations declared by the manifest */
private final ArrayList<String> mInstrumentations = new ArrayList<String>();
/** List of all libraries in use declared by the manifest */
private final ArrayList<String> mLibraries = new ArrayList<String>();
//--- temporary data/flags used during parsing
private IJavaProject mJavaProject;
@@ -95,12 +111,13 @@ public class AndroidManifestParser {
private Locator mLocator;
/**
*
* @param manifestFile
* @param errorListener
* @param gatherData
* @param javaProject
* @param markErrors
* Creates a new {@link ManifestHandler}, which is also an {@link XmlErrorHandler}.
*
* @param manifestFile The manifest file being parsed. Can be null.
* @param errorListener An optional error listener.
* @param gatherData True if data should be gathered.
* @param javaProject The java project holding the manifest file. Can be null.
* @param markErrors True if errors should be marked as Eclipse Markers on the resource.
*/
ManifestHandler(IFile manifestFile, XmlErrorListener errorListener,
boolean gatherData, IJavaProject javaProject, boolean markErrors) {
@@ -160,6 +177,23 @@ public class AndroidManifestParser {
return mApiLevelRequirement;
}
/**
* Returns the list of instrumentations found in the manifest.
* @return An array of instrumentation names, or empty if no instrumentations were
* found.
*/
String[] getInstrumentations() {
return mInstrumentations.toArray(new String[mInstrumentations.size()]);
}
/**
* Returns the list of libraries in use found in the manifest.
* @return An array of library names, or empty if no libraries were found.
*/
String[] getUsesLibraries() {
return mLibraries.toArray(new String[mLibraries.size()]);
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
*/
@@ -217,7 +251,13 @@ public class AndroidManifestParser {
} catch (NumberFormatException e) {
handleError(e, -1 /* lineNumber */);
}
}
} else if (NODE_INSTRUMENTATION.equals(localName)) {
value = getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */);
if (value != null) {
mInstrumentations.add(value);
}
}
break;
case LEVEL_ACTIVITY:
if (NODE_ACTIVITY.equals(localName)) {
@@ -232,7 +272,13 @@ public class AndroidManifestParser {
} else if (NODE_PROVIDER.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
mValidLevel++;
}
} else if (NODE_USES_LIBRARY.equals(localName)) {
value = getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */);
if (value != null) {
mLibraries.add(value);
}
}
break;
case LEVEL_INTENT_FILTER:
// only process this level if we are in an activity
@@ -355,8 +401,7 @@ public class AndroidManifestParser {
String activityName = getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */);
if (activityName != null) {
mCurrentActivity = AndroidManifestHelper.combinePackageAndClassName(mPackage,
activityName);
mCurrentActivity = combinePackageAndClassName(mPackage, activityName);
mActivities.add(mCurrentActivity);
if (mMarkErrors) {
@@ -387,8 +432,7 @@ public class AndroidManifestParser {
String serviceName = getAttributeValue(attributes, ATTRIBUTE_NAME,
true /* hasNamespace */);
if (serviceName != null) {
serviceName = AndroidManifestHelper.combinePackageAndClassName(mPackage,
serviceName);
serviceName = combinePackageAndClassName(mPackage, serviceName);
if (mMarkErrors) {
checkClass(serviceName, superClassName, false /* testVisibility */);
@@ -412,6 +456,9 @@ public class AndroidManifestParser {
* the class or of its constructors.
*/
private void checkClass(String className, String superClassName, boolean testVisibility) {
if (mJavaProject == null) {
return;
}
// we need to check the validity of the activity.
String result = BaseProjectHelper.testClassForManifest(mJavaProject,
className, superClassName, testVisibility);
@@ -477,6 +524,8 @@ public class AndroidManifestParser {
private final String[] mProcesses;
private final Boolean mDebuggable;
private final int mApiLevelRequirement;
private final String[] mInstrumentations;
private final String[] mLibraries;
static {
sParserFactory = SAXParserFactory.newInstance();
@@ -484,8 +533,12 @@ public class AndroidManifestParser {
}
/**
* Parses the Android Manifest, and returns an object containing
* the result of the parsing.
* Parses the Android Manifest, and returns an object containing the result of the parsing.
* <p/>
* This method is useful to parse a specific {@link IFile} in a Java project.
* <p/>
* If you only want to gather data, consider {@link #parseForData(IFile)} instead.
*
* @param javaProject The java project.
* @param manifestFile the {@link IFile} representing the manifest file.
* @param errorListener
@@ -496,8 +549,12 @@ public class AndroidManifestParser {
* @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)
public static AndroidManifestParser parse(
IJavaProject javaProject,
IFile manifestFile,
XmlErrorListener errorListener,
boolean gatherData,
boolean markErrors)
throws CoreException {
try {
SAXParser parser = sParserFactory.newSAXParser();
@@ -512,7 +569,51 @@ public class AndroidManifestParser {
return new AndroidManifestParser(manifestHandler.getPackage(),
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
manifestHandler.getApiLevelRequirement());
manifestHandler.getApiLevelRequirement(), manifestHandler.getInstrumentations(),
manifestHandler.getUsesLibraries());
} catch (ParserConfigurationException e) {
} catch (SAXException e) {
} catch (IOException e) {
} finally {
}
return null;
}
/**
* Parses the Android Manifest, and returns an object containing the result of the parsing.
* <p/>
* This version parses a real {@link File} file given by an actual path, which is useful for
* parsing a file that is not part of an Eclipse Java project.
* <p/>
* It assumes errors cannot be marked on the file and that data gathering is enabled.
*
* @param manifestFile the manifest file to parse.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
*/
private static AndroidManifestParser parse(File manifestFile)
throws CoreException {
try {
SAXParser parser = sParserFactory.newSAXParser();
ManifestHandler manifestHandler = new ManifestHandler(
null, //manifestFile
null, //errorListener
true, //gatherData
null, //javaProject
false //markErrors
);
parser.parse(new InputSource(new FileReader(manifestFile)), manifestHandler);
// get the result from the handler
return new AndroidManifestParser(manifestHandler.getPackage(),
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
manifestHandler.getApiLevelRequirement(), manifestHandler.getInstrumentations(),
manifestHandler.getUsesLibraries());
} catch (ParserConfigurationException e) {
} catch (SAXException e) {
} catch (IOException e) {
@@ -535,13 +636,16 @@ public class AndroidManifestParser {
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
*/
public static AndroidManifestParser parse(IJavaProject javaProject,
XmlErrorListener errorListener, boolean gatherData, boolean markErrors)
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());
IFile manifestFile = getManifest(javaProject.getProject());
if (manifestFile != null) {
ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
errorListener, gatherData, javaProject, markErrors);
@@ -552,7 +656,8 @@ public class AndroidManifestParser {
return new AndroidManifestParser(manifestHandler.getPackage(),
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
manifestHandler.getApiLevelRequirement());
manifestHandler.getApiLevelRequirement(),
manifestHandler.getInstrumentations(), manifestHandler.getUsesLibraries());
}
} catch (ParserConfigurationException e) {
} catch (SAXException e) {
@@ -588,6 +693,18 @@ public class AndroidManifestParser {
true /* gatherData */, false /* markErrors */);
}
/**
* Parses the manifest file, and collects data.
*
* @param osManifestFilePath The OS path of the manifest file to parse.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
*/
public static AndroidManifestParser parseForData(String osManifestFilePath)
throws CoreException {
return parse(new File(osManifestFilePath));
}
/**
* Returns the package defined in the manifest, if found.
* @return The package name or null if not found.
@@ -633,6 +750,22 @@ public class AndroidManifestParser {
public int getApiLevelRequirement() {
return mApiLevelRequirement;
}
/**
* Returns the list of instrumentations found in the manifest.
* @return An array of fully qualified class names, or empty if no instrumentations were found.
*/
public String[] getInstrumentations() {
return mInstrumentations;
}
/**
* Returns the list of libraries in use found in the manifest.
* @return An array of library names, or empty if no uses-library declarations were found.
*/
public String[] getUsesLibraries() {
return mLibraries;
}
/**
@@ -647,15 +780,92 @@ public class AndroidManifestParser {
* @param processes the list of custom processes declared in the manifest.
* @param debuggable the debuggable attribute, or null if not set.
* @param apiLevelRequirement the minSdkVersion attribute value or 0 if not set.
* @param instrumentations the list of instrumentations parsed from the manifest.
* @param libraries the list of libraries in use parsed from the manifest.
*/
private AndroidManifestParser(String javaPackage, String[] activities,
String launcherActivity, String[] processes, Boolean debuggable,
int apiLevelRequirement) {
int apiLevelRequirement, String[] instrumentations, String[] libraries) {
mJavaPackage = javaPackage;
mActivities = activities;
mLauncherActivity = launcherActivity;
mProcesses = processes;
mDebuggable = debuggable;
mApiLevelRequirement = apiLevelRequirement;
mInstrumentations = instrumentations;
mLibraries = libraries;
}
/**
* 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;
}
}
/**
* Given a fully qualified activity name (e.g. com.foo.test.MyClass) and given a project
* package base name (e.g. com.foo), returns the relative activity name that would be used
* the "name" attribute of an "activity" element.
*
* @param fullActivityName a fully qualified activity class name, e.g. "com.foo.test.MyClass"
* @param packageName The project base package name, e.g. "com.foo"
* @return The relative activity name if it can be computed or the original fullActivityName.
*/
public static String extractActivityName(String fullActivityName, String packageName) {
if (packageName != null && fullActivityName != null) {
if (packageName.length() > 0 && fullActivityName.startsWith(packageName)) {
String name = fullActivityName.substring(packageName.length());
if (name.length() > 0 && name.charAt(0) == '.') {
return name;
}
}
}
return fullActivityName;
}
}

View File

@@ -86,8 +86,13 @@ public class XmlErrorHandler extends DefaultHandler {
*/
@Override
public void warning(SAXParseException exception) throws SAXException {
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
exception.getLineNumber(), IMarker.SEVERITY_WARNING);
if (mFile != null) {
BaseProjectHelper.addMarker(mFile,
AndroidConstants.MARKER_XML,
exception.getMessage(),
exception.getLineNumber(),
IMarker.SEVERITY_WARNING);
}
}
protected final IFile getFile() {
@@ -104,12 +109,19 @@ public class XmlErrorHandler extends DefaultHandler {
mErrorListener.errorFound();
}
if (lineNumber != -1) {
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
lineNumber, IMarker.SEVERITY_ERROR);
} else {
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
IMarker.SEVERITY_ERROR);
if (mFile != null) {
if (lineNumber != -1) {
BaseProjectHelper.addMarker(mFile,
AndroidConstants.MARKER_XML,
exception.getMessage(),
lineNumber,
IMarker.SEVERITY_ERROR);
} else {
BaseProjectHelper.addMarker(mFile,
AndroidConstants.MARKER_XML,
exception.getMessage(),
IMarker.SEVERITY_ERROR);
}
}
}
}

View File

@@ -442,11 +442,15 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
tooltip = ((TextAttributeDescriptor) choice).getTooltip();
}
// Get the namespace URI for the attribute. Note that some attributes
// do not have a namespace and thus return null here.
String nsUri = ((AttributeDescriptor)choice).getNamespaceUri();
nsPrefix = nsUriMap.get(nsUri);
if (nsPrefix == null) {
nsPrefix = lookupNamespacePrefix(currentNode, nsUri);
nsUriMap.put(nsUri, nsPrefix);
if (nsUri != null) {
nsPrefix = nsUriMap.get(nsUri);
if (nsPrefix == null) {
nsPrefix = lookupNamespacePrefix(currentNode, nsUri);
nsUriMap.put(nsUri, nsPrefix);
}
}
if (nsPrefix != null) {
nsPrefix += ":"; //$NON-NLS-1$

View File

@@ -18,12 +18,14 @@ package com.android.ide.eclipse.editors.layout;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.editors.resources.manager.ProjectClassLoader;
import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
import com.android.layoutlib.api.IProjectCallback;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
@@ -83,17 +85,20 @@ public final class ProjectCallback implements IProjectCallback {
}
/**
* {@inheritDoc}
*
* Returns the namespace for the project. The namespace contains a standard part + the
* application package.
*
* @return The package namespace of the project or null in case of error.
*/
public String getNamespace() {
if (mNamespace == null) {
AndroidManifestHelper manifest = new AndroidManifestHelper(mProject);
String javaPackage = manifest.getPackageName();
mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage);
IFile manifestFile = AndroidManifestParser.getManifest(mProject);
try {
AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
String javaPackage = data.getPackage();
mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage);
} catch (CoreException e) {
}
}
return mNamespace;

View File

@@ -17,6 +17,8 @@
package com.android.ide.eclipse.editors.layout.descriptors;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.common.resources.ViewClassInfo;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
@@ -25,6 +27,7 @@ import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.editors.descriptors.ReferenceAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
import com.android.sdklib.SdkConstants;
@@ -131,8 +134,23 @@ public final class LayoutDescriptors implements IDescriptorProvider {
String xml_name = info.getShortClassName();
String tooltip = info.getJavaDoc();
// Process all View attributes
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
// All views and groups have an implicit "style" attribute which is a reference.
AttributeInfo styleInfo = new DeclareStyleableInfo.AttributeInfo(
"style", //$NON-NLS-1$ xmlLocalName
new DeclareStyleableInfo.AttributeInfo.Format[] {
DeclareStyleableInfo.AttributeInfo.Format.REFERENCE
});
styleInfo.setJavaDoc("A reference to a custom style"); //tooltip
DescriptorsUtils.appendAttribute(attributes,
"style", //$NON-NLS-1$
null, //nsUri
styleInfo,
false, //required
null); // overrides
// Process all View attributes
DescriptorsUtils.appendAttributes(attributes,
null, // elementName
SdkConstants.NS_RESOURCES,
@@ -155,7 +173,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
null /* overrides */);
}
}
// Process all LayoutParams attributes
ArrayList<AttributeDescriptor> layoutAttributes = new ArrayList<AttributeDescriptor>();
LayoutParamsInfo layoutParams = info.getLayoutData();

View File

@@ -17,7 +17,7 @@
package com.android.ide.eclipse.editors.manifest.model;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.editors.AndroidEditor;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
@@ -251,8 +251,8 @@ public class UiClassAttributeNode extends UiTextAttributeNode {
String javaPackage = getManifestPackage();
// build the fully qualified name of the class
String className = AndroidManifestHelper.combinePackageAndClassName(javaPackage,
textValue);
String className = AndroidManifestParser.combinePackageAndClassName(
javaPackage, textValue);
// only test the vilibility for activities.
boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals(

View File

@@ -18,7 +18,7 @@ package com.android.ide.eclipse.editors.resources.manager;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
@@ -28,6 +28,7 @@ import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -120,7 +121,14 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi
if (projectResources != null) {
// create the classname
String className = getRClassName(project);
if (className == null) {
// We need to abort.
AdtPlugin.log(IStatus.ERROR,
"loadAndParseRClass: failed to find manifest package for project %1$s", //$NON-NLS-1$
project.getName());
return;
}
// create a temporary class loader to load it.
ProjectClassLoader loader = new ProjectClassLoader(null /* parentClassLoader */,
project);
@@ -199,13 +207,28 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi
}
return false;
}
/**
* Returns the class name of the R class, based on the project's manifest's package.
*
* @return A class name (e.g. "my.app.R") or null if there's no valid package in the manifest.
*/
private String getRClassName(IProject project) {
// create the classname
AndroidManifestHelper manifest = new AndroidManifestHelper(project);
String javaPackage = manifest.getPackageName();
return javaPackage + ".R"; //$NON-NLS-1$
try {
IFile manifestFile = AndroidManifestParser.getManifest(project);
AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
String javaPackage = data.getPackage();
return javaPackage + ".R"; //$NON-NLS-1$
} catch (CoreException e) {
// This will typically happen either because the manifest file is not present
// and/or the workspace needs to be refreshed.
AdtPlugin.logAndPrintError(e,
"Android Resources",
"Failed to find the package of the AndroidManifest of project %1$s. Reason: %2$s",
project.getName(),
e.getMessage());
return null;
}
}
}

View File

@@ -222,10 +222,10 @@ class NewXmlFileCreationPage extends WizardPage {
null, // default attributes
1 // target API level
),
new TypeInfo("Gadget Provider", // UI name
"An XML file that describes a gadget provider.", // tooltip
new TypeInfo("AppWidget Provider", // UI name
"An XML file that describes a widget provider.", // tooltip
ResourceFolderType.XML, // folder type
AndroidTargetData.DESCRIPTOR_GADGET_PROVIDER, // root seed
AndroidTargetData.DESCRIPTOR_APPWIDGET_PROVIDER, // root seed
null, // default root
SdkConstants.NS_RESOURCES, // xmlns
null, // default attributes
@@ -1109,7 +1109,7 @@ class NewXmlFileCreationPage extends WizardPage {
TypeInfo type = getSelectedType();
if (type.getTargetApiLevel() > currentApiLevel) {
error = "The API level of the selected type (e.g. gadget, etc.) is not " +
error = "The API level of the selected type (e.g. AppWidget, etc.) is not " +
"compatible with the API level of the project.";
}
}

View File

@@ -53,8 +53,8 @@ public final class XmlDescriptors implements IDescriptorProvider {
/** The root document descriptor for preferences. */
private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
/** The root document descriptor for gadget provider. */
private DocumentDescriptor mGadgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
/** The root document descriptor for widget provider. */
private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
/** @return the root descriptor for both searchable and preferences. */
public DocumentDescriptor getDescriptor() {
@@ -75,9 +75,9 @@ public final class XmlDescriptors implements IDescriptorProvider {
return mPrefDescriptor;
}
/** @return the root descriptor for gadget providers. */
public DocumentDescriptor getGadgetDescriptor() {
return mGadgetDescriptor;
/** @return the root descriptor for widget providers. */
public DocumentDescriptor getAppWidgetDescriptor() {
return mAppWidgetDescriptor;
}
public IDescriptorProvider getSearchableProvider() {
@@ -104,14 +104,14 @@ public final class XmlDescriptors implements IDescriptorProvider {
};
}
public IDescriptorProvider getGadgetProvider() {
public IDescriptorProvider getAppWidgetProvider() {
return new IDescriptorProvider() {
public ElementDescriptor getDescriptor() {
return mGadgetDescriptor;
return mAppWidgetDescriptor;
}
public ElementDescriptor[] getRootElementDescriptors() {
return mGadgetDescriptor.getChildren();
return mAppWidgetDescriptor.getChildren();
}
};
}
@@ -123,13 +123,13 @@ public final class XmlDescriptors implements IDescriptorProvider {
* all at once.
*
* @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file
* @param gadgetStyleMap The map style=>attributes for <gadget-provider> from the attrs.xml file
* @param appWidgetStyleMap The map style=>attributes for <appwidget-provider> from the attrs.xml file
* @param prefs The list of non-group preference descriptions
* @param prefGroups The list of preference group descriptions
*/
public synchronized void updateDescriptors(
Map<String, DeclareStyleableInfo> searchableStyleMap,
Map<String, DeclareStyleableInfo> gadgetStyleMap,
Map<String, DeclareStyleableInfo> appWidgetStyleMap,
ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
@@ -137,16 +137,16 @@ public final class XmlDescriptors implements IDescriptorProvider {
SdkConstants.NS_RESOURCES);
ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
ElementDescriptor gadget = createGadgetProviderInfo(gadgetStyleMap, xmlns);
ElementDescriptor appWidget = createAppWidgetProviderInfo(appWidgetStyleMap, xmlns);
ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns);
ArrayList<ElementDescriptor> list = new ArrayList<ElementDescriptor>();
if (searchable != null) {
list.add(searchable);
mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable });
}
if (gadget != null) {
list.add(gadget);
mGadgetDescriptor.setChildren(new ElementDescriptor[]{ gadget });
if (appWidget != null) {
list.add(appWidget);
mAppWidgetDescriptor.setChildren(new ElementDescriptor[]{ appWidget });
}
if (preferences != null) {
list.add(preferences);
@@ -190,25 +190,25 @@ public final class XmlDescriptors implements IDescriptorProvider {
}
/**
* Returns the new ElementDescriptor for <gadget-provider>
* Returns the new ElementDescriptor for <appwidget-provider>
*/
private ElementDescriptor createGadgetProviderInfo(
Map<String, DeclareStyleableInfo> gadgetStyleMap,
private ElementDescriptor createAppWidgetProviderInfo(
Map<String, DeclareStyleableInfo> appWidgetStyleMap,
XmlnsAttributeDescriptor xmlns) {
if (gadgetStyleMap == null) {
if (appWidgetStyleMap == null) {
return null;
}
ElementDescriptor gadget = createElement(gadgetStyleMap,
"GadgetProviderInfo", //$NON-NLS-1$ styleName
"gadget-provider", //$NON-NLS-1$ xmlName
"Gadget Provider", // uiName
ElementDescriptor appWidget = createElement(appWidgetStyleMap,
"AppWidgetProviderInfo", //$NON-NLS-1$ styleName
"appwidget-provider", //$NON-NLS-1$ xmlName
"AppWidget Provider", // uiName
null, // sdk url
xmlns, // extraAttribute
null, // childrenElements
false /* mandatory */ );
return gadget;
return appWidget;
}
/**