1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.editors.resources; 18 19 import com.android.ide.eclipse.adt.AdtConstants; 20 import com.android.ide.eclipse.adt.AdtPlugin; 21 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; 22 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; 23 import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors; 24 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; 25 import com.android.sdklib.xml.AndroidXPathFactory; 26 27 import org.eclipse.core.resources.IFile; 28 import org.eclipse.core.runtime.IStatus; 29 import org.eclipse.ui.IEditorInput; 30 import org.eclipse.ui.IEditorPart; 31 import org.eclipse.ui.PartInitException; 32 import org.eclipse.ui.part.FileEditorInput; 33 import org.w3c.dom.Document; 34 import org.w3c.dom.Node; 35 36 import javax.xml.xpath.XPath; 37 import javax.xml.xpath.XPathConstants; 38 import javax.xml.xpath.XPathExpressionException; 39 40 /** 41 * Multi-page form editor for /res/values XML files. 42 */ 43 public class ResourcesEditor extends AndroidXmlEditor { 44 45 public static final String ID = AdtConstants.EDITORS_NAMESPACE + ".resources.ResourcesEditor"; //$NON-NLS-1$ 46 47 /** Root node of the UI element hierarchy */ 48 private UiElementNode mUiResourcesNode; 49 50 51 /** 52 * Creates the form editor for resources XML files. 53 */ 54 public ResourcesEditor() { 55 super(); 56 } 57 58 /** 59 * Returns the root node of the UI element hierarchy, which 60 * here is the "resources" node. 61 */ 62 @Override 63 public UiElementNode getUiRootNode() { 64 return mUiResourcesNode; 65 } 66 67 // ---- Base Class Overrides ---- 68 69 /** 70 * Returns whether the "save as" operation is supported by this editor. 71 * <p/> 72 * Save-As is a valid operation for the ManifestEditor since it acts on a 73 * single source file. 74 * 75 * @see IEditorPart 76 */ 77 @Override 78 public boolean isSaveAsAllowed() { 79 return true; 80 } 81 82 /** 83 * Create the various form pages. 84 */ 85 @Override 86 protected void createFormPages() { 87 try { 88 addPage(new ResourcesTreePage(this)); 89 } catch (PartInitException e) { 90 AdtPlugin.log(IStatus.ERROR, "Error creating nested page"); //$NON-NLS-1$ 91 AdtPlugin.getDefault().getLog().log(e.getStatus()); 92 } 93 } 94 95 /* (non-java doc) 96 * Change the tab/title name to include the project name. 97 */ 98 @Override 99 protected void setInput(IEditorInput input) { 100 super.setInput(input); 101 if (input instanceof FileEditorInput) { 102 FileEditorInput fileInput = (FileEditorInput) input; 103 IFile file = fileInput.getFile(); 104 setPartName(String.format("%1$s", 105 file.getName())); 106 } 107 } 108 109 /** 110 * Processes the new XML Model, which XML root node is given. 111 * 112 * @param xml_doc The XML document, if available, or null if none exists. 113 */ 114 @Override 115 protected void xmlModelChanged(Document xml_doc) { 116 // init the ui root on demand 117 initUiRootNode(false /*force*/); 118 119 mUiResourcesNode.setXmlDocument(xml_doc); 120 if (xml_doc != null) { 121 ElementDescriptor resources_desc = 122 ResourcesDescriptors.getInstance().getElementDescriptor(); 123 try { 124 XPath xpath = AndroidXPathFactory.newXPath(); 125 Node node = (Node) xpath.evaluate("/" + resources_desc.getXmlName(), //$NON-NLS-1$ 126 xml_doc, 127 XPathConstants.NODE); 128 // Node can be null _or_ it must be the element we searched for. 129 assert node == null || node.getNodeName().equals(resources_desc.getXmlName()); 130 131 // Refresh the manifest UI node and all its descendants 132 mUiResourcesNode.loadFromXmlNode(node); 133 } catch (XPathExpressionException e) { 134 AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$ 135 resources_desc.getXmlName()); 136 } 137 } 138 139 super.xmlModelChanged(xml_doc); 140 } 141 142 /** 143 * Creates the initial UI Root Node, including the known mandatory elements. 144 * @param force if true, a new UiRootNode is recreated even if it already exists. 145 */ 146 @Override 147 protected void initUiRootNode(boolean force) { 148 // The manifest UI node is always created, even if there's no corresponding XML node. 149 if (mUiResourcesNode == null || force) { 150 ElementDescriptor resources_desc = 151 ResourcesDescriptors.getInstance().getElementDescriptor(); 152 mUiResourcesNode = resources_desc.createUiNode(); 153 mUiResourcesNode.setEditor(this); 154 155 onDescriptorsChanged(); 156 } 157 } 158 159 // ---- Local Methods ---- 160 161 private void onDescriptorsChanged() { 162 // nothing to be done, as the descriptor are static for now. 163 // FIXME Update when the descriptors are not static 164 } 165 } 166