diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java | 578 |
1 files changed, 0 insertions, 578 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java deleted file mode 100644 index 55ebf5970..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java +++ /dev/null @@ -1,578 +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.adt.internal.editors.manifest; - -import static com.android.SdkConstants.ANDROID_URI; -import static com.android.SdkConstants.ATTR_NAME; -import static com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors.USES_PERMISSION; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.ApplicationPage; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.InstrumentationPage; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.OverviewPage; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.PermissionPage; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.Region; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; -import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import java.util.Collection; -import java.util.List; - -/** - * Multi-page form editor for AndroidManifest.xml. - */ -@SuppressWarnings("restriction") -public final class ManifestEditor extends AndroidXmlEditor { - - public static final String ID = AdtConstants.EDITORS_NAMESPACE + ".manifest.ManifestEditor"; //$NON-NLS-1$ - - private final static String EMPTY = ""; //$NON-NLS-1$ - - /** Root node of the UI element hierarchy */ - private UiElementNode mUiManifestNode; - /** The Application Page tab */ - private ApplicationPage mAppPage; - /** The Overview Manifest Page tab */ - private OverviewPage mOverviewPage; - /** The Permission Page tab */ - private PermissionPage mPermissionPage; - /** The Instrumentation Page tab */ - private InstrumentationPage mInstrumentationPage; - - private IFileListener mMarkerMonitor; - - - /** - * Creates the form editor for AndroidManifest.xml. - */ - public ManifestEditor() { - super(); - addDefaultTargetListener(); - } - - @Override - public void dispose() { - super.dispose(); - - GlobalProjectMonitor.getMonitor().removeFileListener(mMarkerMonitor); - } - - @Override - public void activated() { - super.activated(); - clearActionBindings(false); - } - - @Override - public void deactivated() { - super.deactivated(); - updateActionBindings(); - } - - @Override - protected void pageChange(int newPageIndex) { - super.pageChange(newPageIndex); - if (newPageIndex == mTextPageIndex) { - updateActionBindings(); - } else { - clearActionBindings(false); - } - } - - @Override - protected int getPersistenceCategory() { - return CATEGORY_MANIFEST; - } - - /** - * Return the root node of the UI element hierarchy, which here - * is the "manifest" node. - */ - @Override - public UiElementNode getUiRootNode() { - return mUiManifestNode; - } - - /** - * Returns the Manifest descriptors for the file being edited. - */ - public AndroidManifestDescriptors getManifestDescriptors() { - AndroidTargetData data = getTargetData(); - if (data != null) { - return data.getManifestDescriptors(); - } - - return null; - } - - // ---- Base Class Overrides ---- - - /** - * Returns whether the "save as" operation is supported by this editor. - * <p/> - * Save-As is a valid operation for the ManifestEditor since it acts on a - * single source file. - * - * @see IEditorPart - */ - @Override - public boolean isSaveAsAllowed() { - return true; - } - - @Override - public void doSave(IProgressMonitor monitor) { - // Look up the current (pre-save) values of minSdkVersion and targetSdkVersion - int prevMinSdkVersion = -1; - int prevTargetSdkVersion = -1; - IProject project = null; - ManifestInfo info = null; - try { - project = getProject(); - if (project != null) { - info = ManifestInfo.get(project); - prevMinSdkVersion = info.getMinSdkVersion(); - prevTargetSdkVersion = info.getTargetSdkVersion(); - info.clear(); - } - } catch (Throwable t) { - // We don't expect exceptions from the above calls, but we *really* - // need to make sure that nothing can prevent the save function from - // getting called! - AdtPlugin.log(t, null); - } - - // Actually save - super.doSave(monitor); - - // If the target/minSdkVersion has changed, clear all lint warnings (since many - // of them are tied to the min/target sdk levels), in order to avoid showing stale - // results - try { - if (info != null) { - int newMinSdkVersion = info.getMinSdkVersion(); - int newTargetSdkVersion = info.getTargetSdkVersion(); - if (newMinSdkVersion != prevMinSdkVersion - || newTargetSdkVersion != prevTargetSdkVersion) { - assert project != null; - EclipseLintClient.clearMarkers(project); - } - } - } catch (Throwable t) { - AdtPlugin.log(t, null); - } - } - - /** - * Creates the various form pages. - */ - @Override - protected void createFormPages() { - try { - addPage(mOverviewPage = new OverviewPage(this)); - addPage(mAppPage = new ApplicationPage(this)); - addPage(mPermissionPage = new PermissionPage(this)); - addPage(mInstrumentationPage = new InstrumentationPage(this)); - } catch (PartInitException e) { - AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$ - } - } - - /* (non-java doc) - * Change the tab/title name to include the project name. - */ - @Override - protected void setInput(IEditorInput input) { - super.setInput(input); - IFile inputFile = getInputFile(); - if (inputFile != null) { - startMonitoringMarkers(); - setPartName(String.format("%1$s Manifest", inputFile.getProject().getName())); - } - } - - /** - * Processes the new XML Model, which XML root node is given. - * - * @param xml_doc The XML document, if available, or null if none exists. - */ - @Override - protected void xmlModelChanged(Document xml_doc) { - // create the ui root node on demand. - initUiRootNode(false /*force*/); - - loadFromXml(xml_doc); - } - - private void loadFromXml(Document xmlDoc) { - mUiManifestNode.setXmlDocument(xmlDoc); - Node node = getManifestXmlNode(xmlDoc); - - if (node != null) { - // Refresh the manifest UI node and all its descendants - mUiManifestNode.loadFromXmlNode(node); - } - } - - private Node getManifestXmlNode(Document xmlDoc) { - if (xmlDoc != null) { - ElementDescriptor manifestDesc = mUiManifestNode.getDescriptor(); - String manifestXmlName = manifestDesc == null ? null : manifestDesc.getXmlName(); - assert manifestXmlName != null; - - if (manifestXmlName != null) { - Node node = xmlDoc.getDocumentElement(); - if (node != null && manifestXmlName.equals(node.getNodeName())) { - return node; - } - - for (node = xmlDoc.getFirstChild(); - node != null; - node = node.getNextSibling()) { - if (node.getNodeType() == Node.ELEMENT_NODE && - manifestXmlName.equals(node.getNodeName())) { - return node; - } - } - } - } - - return null; - } - - private void onDescriptorsChanged() { - IStructuredModel model = getModelForRead(); - if (model != null) { - try { - Node node = getManifestXmlNode(getXmlDocument(model)); - mUiManifestNode.reloadFromXmlNode(node); - } finally { - model.releaseFromRead(); - } - } - - if (mOverviewPage != null) { - mOverviewPage.refreshUiApplicationNode(); - } - - if (mAppPage != null) { - mAppPage.refreshUiApplicationNode(); - } - - if (mPermissionPage != null) { - mPermissionPage.refreshUiNode(); - } - - if (mInstrumentationPage != null) { - mInstrumentationPage.refreshUiNode(); - } - } - - /** - * Reads and processes the current markers and adds a listener for marker changes. - */ - private void startMonitoringMarkers() { - final IFile inputFile = getInputFile(); - if (inputFile != null) { - updateFromExistingMarkers(inputFile); - - mMarkerMonitor = new IFileListener() { - @Override - public void fileChanged(@NonNull IFile file, @NonNull IMarkerDelta[] markerDeltas, - int kind, @Nullable String extension, int flags, boolean isAndroidProject) { - if (isAndroidProject && file.equals(inputFile)) { - processMarkerChanges(markerDeltas); - } - } - }; - - GlobalProjectMonitor.getMonitor().addFileListener( - mMarkerMonitor, IResourceDelta.CHANGED); - } - } - - /** - * Processes the markers of the specified {@link IFile} and updates the error status of - * {@link UiElementNode}s and {@link UiAttributeNode}s. - * @param inputFile the file being edited. - */ - private void updateFromExistingMarkers(IFile inputFile) { - try { - // get the markers for the file - IMarker[] markers = inputFile.findMarkers( - AdtConstants.MARKER_ANDROID, true, IResource.DEPTH_ZERO); - - AndroidManifestDescriptors desc = getManifestDescriptors(); - if (desc != null) { - ElementDescriptor appElement = desc.getApplicationElement(); - - if (appElement != null && mUiManifestNode != null) { - UiElementNode appUiNode = mUiManifestNode.findUiChildNode( - appElement.getXmlName()); - List<UiElementNode> children = appUiNode.getUiChildren(); - - for (IMarker marker : markers) { - processMarker(marker, children, IResourceDelta.ADDED); - } - } - } - - } catch (CoreException e) { - // findMarkers can throw an exception, in which case, we'll do nothing. - } - } - - /** - * Processes a {@link IMarker} change. - * @param markerDeltas the list of {@link IMarkerDelta} - */ - private void processMarkerChanges(IMarkerDelta[] markerDeltas) { - AndroidManifestDescriptors descriptors = getManifestDescriptors(); - if (descriptors != null && descriptors.getApplicationElement() != null) { - UiElementNode app_ui_node = mUiManifestNode.findUiChildNode( - descriptors.getApplicationElement().getXmlName()); - List<UiElementNode> children = app_ui_node.getUiChildren(); - - for (IMarkerDelta markerDelta : markerDeltas) { - processMarker(markerDelta.getMarker(), children, markerDelta.getKind()); - } - } - } - - /** - * Processes a new/old/updated marker. - * @param marker The marker being added/removed/changed - * @param nodeList the list of activity/service/provider/receiver nodes. - * @param kind the change kind. Can be {@link IResourceDelta#ADDED}, - * {@link IResourceDelta#REMOVED}, or {@link IResourceDelta#CHANGED} - */ - private void processMarker(IMarker marker, List<UiElementNode> nodeList, int kind) { - // get the data from the marker - String nodeType = marker.getAttribute(AdtConstants.MARKER_ATTR_TYPE, EMPTY); - if (nodeType == EMPTY) { - return; - } - - String className = marker.getAttribute(AdtConstants.MARKER_ATTR_CLASS, EMPTY); - if (className == EMPTY) { - return; - } - - for (UiElementNode ui_node : nodeList) { - if (ui_node.getDescriptor().getXmlName().equals(nodeType)) { - for (UiAttributeNode attr : ui_node.getAllUiAttributes()) { - if (attr.getDescriptor().getXmlLocalName().equals( - AndroidManifestDescriptors.ANDROID_NAME_ATTR)) { - if (attr.getCurrentValue().equals(className)) { - if (kind == IResourceDelta.REMOVED) { - attr.setHasError(false); - } else { - attr.setHasError(true); - } - return; - } - } - } - } - } - } - - /** - * Creates the initial UI Root Node, including the known mandatory elements. - * @param force if true, a new UiManifestNode is recreated even if it already exists. - */ - @Override - protected void initUiRootNode(boolean force) { - // The manifest UI node is always created, even if there's no corresponding XML node. - if (mUiManifestNode != null && force == false) { - return; - } - - AndroidManifestDescriptors manifestDescriptor = getManifestDescriptors(); - - if (manifestDescriptor != null) { - ElementDescriptor manifestElement = manifestDescriptor.getManifestElement(); - mUiManifestNode = manifestElement.createUiNode(); - mUiManifestNode.setEditor(this); - - // Similarly, always create the /manifest/uses-sdk followed by /manifest/application - // (order of the elements now matters) - ElementDescriptor element = manifestDescriptor.getUsesSdkElement(); - boolean present = false; - for (UiElementNode ui_node : mUiManifestNode.getUiChildren()) { - if (ui_node.getDescriptor() == element) { - present = true; - break; - } - } - if (!present) { - mUiManifestNode.appendNewUiChild(element); - } - - element = manifestDescriptor.getApplicationElement(); - present = false; - for (UiElementNode ui_node : mUiManifestNode.getUiChildren()) { - if (ui_node.getDescriptor() == element) { - present = true; - break; - } - } - if (!present) { - mUiManifestNode.appendNewUiChild(element); - } - - onDescriptorsChanged(); - } else { - // create a dummy descriptor/uinode until we have real descriptors - ElementDescriptor desc = new ElementDescriptor("manifest", //$NON-NLS-1$ - "temporary descriptors due to missing decriptors", //$NON-NLS-1$ - null /*tooltip*/, null /*sdk_url*/, null /*attributes*/, - null /*children*/, false /*mandatory*/); - mUiManifestNode = desc.createUiNode(); - mUiManifestNode.setEditor(this); - } - } - - /** - * Adds the given set of permissions into the manifest file in the suitable - * location - * - * @param permissions permission fqcn's to be added - * @param show if true, show one or more of the newly added permissions - */ - public void addPermissions(@NonNull final List<String> permissions, final boolean show) { - wrapUndoEditXmlModel("Add permissions", new Runnable() { - @Override - public void run() { - // Ensure that the model is current: - initUiRootNode(true /*force*/); - UiElementNode root = getUiRootNode(); - - ElementDescriptor descriptor = getManifestDescriptors().getUsesPermissionElement(); - boolean shown = false; - for (String permission : permissions) { - // Find the first permission which sorts alphabetically laster than - // this permission (or the last permission, if none are after in the alphabet) - // and insert it there - int lastPermissionIndex = -1; - int nextPermissionIndex = -1; - int index = 0; - for (UiElementNode sibling : root.getUiChildren()) { - Node node = sibling.getXmlNode(); - if (node.getNodeName().equals(USES_PERMISSION)) { - lastPermissionIndex = index; - String name = ((Element) node).getAttributeNS(ANDROID_URI, ATTR_NAME); - if (permission.compareTo(name) < 0) { - nextPermissionIndex = index; - break; - } - } else if (node.getNodeName().equals("application")) { //$NON-NLS-1$ - // permissions should come before the application element - nextPermissionIndex = index; - break; - } - index++; - } - - if (nextPermissionIndex != -1) { - index = nextPermissionIndex; - } else if (lastPermissionIndex != -1) { - index = lastPermissionIndex + 1; - } else { - index = root.getUiChildren().size(); - } - UiElementNode usesPermission = root.insertNewUiChild(index, descriptor); - usesPermission.setAttributeValue(ATTR_NAME, ANDROID_URI, permission, - true /*override*/); - Node node = usesPermission.createXmlNode(); - if (show && !shown) { - shown = true; - if (node instanceof IndexedRegion && getInputFile() != null) { - IndexedRegion indexedRegion = (IndexedRegion) node; - IRegion region = new Region(indexedRegion.getStartOffset(), - indexedRegion.getEndOffset() - indexedRegion.getStartOffset()); - try { - AdtPlugin.openFile(getInputFile(), region, true /*show*/); - } catch (PartInitException e) { - AdtPlugin.log(e, null); - } - } else { - show(node); - } - } - } - } - }); - } - - /** - * Removes the permissions from the manifest editor - * - * @param permissions the permission fqcn's to be removed - */ - public void removePermissions(@NonNull final Collection<String> permissions) { - wrapUndoEditXmlModel("Remove permissions", new Runnable() { - @Override - public void run() { - // Ensure that the model is current: - initUiRootNode(true /*force*/); - UiElementNode root = getUiRootNode(); - - for (String permission : permissions) { - for (UiElementNode sibling : root.getUiChildren()) { - Node node = sibling.getXmlNode(); - if (node.getNodeName().equals(USES_PERMISSION)) { - String name = ((Element) node).getAttributeNS(ANDROID_URI, ATTR_NAME); - if (name.equals(permission)) { - sibling.deleteXmlNode(); - break; - } - } - } - } - } - }); - } -} |