Home | History | Annotate | Download | only in values
      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.values;
     18 
     19 import com.android.annotations.NonNull;
     20 import com.android.annotations.Nullable;
     21 import com.android.ide.eclipse.adt.AdtConstants;
     22 import com.android.ide.eclipse.adt.AdtPlugin;
     23 import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlDelegate;
     24 import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
     25 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
     26 import com.android.ide.eclipse.adt.internal.editors.values.descriptors.ValuesDescriptors;
     27 import com.android.resources.ResourceFolderType;
     28 import com.android.xml.AndroidXPathFactory;
     29 
     30 import org.eclipse.core.runtime.IStatus;
     31 import org.eclipse.ui.PartInitException;
     32 import org.w3c.dom.Document;
     33 import org.w3c.dom.Node;
     34 
     35 import javax.xml.xpath.XPath;
     36 import javax.xml.xpath.XPathConstants;
     37 import javax.xml.xpath.XPathExpressionException;
     38 
     39 /**
     40  * Multi-page form editor for /res/values XML files.
     41  */
     42 public class ValuesEditorDelegate extends CommonXmlDelegate {
     43 
     44     public static class Creator implements IDelegateCreator {
     45         @Override
     46         @SuppressWarnings("unchecked")
     47         public ValuesEditorDelegate createForFile(
     48                 @NonNull CommonXmlEditor delegator,
     49                 @Nullable ResourceFolderType type) {
     50             if (ResourceFolderType.VALUES == type) {
     51                 return new ValuesEditorDelegate(delegator);
     52             }
     53 
     54             return null;
     55         }
     56     }
     57 
     58     /**
     59      * Old standalone-editor ID.
     60      * Use {@link CommonXmlEditor#ID} instead.
     61      */
     62     public static final String LEGACY_EDITOR_ID =
     63         AdtConstants.EDITORS_NAMESPACE + ".resources.ResourcesEditor"; //$NON-NLS-1$
     64 
     65 
     66     /**
     67      * Creates the form editor for resources XML files.
     68      */
     69     private ValuesEditorDelegate(CommonXmlEditor editor) {
     70         super(editor, new ValuesContentAssist());
     71         editor.addDefaultTargetListener();
     72     }
     73 
     74     // ---- Base Class Overrides ----
     75 
     76     /**
     77      * Create the various form pages.
     78      */
     79     @Override
     80     public void delegateCreateFormPages() {
     81         try {
     82             getEditor().addPage(new ValuesTreePage(getEditor()));
     83         } catch (PartInitException e) {
     84             AdtPlugin.log(IStatus.ERROR, "Error creating nested page"); //$NON-NLS-1$
     85             AdtPlugin.getDefault().getLog().log(e.getStatus());
     86         }
     87      }
     88 
     89     /**
     90      * Processes the new XML Model, which XML root node is given.
     91      *
     92      * @param xml_doc The XML document, if available, or null if none exists.
     93      */
     94     @Override
     95     public void delegateXmlModelChanged(Document xml_doc) {
     96         // init the ui root on demand
     97         delegateInitUiRootNode(false /*force*/);
     98 
     99         getUiRootNode().setXmlDocument(xml_doc);
    100         if (xml_doc != null) {
    101             ElementDescriptor resources_desc =
    102                     ValuesDescriptors.getInstance().getElementDescriptor();
    103             try {
    104                 XPath xpath = AndroidXPathFactory.newXPath();
    105                 Node node = (Node) xpath.evaluate("/" + resources_desc.getXmlName(),  //$NON-NLS-1$
    106                         xml_doc,
    107                         XPathConstants.NODE);
    108                 // Node can be null _or_ it must be the element we searched for.
    109                 assert node == null || node.getNodeName().equals(resources_desc.getXmlName());
    110 
    111                 // Refresh the manifest UI node and all its descendants
    112                 getUiRootNode().loadFromXmlNode(node);
    113             } catch (XPathExpressionException e) {
    114                 AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$
    115                         resources_desc.getXmlName());
    116             }
    117         }
    118     }
    119 
    120     /**
    121      * Creates the initial UI Root Node, including the known mandatory elements.
    122      * @param force if true, a new UiRootNode is recreated even if it already exists.
    123      */
    124     @Override
    125     public void delegateInitUiRootNode(boolean force) {
    126         // The manifest UI node is always created, even if there's no corresponding XML node.
    127         if (getUiRootNode() == null || force) {
    128             ElementDescriptor resources_desc =
    129                     ValuesDescriptors.getInstance().getElementDescriptor();
    130             setUiRootNode(resources_desc.createUiNode());
    131             getUiRootNode().setEditor(getEditor());
    132 
    133             onDescriptorsChanged();
    134         }
    135     }
    136 
    137     // ---- Local methods ----
    138 
    139     private void onDescriptorsChanged() {
    140         // nothing to be done, as the descriptor are static for now.
    141         // FIXME Update when the descriptors are not static
    142     }
    143 }
    144 
    145