blob: 20ac2033e400e4705d3b2cd208e4b217fad4dc1f [file] [log] [blame]
/*
* 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;
}
}