Home | History | Annotate | Download | only in formatting
      1 /*
      2  * Copyright (C) 2011 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 package com.android.ide.eclipse.adt.internal.editors.formatting;
     17 
     18 import com.android.annotations.NonNull;
     19 import com.android.annotations.Nullable;
     20 import com.android.annotations.VisibleForTesting;
     21 import com.android.ide.common.xml.XmlFormatPreferences;
     22 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
     23 import com.android.ide.common.xml.XmlAttributeSortOrder;
     24 
     25 import org.eclipse.core.runtime.Preferences;
     26 import org.eclipse.jface.preference.IPreferenceStore;
     27 import org.eclipse.ui.internal.editors.text.EditorsPlugin;
     28 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
     29 import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
     30 import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
     31 import org.eclipse.wst.xml.core.internal.preferences.XMLCorePreferenceNames;
     32 import org.w3c.dom.Attr;
     33 
     34 import java.util.Comparator;
     35 
     36 /**
     37  * Formatting preferences used by the Android XML formatter.
     38  */
     39 public class EclipseXmlFormatPreferences extends XmlFormatPreferences {
     40     @VisibleForTesting
     41     protected EclipseXmlFormatPreferences() {
     42     }
     43 
     44     /**
     45      * Creates a new {@link EclipseXmlFormatPreferences} based on the current settings
     46      * in {@link AdtPrefs}
     47      *
     48      * @return an {@link EclipseXmlFormatPreferences} object
     49      */
     50     @NonNull
     51     public static EclipseXmlFormatPreferences create() {
     52         EclipseXmlFormatPreferences p = new EclipseXmlFormatPreferences();
     53         AdtPrefs prefs = AdtPrefs.getPrefs();
     54 
     55         p.useEclipseIndent = prefs.isUseEclipseIndent();
     56         p.removeEmptyLines = prefs.isRemoveEmptyLines();
     57         p.oneAttributeOnFirstLine = prefs.isOneAttributeOnFirstLine();
     58         p.sortAttributes = prefs.getAttributeSort();
     59         p.spaceBeforeClose = prefs.isSpaceBeforeClose();
     60 
     61         return p;
     62     }
     63 
     64     @Override
     65     @Nullable
     66     public Comparator<Attr> getAttributeComparator() {
     67         // Can't just skip sorting; the attribute table moves attributes out of order
     68         // due to hashing, so sort by node positions
     69         if (sortAttributes == XmlAttributeSortOrder.NO_SORTING) {
     70             return EXISTING_ORDER_COMPARATOR;
     71         }
     72         return sortAttributes.getAttributeComparator();
     73     }
     74 
     75     private static final Comparator<Attr> EXISTING_ORDER_COMPARATOR = new Comparator<Attr>() {
     76         @Override
     77         public int compare(Attr attr1, Attr attr2) {
     78             IndexedRegion region1 = (IndexedRegion) attr1;
     79             IndexedRegion region2 = (IndexedRegion) attr2;
     80 
     81             return region1.getStartOffset() - region2.getStartOffset();
     82         }
     83     };
     84 
     85     // The XML module settings do not have a public API. We should replace this with JDT
     86     // settings anyway since that's more likely what users have configured and want applied
     87     // to their XML files
     88 
     89     /**
     90      * Returns the string to use to indent one indentation level
     91      *
     92      * @return the string used to indent one indentation level
     93      */
     94     @Override
     95     @SuppressWarnings({
     96             "restriction", "deprecation"
     97     })
     98     public String getOneIndentUnit() {
     99         if (useEclipseIndent) {
    100             // Look up Eclipse indent preferences
    101             // TODO: Use the JDT preferences instead, which make more sense
    102             Preferences preferences = XMLCorePlugin.getDefault().getPluginPreferences();
    103             int indentationWidth = preferences.getInt(XMLCorePreferenceNames.INDENTATION_SIZE);
    104             String indentCharPref = preferences.getString(XMLCorePreferenceNames.INDENTATION_CHAR);
    105             boolean useSpaces = XMLCorePreferenceNames.SPACE.equals(indentCharPref);
    106 
    107             StringBuilder indentString = new StringBuilder();
    108             for (int j = 0; j < indentationWidth; j++) {
    109                 if (useSpaces) {
    110                     indentString.append(' ');
    111                 } else {
    112                     indentString.append('\t');
    113                 }
    114             }
    115             mOneIndentUnit = indentString.toString();
    116         }
    117 
    118         return mOneIndentUnit;
    119     }
    120 
    121     /**
    122      * Returns the number of spaces used to display a single tab character
    123      *
    124      * @return the number of spaces used to display a single tab character
    125      */
    126     @Override
    127     @SuppressWarnings("restriction") // Editor settings
    128     public int getTabWidth() {
    129         if (mTabWidth == -1) {
    130             String key = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH;
    131             try {
    132                 IPreferenceStore prefs = EditorsPlugin.getDefault().getPreferenceStore();
    133                 mTabWidth = prefs.getInt(key);
    134             } catch (Throwable t) {
    135                 // Pass: We'll pick a suitable default instead below
    136             }
    137             if (mTabWidth <= 0) {
    138                 mTabWidth = 4;
    139             }
    140         }
    141 
    142         return mTabWidth;
    143     }
    144 }
    145