001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.part;
011:
012: import java.io.ByteArrayInputStream;
013: import java.io.ByteArrayOutputStream;
014: import java.io.DataInputStream;
015: import java.io.DataOutputStream;
016: import java.io.IOException;
017:
018: import org.eclipse.core.resources.IResource;
019: import org.eclipse.core.resources.IWorkspace;
020: import org.eclipse.core.resources.ResourcesPlugin;
021: import org.eclipse.core.runtime.Path;
022: import org.eclipse.swt.dnd.ByteArrayTransfer;
023: import org.eclipse.swt.dnd.TransferData;
024:
025: /**
026: * The <code>ResourceTransfer</code> class is used to transfer an
027: * array of <code>IResources</code>s from one part to another in a
028: * drag and drop operation or a cut, copy, paste action.
029: * <p>
030: * In every drag and drop operation there is a <code>DragSource</code> and
031: * a <code>DropTarget</code>. When a drag occurs a <code>Transfer</code> is
032: * used to marshall the drag data from the source into a byte array. If a drop
033: * occurs another <code>Transfer</code> is used to marshall the byte array into
034: * drop data for the target.
035: * </p>
036: * <p>
037: * When a <code>CutAction</code> or a <code>CopyAction</code> is performed,
038: * this transfer is used to place references to the selected resources
039: * on the <code>Clipboard</code>. When a <code>PasteAction</code> is performed, the
040: * references on the clipboard are used to move or copy the resources
041: * to the selected destination.
042: * </p>
043: * <p>
044: * This class can be used for a <code>Viewer<code> or an SWT component directly.
045: * A singleton is provided which may be serially reused (see <code>getInstance</code>).
046: * It is not intended to be subclassed.
047: * </p>
048: *
049: * @see org.eclipse.jface.viewers.StructuredViewer
050: * @see org.eclipse.swt.dnd.DropTarget
051: * @see org.eclipse.swt.dnd.DragSource
052: */
053: public class ResourceTransfer extends ByteArrayTransfer {
054:
055: /**
056: * Singleton instance.
057: */
058: private static final ResourceTransfer instance = new ResourceTransfer();
059:
060: // Create a unique ID to make sure that different Eclipse
061: // applications use different "types" of <code>ResourceTransfer</code>
062: private static final String TYPE_NAME = "resource-transfer-format:" + System.currentTimeMillis() + ":" + instance.hashCode();//$NON-NLS-2$//$NON-NLS-1$
063:
064: private static final int TYPEID = registerType(TYPE_NAME);
065:
066: private IWorkspace workspace = ResourcesPlugin.getWorkspace();
067:
068: /**
069: * Creates a new transfer object.
070: */
071: private ResourceTransfer() {
072: }
073:
074: /**
075: * Returns the singleton instance.
076: *
077: * @return the singleton instance
078: */
079: public static ResourceTransfer getInstance() {
080: return instance;
081: }
082:
083: /* (non-Javadoc)
084: * Method declared on Transfer.
085: */
086: protected int[] getTypeIds() {
087: return new int[] { TYPEID };
088: }
089:
090: /* (non-Javadoc)
091: * Returns the type names.
092: *
093: * @return the list of type names
094: */
095: protected String[] getTypeNames() {
096: return new String[] { TYPE_NAME };
097: }
098:
099: /* (non-Javadoc)
100: * Method declared on Transfer.
101: */
102: protected void javaToNative(Object data, TransferData transferData) {
103: if (!(data instanceof IResource[])) {
104: return;
105: }
106:
107: IResource[] resources = (IResource[]) data;
108: /**
109: * The resource serialization format is:
110: * (int) number of resources
111: * Then, the following for each resource:
112: * (int) resource type
113: * (String) path of resource
114: */
115:
116: int resourceCount = resources.length;
117:
118: try {
119: ByteArrayOutputStream out = new ByteArrayOutputStream();
120: DataOutputStream dataOut = new DataOutputStream(out);
121:
122: //write the number of resources
123: dataOut.writeInt(resourceCount);
124:
125: //write each resource
126: for (int i = 0; i < resources.length; i++) {
127: writeResource(dataOut, resources[i]);
128: }
129:
130: //cleanup
131: dataOut.close();
132: out.close();
133: byte[] bytes = out.toByteArray();
134: super .javaToNative(bytes, transferData);
135: } catch (IOException e) {
136: //it's best to send nothing if there were problems
137: }
138: }
139:
140: /* (non-Javadoc)
141: * Method declared on Transfer.
142: */
143: protected Object nativeToJava(TransferData transferData) {
144: /**
145: * The resource serialization format is:
146: * (int) number of resources
147: * Then, the following for each resource:
148: * (int) resource type
149: * (String) path of resource
150: */
151:
152: byte[] bytes = (byte[]) super .nativeToJava(transferData);
153: if (bytes == null) {
154: return null;
155: }
156: DataInputStream in = new DataInputStream(
157: new ByteArrayInputStream(bytes));
158: try {
159: int count = in.readInt();
160: IResource[] results = new IResource[count];
161: for (int i = 0; i < count; i++) {
162: results[i] = readResource(in);
163: }
164: return results;
165: } catch (IOException e) {
166: return null;
167: }
168: }
169:
170: /**
171: * Reads a resource from the given stream.
172: *
173: * @param dataIn the input stream
174: * @return the resource
175: * @exception IOException if there is a problem reading from the stream
176: */
177: private IResource readResource(DataInputStream dataIn)
178: throws IOException {
179: int type = dataIn.readInt();
180: String path = dataIn.readUTF();
181: switch (type) {
182: case IResource.FOLDER:
183: return workspace.getRoot().getFolder(new Path(path));
184: case IResource.FILE:
185: return workspace.getRoot().getFile(new Path(path));
186: case IResource.PROJECT:
187: return workspace.getRoot().getProject(path);
188: }
189: throw new IllegalArgumentException(
190: "Unknown resource type in ResourceTransfer.readResource"); //$NON-NLS-1$
191: }
192:
193: /**
194: * Writes the given resource to the given stream.
195: *
196: * @param dataOut the output stream
197: * @param resource the resource
198: * @exception IOException if there is a problem writing to the stream
199: */
200: private void writeResource(DataOutputStream dataOut,
201: IResource resource) throws IOException {
202: dataOut.writeInt(resource.getType());
203: dataOut.writeUTF(resource.getFullPath().toString());
204: }
205: }
|