Home | History | Annotate | Download | only in resources
      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