From af496633406c19192db960d822b51fa1f574fbf2 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Wed, 14 Oct 2009 17:57:30 -0700 Subject: [PATCH] Add save/load for the user-made Layout Devices. (do not merge) Also added support for mcc/mnc in the schema. --- .../configuration/ConfigurationComposite.java | 3 + .../configurations/CountryCodeQualifier.java | 13 +- .../configurations/NetworkCodeQualifier.java | 16 ++- .../ide/eclipse/adt/internal/sdk/LayoutDevice.java | 147 +++++++++++++++++++++ .../adt/internal/sdk/LayoutDeviceHandler.java | 52 +++++--- .../adt/internal/sdk/LayoutDeviceManager.java | 90 ++++++++++++- ...LayoutConfigsXsd.java => LayoutDevicesXsd.java} | 16 ++- .../android/ide/eclipse/adt/internal/sdk/Sdk.java | 2 +- .../sdk/{layout-configs.xsd => layout-devices.xsd} | 38 +++++- ...outConfisXsd.java => TestLayoutDevicesXsd.java} | 56 ++++---- .../ide/eclipse/adt/internal/sdk/config_sample.xml | 6 +- tools/scripts/devices.xml | 6 +- 12 files changed, 368 insertions(+), 77 deletions(-) rename tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/{LayoutConfigsXsd.java => LayoutDevicesXsd.java} (86%) rename tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/{layout-configs.xsd => layout-devices.xsd} (89%) rename tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/{TestLayoutConfisXsd.java => TestLayoutDevicesXsd.java} (81%) diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java index 8c37cc6b..b6f9a097 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java @@ -591,6 +591,9 @@ public class ConfigurationComposite extends Composite { ConfigManagerDialog dialog = new ConfigManagerDialog(getShell()); dialog.open(); + // save the user devices + Sdk.getCurrent().getLayoutDeviceManager().save(); + // reload the combo with the new content. loadDevices(); initUiWithDevices(); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java index f570bacd..97028e99 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java @@ -33,7 +33,7 @@ public final class CountryCodeQualifier extends ResourceQualifier { private final static Pattern sCountryCodePattern = Pattern.compile("^mcc(\\d{3})$");//$NON-NLS-1$ - private int mCode = DEFAULT_CODE; + private final int mCode; public static final String NAME = "Mobile Country Code"; @@ -56,8 +56,7 @@ public final class CountryCodeQualifier extends ResourceQualifier { return null; } - CountryCodeQualifier qualifier = new CountryCodeQualifier(); - qualifier.mCode = code; + CountryCodeQualifier qualifier = new CountryCodeQualifier(code); return qualifier; } @@ -77,6 +76,14 @@ public final class CountryCodeQualifier extends ResourceQualifier { return ""; //$NON-NLS-1$ } + public CountryCodeQualifier() { + this(DEFAULT_CODE); + } + + public CountryCodeQualifier(int code) { + mCode = code; + } + public int getCode() { return mCode; } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java index 32bd6672..655fe4e3 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java @@ -33,7 +33,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { private final static Pattern sNetworkCodePattern = Pattern.compile("^mnc(\\d{1,3})$"); //$NON-NLS-1$ - private int mCode = DEFAULT_CODE; + private final int mCode; public final static String NAME = "Mobile Network Code"; @@ -56,8 +56,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { return null; } - NetworkCodeQualifier qualifier = new NetworkCodeQualifier(); - qualifier.mCode = code; + NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code); return qualifier; } @@ -77,6 +76,14 @@ public final class NetworkCodeQualifier extends ResourceQualifier { return ""; //$NON-NLS-1$ } + public NetworkCodeQualifier() { + this(DEFAULT_CODE); + } + + public NetworkCodeQualifier(int code) { + mCode = code; + } + public int getCode() { return mCode; } @@ -115,8 +122,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { return false; } - NetworkCodeQualifier qualifier = new NetworkCodeQualifier(); - qualifier.mCode = code; + NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code); config.setNetworkCodeQualifier(qualifier); return true; } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java index 89cac5ba..9e80103d 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java @@ -16,11 +16,26 @@ package com.android.ide.eclipse.adt.internal.sdk; +import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; +import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; /** * Class representing a layout device. @@ -53,6 +68,138 @@ public class LayoutDevice { mName = name; } + /** + * Saves the Layout Device into a document under a given node + * @param doc the document. + * @param parentNode the parent node. + */ + void saveTo(Document doc, Element parentNode) { + // create the device node + Element deviceNode = createNode(doc, parentNode, LayoutDevicesXsd.NODE_DEVICE); + + // create the name attribute (no namespace on this one). + deviceNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, mName); + + // create a default with the x/y dpi + Element defaultNode = createNode(doc, deviceNode, LayoutDevicesXsd.NODE_DEFAULT); + if (Float.isNaN(mXDpi) == false) { + Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_XDPI); + xdpiNode.setTextContent(Float.toString(mXDpi)); + } + if (Float.isNaN(mYDpi) == false) { + Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_YDPI); + xdpiNode.setTextContent(Float.toString(mYDpi)); + } + + // then save all the configs. + for (Entry entry : mEditMap.entrySet()) { + saveConfigTo(doc, deviceNode, entry.getKey(), entry.getValue()); + } + } + + /** + * Creates and returns a new NS-enabled node. + * @param doc the {@link Document} + * @param parentNode the parent node. The new node is appended to this one as a child. + * @param name the name of the node. + * @return the newly created node. + */ + private Element createNode(Document doc, Element parentNode, String name) { + Element newNode = doc.createElementNS( + LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, name); + newNode.setPrefix(doc.lookupPrefix(LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD)); + parentNode.appendChild(newNode); + + return newNode; + } + + /** + * Saves a {@link FolderConfiguration} in a {@link Document}. + * @param doc the Document in which to save + * @param parent the parent node + * @param configName the name of the config + * @param config the config to save + */ + private void saveConfigTo(Document doc, Element parent, String configName, + FolderConfiguration config) { + Element configNode = createNode(doc, parent, LayoutDevicesXsd.NODE_CONFIG); + + // create the name attribute (no namespace on this one). + configNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, configName); + + // now do the qualifiers + CountryCodeQualifier ccq = config.getCountryCodeQualifier(); + if (ccq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_COUNTRY_CODE); + node.setTextContent(Integer.toString(ccq.getCode())); + } + + NetworkCodeQualifier ncq = config.getNetworkCodeQualifier(); + if (ncq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NETWORK_CODE); + node.setTextContent(Integer.toString(ncq.getCode())); + } + + ScreenSizeQualifier ssq = config.getScreenSizeQualifier(); + if (ssq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_SIZE); + node.setTextContent(ssq.getFolderSegment(null)); + } + + ScreenRatioQualifier srq = config.getScreenRatioQualifier(); + if (srq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_RATIO); + node.setTextContent(srq.getFolderSegment(null)); + } + + ScreenOrientationQualifier soq = config.getScreenOrientationQualifier(); + if (soq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_ORIENTATION); + node.setTextContent(soq.getFolderSegment(null)); + } + + PixelDensityQualifier pdq = config.getPixelDensityQualifier(); + if (pdq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_PIXEL_DENSITY); + node.setTextContent(pdq.getFolderSegment(null)); + } + + TouchScreenQualifier ttq = config.getTouchTypeQualifier(); + if (ttq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TOUCH_TYPE); + node.setTextContent(ttq.getFolderSegment(null)); + } + + KeyboardStateQualifier ksq = config.getKeyboardStateQualifier(); + if (ksq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_KEYBOARD_STATE); + node.setTextContent(ksq.getFolderSegment(null)); + } + + TextInputMethodQualifier timq = config.getTextInputMethodQualifier(); + if (timq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD); + node.setTextContent(timq.getFolderSegment(null)); + } + + NavigationMethodQualifier nmq = config.getNavigationMethodQualifier(); + if (nmq != null) { + Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_METHOD); + node.setTextContent(nmq.getFolderSegment(null)); + } + + ScreenDimensionQualifier sdq = config.getScreenDimensionQualifier(); + if (sdq != null) { + Element sizeNode = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_DIMENSION); + + Element node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE); + node.setTextContent(Integer.toString(sdq.getValue1())); + + node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE); + node.setTextContent(Integer.toString(sdq.getValue2())); + } + } + void addConfig(String name, FolderConfiguration config) { mEditMap.put(name, config); _seal(); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java index bb9a13d0..7ad4e5d1 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceHandler.java @@ -16,9 +16,11 @@ package com.android.ide.eclipse.adt.internal.sdk; +import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier; +import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier; import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier; @@ -44,7 +46,7 @@ import java.util.List; /** * {@link DefaultHandler} implementation to parse Layout Device XML file. - * @see LayoutConfigsXsd + * @see LayoutDevicesXsd * @see Layout-configs.xsd */ class LayoutDeviceHandler extends DefaultHandler { @@ -74,17 +76,17 @@ class LayoutDeviceHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { - if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) { + if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) { // get the deviceName, will not be null since we validated the XML. - String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME); + String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME); // create a device and add it to the list mCurrentDevice = new LayoutDevice(deviceName); mDevices.add(mCurrentDevice); - } else if (LayoutConfigsXsd.NODE_DEFAULT.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_DEFAULT.equals(localName)) { // create a new default config mDefaultConfig = mCurrentConfig = new FolderConfiguration(); - } else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) { // create a new config mCurrentConfig = new FolderConfiguration(); @@ -94,11 +96,11 @@ class LayoutDeviceHandler extends DefaultHandler { } // get the name of the config - String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME); + String deviceName = attributes.getValue("", LayoutDevicesXsd.ATTR_NAME); // give it to the current device. mCurrentDevice.addConfig(deviceName, mCurrentConfig); - } else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) { mSize1 = mSize2 = null; } @@ -112,53 +114,61 @@ class LayoutDeviceHandler extends DefaultHandler { @Override public void endElement(String uri, String localName, String name) throws SAXException { - if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) { + if (LayoutDevicesXsd.NODE_DEVICE.equals(localName)) { mCurrentDevice = null; mDefaultConfig = null; - } else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_CONFIG.equals(localName)) { mCurrentConfig = null; - } else if (LayoutConfigsXsd.NODE_SCREEN_SIZE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_COUNTRY_CODE.equals(localName)) { + CountryCodeQualifier ccq = new CountryCodeQualifier( + Integer.parseInt(mStringAccumulator.toString())); + mCurrentConfig.setCountryCodeQualifier(ccq); + } else if (LayoutDevicesXsd.NODE_NETWORK_CODE.equals(localName)) { + NetworkCodeQualifier ncq = new NetworkCodeQualifier( + Integer.parseInt(mStringAccumulator.toString())); + mCurrentConfig.setNetworkCodeQualifier(ncq); + } else if (LayoutDevicesXsd.NODE_SCREEN_SIZE.equals(localName)) { ScreenSizeQualifier ssq = new ScreenSizeQualifier( ScreenSize.getEnum(mStringAccumulator.toString())); mCurrentConfig.setScreenSizeQualifier(ssq); - } else if (LayoutConfigsXsd.NODE_SCREEN_RATIO.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_RATIO.equals(localName)) { ScreenRatioQualifier srq = new ScreenRatioQualifier( ScreenRatio.getEnum(mStringAccumulator.toString())); mCurrentConfig.setScreenRatioQualifier(srq); - } else if (LayoutConfigsXsd.NODE_SCREEN_ORIENTATION.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_ORIENTATION.equals(localName)) { ScreenOrientationQualifier soq = new ScreenOrientationQualifier( ScreenOrientation.getEnum(mStringAccumulator.toString())); mCurrentConfig.setScreenOrientationQualifier(soq); - } else if (LayoutConfigsXsd.NODE_PIXEL_DENSITY.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_PIXEL_DENSITY.equals(localName)) { PixelDensityQualifier pdq = new PixelDensityQualifier( Density.getEnum(mStringAccumulator.toString())); mCurrentConfig.setPixelDensityQualifier(pdq); - } else if (LayoutConfigsXsd.NODE_TOUCH_TYPE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_TOUCH_TYPE.equals(localName)) { TouchScreenQualifier tsq = new TouchScreenQualifier( TouchScreenType.getEnum(mStringAccumulator.toString())); mCurrentConfig.setTouchTypeQualifier(tsq); - } else if (LayoutConfigsXsd.NODE_KEYBOARD_STATE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_KEYBOARD_STATE.equals(localName)) { KeyboardStateQualifier ksq = new KeyboardStateQualifier( KeyboardState.getEnum(mStringAccumulator.toString())); mCurrentConfig.setKeyboardStateQualifier(ksq); - } else if (LayoutConfigsXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) { TextInputMethodQualifier timq = new TextInputMethodQualifier( TextInputMethod.getEnum(mStringAccumulator.toString())); mCurrentConfig.setTextInputMethodQualifier(timq); - } else if (LayoutConfigsXsd.NODE_NAV_METHOD.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_NAV_METHOD.equals(localName)) { NavigationMethodQualifier nmq = new NavigationMethodQualifier( NavigationMethod.getEnum(mStringAccumulator.toString())); mCurrentConfig.setNavigationMethodQualifier(nmq); - } else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SCREEN_DIMENSION.equals(localName)) { ScreenDimensionQualifier qual = ScreenDimensionQualifier.getQualifier(mSize1, mSize2); if (qual != null) { mCurrentConfig.setScreenDimensionQualifier(qual); } - } else if (LayoutConfigsXsd.NODE_XDPI.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_XDPI.equals(localName)) { mCurrentDevice.setXDpi(Float.parseFloat(mStringAccumulator.toString())); - } else if (LayoutConfigsXsd.NODE_YDPI.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_YDPI.equals(localName)) { mCurrentDevice.setYDpi(Float.parseFloat(mStringAccumulator.toString())); - } else if (LayoutConfigsXsd.NODE_SIZE.equals(localName)) { + } else if (LayoutDevicesXsd.NODE_SIZE.equals(localName)) { if (mSize1 == null) { mSize1 = mStringAccumulator.toString(); } else if (mSize2 == null) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java index 03daf401..3b19f172 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDeviceManager.java @@ -18,8 +18,12 @@ package com.android.ide.eclipse.adt.internal.sdk; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration; +import com.android.prefs.AndroidLocation; +import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.SdkConstants; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -35,10 +39,17 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Result; import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Validator; @@ -232,11 +243,43 @@ public class LayoutDeviceManager { } } - void load(String sdkOsLocation) { + /** + * Saves the user-made {@link LayoutDevice}s to disk. + */ + public void save() { + try { + String userFolder = AndroidLocation.getFolder(); + File deviceXml = new File(userFolder, SdkConstants.FN_DEVICES_XML); + if (deviceXml.isDirectory() == false) { + write(deviceXml, mUserLayoutDevices); + } + } catch (AndroidLocationException e) { + // no user folder? simply don't save the user layout device. + // we could display the error, but it's likely something else did before, as + // nothing will work w/o it. + AdtPlugin.log(e, "Unable to find user directory"); + } + } + + /** + * Loads the default built-in and user created Layout Devices. + * @param sdkOsLocation location of the SDK. + */ + void loadDefaultAndUserDevices(String sdkOsLocation) { // load the default devices loadDefaultLayoutDevices(sdkOsLocation); // load the user devices; + try { + String userFolder = AndroidLocation.getFolder(); + File deviceXml = new File(userFolder, SdkConstants.FN_DEVICES_XML); + if (deviceXml.isFile()) { + parseLayoutDevices(deviceXml, mUserLayoutDevices); + } + } catch (AndroidLocationException e) { + // no user folder? simply don't load the user layout device + AdtPlugin.log(e, "Unable to find user directory"); + } } void parseAddOnLayoutDevice(File deviceXml) { @@ -251,6 +294,8 @@ public class LayoutDeviceManager { /** * Does the actual parsing of a devices.xml file. + * @param deviceXml the {@link File} to load/parse. This must be an existing file. + * @param list the list in which to write the parsed {@link LayoutDevice}. */ private void parseLayoutDevices(File deviceXml, List list) { // first we validate the XML @@ -259,7 +304,7 @@ public class LayoutDeviceManager { CaptureErrorHandler errorHandler = new CaptureErrorHandler(deviceXml.getAbsolutePath()); - Validator validator = LayoutConfigsXsd.getValidator(errorHandler); + Validator validator = LayoutDevicesXsd.getValidator(errorHandler); validator.validate(source); if (errorHandler.foundError() == false) { @@ -307,4 +352,45 @@ public class LayoutDeviceManager { mLayoutDevices = Collections.unmodifiableList(list); } + /** + * Writes the given {@link LayoutDevice}s into the given file. + * @param deviceXml the file to write. + * @param deviceList the LayoutDevice to write into the file. + */ + private void write(File deviceXml, List deviceList) { + try { + // create a new document + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + Document doc = docBuilder.newDocument(); + + // create a base node + Element baseNode = doc.createElementNS( + LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, + LayoutDevicesXsd.NODE_LAYOUT_DEVICES); + // create the prefix for the namespace + baseNode.setPrefix("d"); + doc.appendChild(baseNode); + + // fill it with the layout devices. + for (LayoutDevice device : deviceList) { + device.saveTo(doc, baseNode); + } + + // save the document to disk + // Prepare the DOM document for writing + Source source = new DOMSource(doc); + + // Prepare the output file + File file = new File(deviceXml.getAbsolutePath()); + Result result = new StreamResult(file); + + // Write the DOM document to the file + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform(source, result); + } catch (Exception e) { + AdtPlugin.log(e, "Failed to write %s", deviceXml.getAbsolutePath()); + } + } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java similarity index 86% rename from tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java rename to tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java index c75c15ec..67e97186 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevicesXsd.java @@ -31,14 +31,14 @@ import javax.xml.validation.Validator; /** * Public constants for the layout device description XML Schema. */ -public class LayoutConfigsXsd { +public class LayoutDevicesXsd { /** The XML namespace of the layout-configs XML. */ - public static final String NS_LAYOUT_CONFIG_XSD = - "http://schemas.android.com/sdk/android/layout-configs/1"; //$NON-NLS-1$ + public static final String NS_LAYOUT_DEVICE_XSD = + "http://schemas.android.com/sdk/android/layout-devices/1"; //$NON-NLS-1$ /** - * The "layout-configs" element is the root element of this schema. + * The "layout-devices" element is the root element of this schema. * * It must contain one or more "device" elements that each define the configurations * available for a given device. @@ -46,7 +46,7 @@ public class LayoutConfigsXsd { * These definitions are used in the Graphical Layout Editor in the * Android Development Tools (ADT) plugin for Eclipse. */ - public static final String NODE_LAYOUT_CONFIGS = "layout-configs"; //$NON-NLS-1$ + public static final String NODE_LAYOUT_DEVICES = "layout-devices"; //$NON-NLS-1$ /** * A device element must contain at most one "default" element followed @@ -76,6 +76,10 @@ public class LayoutConfigsXsd { public static final String NODE_CONFIG = "config"; //$NON-NLS-1$ + public static final String NODE_COUNTRY_CODE = "country-code"; //$NON-NLS-1$ + + public static final String NODE_NETWORK_CODE = "network-code"; //$NON-NLS-1$ + public static final String NODE_SCREEN_SIZE = "screen-size"; //$NON-NLS-1$ public static final String NODE_SCREEN_RATIO = "screen-ratio"; //$NON-NLS-1$ @@ -111,7 +115,7 @@ public class LayoutConfigsXsd { * Helper to get an input stream of the layout config XML schema. */ public static InputStream getXsdStream() { - return LayoutConfigsXsd.class.getResourceAsStream("layout-configs.xsd"); //$NON-NLS-1$ + return LayoutDevicesXsd.class.getResourceAsStream("layout-devices.xsd"); //$NON-NLS-1$ } /** Helper method that returns a {@link Validator} for our XSD */ diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java index 6a8bd5bf..45ff31f7 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java @@ -440,7 +440,7 @@ public class Sdk implements IProjectListener { SdkConstants.OS_SDK_DOCS_FOLDER); // load the built-in and user layout devices - mLayoutDeviceManager.load(mManager.getLocation()); + mLayoutDeviceManager.loadDefaultAndUserDevices(mManager.getLocation()); // and the ones from the add-on loadLayoutDevices(); } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd similarity index 89% rename from tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd rename to tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd index 49131fba..8a585600 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-devices.xsd @@ -15,17 +15,17 @@ * limitations under the License. --> - + - The "layout-configs" element is the root element of this schema. + The "layout-devices" element is the root element of this schema. It must contain one or more "device" elements that each define the configurations available for a given device. @@ -37,7 +37,7 @@ - + @@ -92,6 +92,34 @@ + + + + Specifies the configuration is for a particular Mobile Country Code. + + + + + + + + + + + + + + Specifies the configuration is for a particular Mobile Network Code. + + + + + + + + + + diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java similarity index 81% rename from tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java rename to tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java index 43b0507e..8aa8ee0a 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutDevicesXsd.java @@ -30,9 +30,9 @@ import javax.xml.validation.Validator; import junit.framework.TestCase; /** - * Tests local validation of a Layout-Configs sample XMLs using an XML Schema validator. + * Tests local validation of a Layout-Devices sample XMLs using an XML Schema validator. */ -public class TestLayoutConfisXsd extends TestCase { +public class TestLayoutDevicesXsd extends TestCase { @Override protected void setUp() throws Exception { @@ -117,7 +117,7 @@ public class TestLayoutConfisXsd extends TestCase { Source source = new StreamSource(new StringReader(document)); // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = LayoutConfigsXsd.getValidator(null); + Validator validator = LayoutDevicesXsd.getValidator(null); try { validator.validate(source); } catch (SAXParseException e) { @@ -133,7 +133,7 @@ public class TestLayoutConfisXsd extends TestCase { Source source = new StreamSource(new StringReader(document)); CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = LayoutConfigsXsd.getValidator(null); + Validator validator = LayoutDevicesXsd.getValidator(null); validator.validate(source); handler.verify(); } @@ -144,11 +144,11 @@ public class TestLayoutConfisXsd extends TestCase { public void testValidateLocalRepositoryFile() throws Exception { InputStream xmlStream = - TestLayoutConfisXsd.class.getResourceAsStream("config_sample.xml"); + TestLayoutDevicesXsd.class.getResourceAsStream("config_sample.xml"); Source source = new StreamSource(xmlStream); CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = LayoutConfigsXsd.getValidator(handler); + Validator validator = LayoutDevicesXsd.getValidator(handler); validator.validate(source); handler.verify(); } @@ -168,9 +168,9 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + - "", + "", // expected failure "cvc-complex-type.2.4.a: Invalid content was found.*"); @@ -181,9 +181,9 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + - "", + "", // expected failure "cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'."); @@ -194,10 +194,10 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "", + "", // expected failure - "cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*"); + "cvc-complex-type.2.4.b: The content of element 'd:layout-devices' is not complete.*"); } /** A document with an empty device element is not valid. */ @@ -205,9 +205,9 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + - "", + "", // expected failure "cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*"); @@ -218,12 +218,12 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + " " + " " + "" + - "", + "", // expected failure "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*"); @@ -234,12 +234,12 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + " " + " " + "" + - "", + "", // expected failure "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*"); @@ -250,13 +250,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + " " + " 0 1 " + " " + "" + - "", + "", // expected failure "cvc-minInclusive-valid: Value '0' is not facet-valid with respect to minInclusive '1'.*"); @@ -267,13 +267,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + " " + " -5 1 " + " " + "" + - "", + "", // expected failure "cvc-minInclusive-valid: Value '-5' is not facet-valid with respect to minInclusive '1'.*"); @@ -284,13 +284,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + " " + " 0" + " " + "" + - "", + "", // expected failure "cvc-minExclusive-valid: Value '0' is not facet-valid with respect to minExclusive '0.0E1'.*"); @@ -302,13 +302,13 @@ public class TestLayoutConfisXsd extends TestCase { checkFailure( // document "" + - "" + + "" + "" + " " + " -3.1415926538" + " " + "" + - "", + "", // expected failure "cvc-minExclusive-valid: Value '-3.1415926538' is not facet-valid with respect to minExclusive '0.0E1'.*"); @@ -319,13 +319,13 @@ public class TestLayoutConfisXsd extends TestCase { checkSuccess( // document "" + - "" + + "" + "" + " " + " \n long \r " + " " + "" + - ""); + ""); } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml index 901dd71c..56a753f9 100755 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. --> - + xmlns:d="http://schemas.android.com/sdk/android/layout-devices/1"> @@ -134,4 +134,4 @@ - + diff --git a/tools/scripts/devices.xml b/tools/scripts/devices.xml index e600a199..2d10b898 100644 --- a/tools/scripts/devices.xml +++ b/tools/scripts/devices.xml @@ -1,7 +1,7 @@ - + xmlns:d="http://schemas.android.com/sdk/android/layout-devices/1"> @@ -59,4 +59,4 @@ land - + -- 2.11.0