1 /* 2 * Copyright (C) 2009 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.sdk; 18 19 import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; 20 import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; 21 import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; 22 import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; 23 import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationStateQualifier; 24 import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; 25 import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; 26 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; 27 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; 28 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier; 29 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier; 30 import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier; 31 import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier; 32 import com.android.sdklib.resources.Density; 33 import com.android.sdklib.resources.Keyboard; 34 import com.android.sdklib.resources.KeyboardState; 35 import com.android.sdklib.resources.Navigation; 36 import com.android.sdklib.resources.NavigationState; 37 import com.android.sdklib.resources.ScreenOrientation; 38 import com.android.sdklib.resources.ScreenRatio; 39 import com.android.sdklib.resources.ScreenSize; 40 import com.android.sdklib.resources.TouchScreen; 41 42 import org.xml.sax.Attributes; 43 import org.xml.sax.SAXException; 44 import org.xml.sax.helpers.DefaultHandler; 45 46 import java.util.ArrayList; 47 import java.util.List; 48 49 /** 50 * {@link DefaultHandler} implementation to parse Layout Device XML file. 51 * @see LayoutDevicesXsd 52 * @see Layout-configs.xsd 53 */ 54 class LayoutDeviceHandler extends DefaultHandler { 55 /* 56 * The handler does most of the work in startElement and endElement. 57 * In startElement, it'll create DeviceConfiguration on <device>, as well as 58 * FolderConfiguration instances on <default> and <config>. 59 * Those objects are then filled as new nodes are discovered. 60 * 61 * For the qualifier values, the qualifier is created and added to the current config 62 * on the endElement, by using the content found in characters(). 63 */ 64 65 private List<LayoutDevice> mDevices = new ArrayList<LayoutDevice>(); 66 67 private LayoutDevice mCurrentDevice; 68 private FolderConfiguration mDefaultConfig; 69 private FolderConfiguration mCurrentConfig; 70 private final StringBuilder mStringAccumulator = new StringBuilder(); 71 72 private String mSize1, mSize2; 73 getDevices()74 public List<LayoutDevice> getDevices() { 75 return mDevices; 76 } 77 78 @Override startElement(String uri, String localName, String name, Attributes attributes)79 public void startElement(String uri, String localName, String name, Attributes attributes) 80 throws SAXException { 81 if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) { 82 // get the deviceName, will not be null since we validated the XML. 83 String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME); 84 85 // create a device and add it to the list 86 mCurrentDevice = new LayoutDevice(deviceName); 87 mDevices.add(mCurrentDevice); 88 } else if (LayoutDevicesXsd.NODE_DEFAULT.equals(localName)) { 89 // create a new default config 90 mDefaultConfig = mCurrentConfig = new FolderConfiguration(); 91 } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) { 92 // create a new config 93 mCurrentConfig = new FolderConfiguration(); 94 95 // init with default config if applicable 96 if (mDefaultConfig != null) { 97 mCurrentConfig.set(mDefaultConfig); 98 } 99 100 // get the name of the config 101 String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME); 102 103 // give it to the current device. 104 mCurrentDevice.addConfig(deviceName, mCurrentConfig); 105 } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) { 106 mSize1 = mSize2 = null; 107 } 108 109 mStringAccumulator.setLength(0); 110 } 111 112 @Override characters(char[] ch, int start, int length)113 public void characters(char[] ch, int start, int length) throws SAXException { 114 mStringAccumulator.append(ch, start, length); 115 } 116 117 @Override endElement(String uri, String localName, String name)118 public void endElement(String uri, String localName, String name) throws SAXException { 119 if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) { 120 mCurrentDevice = null; 121 mDefaultConfig = null; 122 } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) { 123 mCurrentConfig = null; 124 } else if (LayoutDevicesXsd.NODE_COUNTRY_CODE.equals(localName)) { 125 CountryCodeQualifier ccq = new CountryCodeQualifier( 126 Integer.parseInt(mStringAccumulator.toString())); 127 mCurrentConfig.setCountryCodeQualifier(ccq); 128 } else if (LayoutDevicesXsd.NODE_NETWORK_CODE.equals(localName)) { 129 NetworkCodeQualifier ncq = new NetworkCodeQualifier( 130 Integer.parseInt(mStringAccumulator.toString())); 131 mCurrentConfig.setNetworkCodeQualifier(ncq); 132 } else if (LayoutDevicesXsd.NODE_SCREEN_SIZE.equals(localName)) { 133 ScreenSizeQualifier ssq = new ScreenSizeQualifier( 134 ScreenSize.getEnum(mStringAccumulator.toString())); 135 mCurrentConfig.setScreenSizeQualifier(ssq); 136 } else if (LayoutDevicesXsd.NODE_SCREEN_RATIO.equals(localName)) { 137 ScreenRatioQualifier srq = new ScreenRatioQualifier( 138 ScreenRatio.getEnum(mStringAccumulator.toString())); 139 mCurrentConfig.setScreenRatioQualifier(srq); 140 } else if (LayoutDevicesXsd.NODE_SCREEN_ORIENTATION.equals(localName)) { 141 ScreenOrientationQualifier soq = new ScreenOrientationQualifier( 142 ScreenOrientation.getEnum(mStringAccumulator.toString())); 143 mCurrentConfig.setScreenOrientationQualifier(soq); 144 } else if (LayoutDevicesXsd.NODE_PIXEL_DENSITY.equals(localName)) { 145 PixelDensityQualifier pdq = new PixelDensityQualifier( 146 Density.getEnum(mStringAccumulator.toString())); 147 mCurrentConfig.setPixelDensityQualifier(pdq); 148 } else if (LayoutDevicesXsd.NODE_TOUCH_TYPE.equals(localName)) { 149 TouchScreenQualifier tsq = new TouchScreenQualifier( 150 TouchScreen.getEnum(mStringAccumulator.toString())); 151 mCurrentConfig.setTouchTypeQualifier(tsq); 152 } else if (LayoutDevicesXsd.NODE_KEYBOARD_STATE.equals(localName)) { 153 KeyboardStateQualifier ksq = new KeyboardStateQualifier( 154 KeyboardState.getEnum(mStringAccumulator.toString())); 155 mCurrentConfig.setKeyboardStateQualifier(ksq); 156 } else if (LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) { 157 TextInputMethodQualifier timq = new TextInputMethodQualifier( 158 Keyboard.getEnum(mStringAccumulator.toString())); 159 mCurrentConfig.setTextInputMethodQualifier(timq); 160 } else if (LayoutDevicesXsd.NODE_NAV_STATE.equals(localName)) { 161 NavigationStateQualifier nsq = new NavigationStateQualifier( 162 NavigationState.getEnum(mStringAccumulator.toString())); 163 mCurrentConfig.setNavigationStateQualifier(nsq); 164 } else if (LayoutDevicesXsd.NODE_NAV_METHOD.equals(localName)) { 165 NavigationMethodQualifier nmq = new NavigationMethodQualifier( 166 Navigation.getEnum(mStringAccumulator.toString())); 167 mCurrentConfig.setNavigationMethodQualifier(nmq); 168 } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) { 169 ScreenDimensionQualifier qual = ScreenDimensionQualifier.getQualifier(mSize1, mSize2); 170 if (qual != null) { 171 mCurrentConfig.setScreenDimensionQualifier(qual); 172 } 173 } else if (LayoutDevicesXsd.NODE_XDPI.equals(localName)) { 174 mCurrentDevice.setXDpi(Float.parseFloat(mStringAccumulator.toString())); 175 } else if (LayoutDevicesXsd.NODE_YDPI.equals(localName)) { 176 mCurrentDevice.setYDpi(Float.parseFloat(mStringAccumulator.toString())); 177 } else if (LayoutDevicesXsd.NODE_SIZE.equals(localName)) { 178 if (mSize1 == null) { 179 mSize1 = mStringAccumulator.toString(); 180 } else if (mSize2 == null) { 181 mSize2 = mStringAccumulator.toString(); 182 } 183 } 184 } 185 } 186