Package org.eclipse.wst.sse.ui.internal

Source Code of org.eclipse.wst.sse.ui.internal.TransferBuilder$TransferProxyForDelayLoading

/*******************************************************************************
* Copyright (c) 2001, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Jens Lukowski/Innoopract - initial renaming/restructuring
*    
*******************************************************************************/
package org.eclipse.wst.sse.ui.internal;



import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.wst.sse.ui.internal.extension.DropActionProxy;
import org.eclipse.wst.sse.ui.internal.extension.RegistryReader;
import org.osgi.framework.Bundle;


/**
* Builds drop target transfers, drag source transfers, and drop actions
*/
public class TransferBuilder extends RegistryReader {

  public static final String ATT_CLASS = "class"; //$NON-NLS-1$
  public static final String ATT_ID = "id"; //$NON-NLS-1$
  public static final String ATT_METHOD = "method"; //$NON-NLS-1$
  public static final String ATT_PRIORITY = "priority"; //$NON-NLS-1$
  public static final String ATT_SINGLETON = "singleton"; //$NON-NLS-1$
  public static final String ATT_TARGET_ID = "targetID"; //$NON-NLS-1$
  public static final String ATT_TRANSFER_ID = "transferID"; //$NON-NLS-1$

  private final static boolean debugTime = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/transferbuilder/time")); //$NON-NLS-1$  //$NON-NLS-2$

  public static final String PL_DRAG_SOURCE_TRANSFERS = "dragSourceTransfers"; //$NON-NLS-1$
  public static final String PL_DROP_TARGET_TRANSFERS = "dropTargetTransfers"; //$NON-NLS-1$

  public static final String PLUGIN_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$

  public static final String[] PRIORITIES = {"highest", "high", "mid", "low", "lowest"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$

  public static final String TAG_DRAG_SOURCE_CONTRIBUTION = "dragSourceContribution"; //$NON-NLS-1$
  public static final String TAG_DROP_ACTION = "dropAction"; //$NON-NLS-1$
  public static final String TAG_DROP_TARGET_CONTRIBUTION = "dropTargetContribution"; //$NON-NLS-1$

  public static final String TAG_TRANSFER = "transfer"; //$NON-NLS-1$

  public static final String TRUE = "true"; //$NON-NLS-1$

  private boolean useProxy;

  class TransferProxyForDelayLoading extends Transfer {
      private IConfigurationElement element;
      private String classAttribute;
      private Transfer proxy;
        private Method getTypeIdsMethod, getTypeNamesMethod, javaToNativeMethod, nativeToJavaMethod;

      TransferProxyForDelayLoading() {
          super();
      }

      TransferProxyForDelayLoading(IConfigurationElement elm, String clsAttr) {
          super();
          this.element = elm;
          this.classAttribute = clsAttr;
      }
     
      private Transfer newInstance() {
          if ((element != null) && (classAttribute != null)) {
            Object o = createExtension(element, classAttribute);
            if (o instanceof Transfer) {
                element = null;
                classAttribute = null;
                return (Transfer)o;
            }
          }
          return null;
      }

      public TransferData[] getSupportedTypes() {
          if (proxy == null) {
              proxy = newInstance();
          }
          if (proxy != null) {
              return proxy.getSupportedTypes();
          }
          return new TransferData[0];
        }
        protected int[] getTypeIds() {
          if (proxy == null) {
              proxy = newInstance();
          }
          if (proxy != null) {
                if (getTypeIdsMethod == null) {
                  Class runtimeClass = proxy.getClass();
                    NoSuchMethodException e = null;
                    while (runtimeClass != null) {
                      try {
                          getTypeIdsMethod = runtimeClass.getDeclaredMethod("getTypeIds", new Class[0]);//$NON-NLS-1$
                            getTypeIdsMethod.setAccessible(true);
                            break;
                      } catch (NoSuchMethodException e1) {
                            e = e1;
                            runtimeClass = runtimeClass.getSuperclass();
                      } catch (SecurityException e2) {
                            runtimeClass = runtimeClass.getSuperclass();
                      }
                    }
                    if ((getTypeIdsMethod == null) && (e != null)) {
                        Logger.logException(e);
                    }
                }
                if (getTypeIdsMethod != null) {
                    try {
                         // changed Integer[] return type to int[]
                        int[] r = (int[])getTypeIdsMethod.invoke(proxy, new Object[0]);
                        if ((r != null) && (r.length > 0)) {
                            int[] ret = new int[r.length];
                            for(int i = 0; i < r.length; i++) {
                                ret[i] = r[i];
                            }
                            return ret;
                        }
                    } catch (IllegalAccessException e2) {
                        Logger.logException(e2);
                    } catch (InvocationTargetException e3) {
                        Logger.logException(e3);
                    }
                }
          }
            return new int[0];
        }
        protected String[] getTypeNames() {
          if (proxy == null) {
              proxy = newInstance();
          }
          if (proxy != null) {
                if (getTypeNamesMethod == null) {
                  Class runtimeClass = proxy.getClass();
                    NoSuchMethodException e = null;
                    while (runtimeClass != null) {
                      try {
                          getTypeNamesMethod = runtimeClass.getDeclaredMethod("getTypeNames", new Class[0]);//$NON-NLS-1$
                            getTypeNamesMethod.setAccessible(true);
                            break;
                      } catch (NoSuchMethodException e1) {
                            e = e1;
                            runtimeClass = runtimeClass.getSuperclass();
                      } catch (SecurityException e2) {
                            runtimeClass = runtimeClass.getSuperclass();
                      }
                    }
                    if ((getTypeNamesMethod == null) && (e != null)) {
                        Logger.logException(e);
                    }
                }
                if (getTypeNamesMethod != null) {
                    try {
                        return (String[])getTypeNamesMethod.invoke(proxy, new Object[0]);
                    } catch (IllegalAccessException e2) {
                        Logger.logException(e2);
                    } catch (InvocationTargetException e3) {
                        Logger.logException(e3);
                    }
                }
          }
            return new String[0];
        }
        public boolean isSupportedType(TransferData transferData) {
          if (proxy == null) {
              proxy = newInstance();
          }
          if (proxy != null) {
              return proxy.isSupportedType(transferData);
          }
            return false;
        }
        protected void javaToNative(Object object, TransferData transferData) {
          if (proxy == null) {
              proxy = newInstance();
          }
          if (proxy != null) {
                if (javaToNativeMethod == null) {
                    Class runtimeClass = proxy.getClass();
                    NoSuchMethodException e = null;
                    while (runtimeClass != null) {
                      try {
                          javaToNativeMethod = runtimeClass.getDeclaredMethod("javaToNative", new Class[]{object.getClass(), transferData.getClass()});//$NON-NLS-1$
                          javaToNativeMethod.setAccessible(true);
                            break;
                      } catch (NoSuchMethodException e1) {
                            e = e1;
                            runtimeClass = runtimeClass.getSuperclass();
                      } catch (SecurityException e2) {
                            runtimeClass = runtimeClass.getSuperclass();
                      }
                    }
                    if ((javaToNativeMethod == null) && (e != null)) {
                        Logger.logException(e);
                    }
                }
                if (javaToNativeMethod != null) {
                    try {
                        javaToNativeMethod.invoke(proxy, new Object[]{object, transferData});
                    } catch (IllegalAccessException e2) {
                        Logger.logException(e2);
                    } catch (InvocationTargetException e3) {
                        Logger.logException(e3);
                    }
                }
          }
        }
        protected Object nativeToJava(TransferData transferData) {
          if (proxy == null) {
              proxy = newInstance();
          }
          if (proxy != null) {
                if (nativeToJavaMethod == null) {
                    Class runtimeClass = proxy.getClass();
                    NoSuchMethodException e = null;
                    while (runtimeClass != null) {
                        try {
                            nativeToJavaMethod = runtimeClass.getDeclaredMethod("nativeToJava", new Class[]{transferData.getClass()});//$NON-NLS-1$
                            nativeToJavaMethod.setAccessible(true);
                            break;
                        } catch (NoSuchMethodException e1) {
                            e = e1;
                            runtimeClass = runtimeClass.getSuperclass();
                      } catch (SecurityException e2) {
                            runtimeClass = runtimeClass.getSuperclass();
                      }
                    }
                    if ((nativeToJavaMethod == null) && (e != null)) {
                        Logger.logException(e);
                    }
                }
                if (nativeToJavaMethod != null) {
                    try {
                      return nativeToJavaMethod.invoke(proxy, new Object[]{transferData});
                  } catch (IllegalAccessException e2) {
                       Logger.logException(e2);
                  } catch (InvocationTargetException e3) {
                       Logger.logException(e3);
                  }
                }
          }
            return new Object();
        }
        Transfer getTransferClass() {
          if (proxy == null) {
              proxy = newInstance();
          }
          return proxy;
        }
       
        public String toString() {
          String clazz = element.getAttribute(classAttribute);
          return clazz != null ? clazz : super.toString();
        }
  }
  /**
   * @param element
   * @param classAttribute
   * @return Object
   * @throws CoreException
   */
  static Object createExecutableExtension(final IConfigurationElement element, final String classAttribute) throws CoreException {

    Object obj = null;

    String singleton = element.getAttribute(ATT_SINGLETON);
    String method = element.getAttribute(ATT_METHOD);
    if (TRUE.equalsIgnoreCase(singleton) && method != null) {
      try {
        String name = element.getAttribute(ATT_CLASS);
        String pluginId = element.getDeclaringExtension().getNamespace();
        Class cls = Platform.getBundle(pluginId).loadClass(name);
        Method mtd = cls.getMethod(method, new Class[]{});

        obj = mtd.invoke(null, null);
      } catch (ClassNotFoundException e) {
        obj = null;
      } catch (NoSuchMethodException e) {
        obj = null;
      } catch (IllegalAccessException e) {
        obj = null;
      } catch (InvocationTargetException e) {
        obj = null;
      }
    } else {
      obj = element.createExecutableExtension(classAttribute);
    }

    return obj;
  }

  /**
   * Creates an extension. If the extension plugin has not been loaded a
   * busy cursor will be activated during the duration of the load.
   *
   * @param element
   * @param classAttribute
   * @return Object
   * @throws CoreException
   */
  public static Object createExtension(final IConfigurationElement element, final String classAttribute) {
    // If plugin has been loaded create extension.
    // Otherwise, show busy cursor then create extension.
    final Object[] result = new Object[1];
    String pluginId = element.getDeclaringExtension().getNamespace();
    Bundle bundle = Platform.getBundle(pluginId);
    if (bundle.getState() == Bundle.ACTIVE) {
      try {
        return createExecutableExtension(element, classAttribute);
      } catch (CoreException e) {
        handleCreateExecutableException(result, e);
      }
    } else {
      BusyIndicator.showWhile(null, new Runnable() {
        public void run() {
          try {
            result[0] = createExecutableExtension(element, classAttribute);
          } catch (Exception e) {
            handleCreateExecutableException(result, e);
          }
        }
      });
    }
    return result[0];
  }

  /**
   * @param result
   * @param e
   */
  protected static void handleCreateExecutableException(Object[] result, Throwable e) {
    Logger.logException(e);
    result[0] = null;

  }

  protected List cache;
  protected String targetContributionTag;

  protected List targetIDs;

  /**
   * @param element
   * @return IDropAction
   */
  protected IDropAction createDropAction(IConfigurationElement element) {
    Object obj = null;
    obj = createExtension(element, ATT_CLASS);
    if (obj == null)
      return null;
    return (obj instanceof IDropAction) ? (IDropAction) DropActionProxy.newInstance(obj) : null;
  }

  /**
   * @param transferId
   * @return IDropAction[]
   */
  protected IDropAction[] createDropActions(String transferId) {
    if (cache == null)
      return new IDropAction[0];

    final int num = cache.size();
    if (num == 0)
      return new IDropAction[0];

    IDropAction[] as = new IDropAction[num];
    int j = 0;
    for (int p = 0; p < PRIORITIES.length; p++) {
      for (int i = 0; i < num; i++) {
        Object obj = cache.get(i);
        if (!(obj instanceof IConfigurationElement))
          continue;

        IConfigurationElement element = (IConfigurationElement) obj;
        if (!(TAG_DROP_ACTION.equals(element.getName())) || !(transferId.equals(element.getAttribute(ATT_TRANSFER_ID))))
          continue;

        if (PRIORITIES[p].equals(element.getAttribute(ATT_PRIORITY)) || (p == 2 && element.getAttribute(ATT_PRIORITY) == null)) {
          IDropAction a = createDropAction(element);
          if (a != null) {
            as[j] = a;
            j++;
          }
        }
      }
    }

    if (num == j)
      return as;

    IDropAction[] as2 = new IDropAction[j];
    for (int i = 0; i < j; i++) {
      as2[i] = as[i];
    }

    return as2;
  }

  /**
   * @param element
   * @return Transfer
   */
  protected Transfer createTransfer(IConfigurationElement element) {
      Object obj = null;
      if (useProxy) {
          obj = new TransferProxyForDelayLoading(element, ATT_CLASS);
      } else {
          obj = createExtension(element, ATT_CLASS);
      }
    if (obj == null)
      return null;
    return (obj instanceof Transfer) ? (Transfer) obj : null;
  }

  /**
   * @return Transfer[]
   */
  protected Transfer[] createTransfers() {
    if (cache == null)
      return new Transfer[0];

    final int num = cache.size();
    if (num == 0)
      return new Transfer[0];

    Transfer[] ts = new Transfer[num];
    int j = 0;
    for (int p = 0; p < PRIORITIES.length; p++) {
      for (int i = 0; i < num; i++) {
        Object obj = cache.get(i);
        if (!(obj instanceof IConfigurationElement))
          continue;

        IConfigurationElement element = (IConfigurationElement) obj;
        if (!TAG_TRANSFER.equals(element.getName()))
          continue;

        if (PRIORITIES[p].equals(element.getAttribute(ATT_PRIORITY)) || (p == 2 && element.getAttribute(ATT_PRIORITY) == null)) {
          Transfer t = createTransfer(element);
          if (t != null) {
            ts[j] = t;
            j++;
          }
        }
      }
    }

    if (num == j)
      return ts;

    Transfer[] ts2 = new Transfer[j];
    for (int i = 0; i < j; i++) {
      ts2[i] = ts[i];
    }

    return ts2;
  }

  /**
   * @param editorId
   * @return Transfer[]
   */
  public Transfer[] getDragSourceTransfers(String editorId) {
    return getDragSourceTransfers(new String[]{editorId});
  }

  /**
   * @param editorIds
   * @return Transfer[]
   */
  public Transfer[] getDragSourceTransfers(String[] editorIds) {
    long time0 = System.currentTimeMillis();
    readContributions(editorIds, TAG_DRAG_SOURCE_CONTRIBUTION, PL_DRAG_SOURCE_TRANSFERS);
    Transfer[] transfers = createTransfers();
    if (debugTime)
      System.out.println(getClass().getName() + "#getDragSourceTransfers(" + editorIds + "): " + transfers.length + " transfers created in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    return transfers;
  }

  /**
   * @deprecated use getDropActions(String editorId, Transfer transfer) for the performance
   * @param editorId
   * @param className
   * @return IDropAction[]
   */
  public IDropAction[] getDropActions(String editorId, String transferClassName) {
    return getDropActions(new String[]{editorId}, transferClassName);
  }
 
  /**
   * @param editorId
   * @param class
   * @return IDropAction[]
   */
  public IDropAction[] getDropActions(String editorId, Transfer transfer) {
    return getDropActions(new String[]{editorId}, transfer);
  }
  /**
   * @deprecated use getDropActions(String[] editorIds, Transfer transfer) for the performance
   * @param editorId
   * @param className
   * @return IDropAction[]
   */
  public IDropAction[] getDropActions(String[] editorIds, String transferClassName) {
    long time0 = System.currentTimeMillis();
    readContributions(editorIds, TAG_DROP_TARGET_CONTRIBUTION, PL_DROP_TARGET_TRANSFERS);
    String transferId = getTransferIdOfClassName(transferClassName);
    IDropAction[] actions = createDropActions(transferId);
    if (debugTime)
      System.out.println(getClass().getName() + "#getDropActions(" + editorIds + "): " + actions.length + " drop actions created in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    return actions;
  }

  /**
   * @param editorId
   * @param class
   * @return IDropAction[]
   */
  public IDropAction[] getDropActions(String[] editorIds, Transfer transfer) {
      String transferClassName;
      if (transfer instanceof TransferProxyForDelayLoading) {
          transferClassName = ((TransferProxyForDelayLoading)transfer).getTransferClass().getClass().getName();
      } else {
          transferClassName = transfer.getClass().getName();
      }
      return getDropActions(editorIds, transferClassName);
  }
  /**
   * @param editorId
   * @return Transfer[]
   */
  public Transfer[] getDropTargetTransfers(String editorId) {
    return getDropTargetTransfers(new String[]{editorId});
  }

  /**
   * @param editorIds
   * @return Transfer[]
   */
  public Transfer[] getDropTargetTransfers(String[] editorIds) {
    long time0 = System.currentTimeMillis();
    readContributions(editorIds, TAG_DROP_TARGET_CONTRIBUTION, PL_DROP_TARGET_TRANSFERS);
    Transfer[] transfers = createTransfers();
    if (debugTime) {
      String idlist = ""; //$NON-NLS-1$
      if (editorIds.length > 0) {
        for (int i = 0; i < editorIds.length; i++) {
          idlist += editorIds[i];
          if (i < editorIds.length - 1)
            idlist += ","; //$NON-NLS-1$
        }
      }
      System.out.println(getClass().getName() + "#getDropTargetTransfers(" + idlist + "): " + transfers.length + " transfers created in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    }
    return transfers;
  }

  /**
   * Returns the name of the part ID attribute that is expected in the
   * target extension.
   *
   * @param element
   * @return String
   */
  protected String getTargetID(IConfigurationElement element) {
    String value = element.getAttribute(ATT_TARGET_ID);
    return value != null ? value : "???"; //$NON-NLS-1$
  }

  /**
   * @param className
   * @return String
   */
  private String getTransferIdOfClassName(String className) {
    String id = ""; //$NON-NLS-1$
    final int num = cache.size();
    if (className == null || cache == null || num == 0)
      return id;

    for (int i = 0; i < num; i++) {
      Object obj = cache.get(i);
      if (obj instanceof IConfigurationElement) {
        IConfigurationElement element = (IConfigurationElement) obj;
        if (className.equals(element.getAttribute(ATT_CLASS))) {
          id = element.getAttribute(ATT_ID);
          break;
        }
      }
    }

    return (id.length() != 0 ? id : className);
  }

  /**
   * Reads the contributions from the registry for the provided workbench
   * part and the provided extension point ID.
   *
   * @param id
   * @param tag
   * @param extensionPoint
   */
  protected void readContributions(String[] ids, String tag, String extensionPoint) {
    cache = null;
    targetIDs = Arrays.asList(ids);
    targetContributionTag = tag;
    IExtensionRegistry registry = Platform.getExtensionRegistry();
    readRegistry(registry, PLUGIN_ID, extensionPoint);
  }

  protected boolean readElement(IConfigurationElement element) {
    String tag = element.getName();
    if (tag.equals(targetContributionTag)) {
      String id = getTargetID(element);
      if (id == null || !targetIDs.contains(id)) {
        // This is not of interest to us - don't go deeper
        return true;
      }
    } else if (tag.equals(TAG_TRANSFER)) {
      if (cache == null)
        cache = new ArrayList();
      cache.add(element);
      return true; // just cache the element - don't go into it
    } else if (tag.equals(TAG_DROP_ACTION)) {
      if (cache == null)
        cache = new ArrayList();
      //cache.add(createActionDescriptor(element));
      cache.add(element);
      return true; // just cache the action - don't go into
    } else {
      return false;
    }

    readElementChildren(element);
    return true;
  }
  /**
   * @deprecated - use TransferBuilder(boolean useProxy) for the performance
   */
  public TransferBuilder() {
        this(false);
    }

    public TransferBuilder(boolean useProxy) {
        super();
        this.useProxy = useProxy;
    }
}
TOP

Related Classes of org.eclipse.wst.sse.ui.internal.TransferBuilder$TransferProxyForDelayLoading

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.