diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleXmlTransfer.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleXmlTransfer.java | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleXmlTransfer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleXmlTransfer.java new file mode 100644 index 000000000..20ac2033e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleXmlTransfer.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ide.eclipse.adt.internal.editors.layout.gle2; + +import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; +import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; + +import org.eclipse.swt.dnd.ByteArrayTransfer; +import org.eclipse.swt.dnd.TransferData; + +import java.io.UnsupportedEncodingException; + +/** + * A d'n'd {@link Transfer} class that can transfer a <em>simplified</em> XML fragment + * to transfer elements and their attributes between {@link LayoutCanvas}. + * <p/> + * The implementation is based on the {@link ByteArrayTransfer} and what we transfer + * is text with the following fixed format: + * <p/> + * <pre> + * {element-name element-property ... + * attrib_name="attrib_value" + * attrib2="..." + * {...inner elements... + * } + * } + * {...next element... + * } + * + * </pre> + * The format has nothing to do with XML per se, except for the fact that the + * transfered content represents XML elements and XML attributes. + * + * <p/> + * The detailed syntax is: + * <pre> + * - ELEMENT := {NAME PROPERTY*\nATTRIB_LINE*ELEMENT*}\n + * - PROPERTY := $[A-Z]=[^ ]* + * - NAME := [^\n=]+ + * - ATTRIB_LINE := @URI:NAME=[^\n]*\n + * </pre> + * + * Elements are represented by {@link SimpleElement}s and their attributes by + * {@link SimpleAttribute}s, all of which have very specific properties that are + * specifically limited to our needs for drag'n'drop. + */ +final class SimpleXmlTransfer extends ByteArrayTransfer { + + // Reference: http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html + + private static final String TYPE_NAME = "android.ADT.simple.xml.transfer.1"; //$NON-NLS-1$ + private static final int TYPE_ID = registerType(TYPE_NAME); + private static final SimpleXmlTransfer sInstance = new SimpleXmlTransfer(); + + /** Private constructor. Use {@link #getInstance()} to retrieve the singleton instance. */ + private SimpleXmlTransfer() { + // pass + } + + /** Returns the singleton instance. */ + public static SimpleXmlTransfer getInstance() { + return sInstance; + } + + /** + * Helper method that returns the FQCN transfered for the given {@link ElementDescriptor}. + * <p/> + * If the descriptor is a {@link ViewElementDescriptor}, the transfered data is the FQCN + * of the Android View class represented (e.g. "android.widget.Button"). + * For any other non-null descriptor, the XML name is used. + * Otherwise it is null. + * + * @param desc The {@link ElementDescriptor} to transfer. + * @return The FQCN, XML name or null. + */ + public static String getFqcn(ElementDescriptor desc) { + if (desc instanceof ViewElementDescriptor) { + return ((ViewElementDescriptor) desc).getFullClassName(); + } else if (desc != null) { + return desc.getXmlName(); + } + + return null; + } + + @Override + protected int[] getTypeIds() { + return new int[] { TYPE_ID }; + } + + @Override + protected String[] getTypeNames() { + return new String[] { TYPE_NAME }; + } + + /** Transforms a array of {@link SimpleElement} into a native data transfer. */ + @Override + protected void javaToNative(Object object, TransferData transferData) { + if (object == null || !(object instanceof SimpleElement[])) { + return; + } + + if (isSupportedType(transferData)) { + StringBuilder sb = new StringBuilder(); + for (SimpleElement e : (SimpleElement[]) object) { + sb.append(e.toString()); + } + String data = sb.toString(); + + try { + byte[] buf = data.getBytes("UTF-8"); //$NON-NLS-1$ + super.javaToNative(buf, transferData); + } catch (UnsupportedEncodingException e) { + // unlikely; ignore + } + } + } + + /** + * Recreates an array of {@link SimpleElement} from a native data transfer. + * + * @return An array of {@link SimpleElement} or null. The array may be empty. + */ + @Override + protected Object nativeToJava(TransferData transferData) { + if (isSupportedType(transferData)) { + byte[] buf = (byte[]) super.nativeToJava(transferData); + if (buf != null && buf.length > 0) { + try { + String s = new String(buf, "UTF-8"); //$NON-NLS-1$ + return SimpleElement.parseString(s); + } catch (UnsupportedEncodingException e) { + // unlikely to happen, but still possible + } + } + } + + return null; + } +} |