// ============================================================================ // // Copyright (C) 2006-2012 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.repository.ui.views; import java.lang.reflect.InvocationTargetException; import java.util.List; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TransferData; import org.eclipse.ui.part.PluginDropAdapter; import org.osgi.framework.FrameworkUtil; import org.talend.commons.exception.LoginException; import org.talend.commons.exception.PersistenceException; import org.talend.commons.ui.runtime.exception.ExceptionHandler; import org.talend.core.GlobalServiceRegister; import org.talend.core.model.business.BusinessType; import org.talend.core.model.properties.ConnectionItem; import org.talend.core.model.properties.Item; import org.talend.core.model.properties.Property; import org.talend.core.model.properties.RoutineItem; import org.talend.core.model.properties.SQLPatternItem; import org.talend.core.model.repository.ERepositoryObjectType; import org.talend.core.model.repository.IRepositoryViewObject; import org.talend.core.repository.i18n.Messages; import org.talend.core.repository.model.ProxyRepositoryFactory; import org.talend.core.repository.utils.AbstractResourceChangesService; import org.talend.core.repository.utils.TDQServiceRegister; import org.talend.core.runtime.CoreRuntimePlugin; import org.talend.designer.business.diagram.custom.IDiagramModelService; import org.talend.repository.RepositoryWorkUnit; import org.talend.repository.model.ERepositoryStatus; import org.talend.repository.model.IRepositoryNode; import org.talend.repository.model.IRepositoryNode.ENodeType; import org.talend.repository.model.IRepositoryNode.EProperties; import org.talend.repository.model.RepositoryNode; import org.talend.repository.model.actions.CopyObjectAction; import org.talend.repository.model.actions.MoveObjectAction; /** * DOC smallet class global comment. Detailled comment <br/> * * $Id: RepositoryDropAdapter.java 84099 2012-05-24 07:59:33Z cli $ * */ public class RepositoryDropAdapter extends PluginDropAdapter { public RepositoryDropAdapter(StructuredViewer viewer) { super(viewer); } private DropTargetEvent event; @Override public void drop(DropTargetEvent event) { this.event = event; super.drop(event); } /* * (non-Javadoc) * * @see org.eclipse.ui.part.PluginDropAdapter#performDrop(java.lang.Object) */ @Override public boolean performDrop(final Object data) { int operation = getCurrentOperation(); final RepositoryNode targetNode = (RepositoryNode) getCurrentTarget(); boolean toReturn = true; try { switch (operation) { case DND.DROP_COPY: RunnableWithReturnValue runnable = new CopyRunnable( Messages.getString("RepositoryDropAdapter_copyingItems"), data, targetNode); //$NON-NLS-1$ runInProgressDialog(runnable); toReturn = (Boolean) runnable.getReturnValue(); break; case DND.DROP_MOVE: runnable = new MoveRunnable(Messages.getString("RepositoryDropAdapter_movingItems"), data, targetNode); //$NON-NLS-1$ runInProgressDialog(runnable); toReturn = (Boolean) runnable.getReturnValue(); break; // TDI-20080 hqzhang, operation value(actually is event.detail) on drag enter state maybe different from // value on drop // state, this could be a bug of ViewerDropAdapter case DND.DROP_DEFAULT: if (event.detail == DND.DROP_COPY) { runnable = new CopyRunnable(Messages.getString("RepositoryDropAdapter_copyingItems"), data, targetNode); //$NON-NLS-1$ runInProgressDialog(runnable); toReturn = (Boolean) runnable.getReturnValue(); break; } if (event.detail == DND.DROP_MOVE) { runnable = new MoveRunnable(Messages.getString("RepositoryDropAdapter_movingItems"), data, targetNode); //$NON-NLS-1$ runInProgressDialog(runnable); toReturn = (Boolean) runnable.getReturnValue(); break; } default: // Nothing to do } } catch (Exception e) { ExceptionHandler.process(e); } return toReturn; } /** * ADD gdbu 2011-9-29 TDQ-3546 * * DOC gdbu(TDQ) Comment method "judgeCanMoveOrNotByDependency". If current connecton have dependencies in TDQ , * then return false and that means can not move it. * * @param sourceNode * @param resourceChangeService * @return */ private boolean judgeCanMoveOrNotByDependency(RepositoryNode sourceNode, AbstractResourceChangesService resourceChangeService) { for (IRepositoryNode iRepositoryNode : sourceNode.getChildren()) { RepositoryNode repositoryNode = (RepositoryNode) iRepositoryNode; if (repositoryNode.getType().equals(ENodeType.SIMPLE_FOLDER)) { judgeCanMoveOrNotByDependency(repositoryNode, resourceChangeService); } else { // iRepositoryNode.getObject().getProperty().getItem().eResource().unload(); Item item = repositoryNode.getObject() == null ? null : repositoryNode.getObject().getProperty().getItem(); if (resourceChangeService != null && null != item) { boolean handleResourceChange = resourceChangeService.handleResourceChange(((ConnectionItem) item) .getConnection()); if (!handleResourceChange) { return handleResourceChange; } } } } return true; } /* * (non-Javadoc) * * @see org.eclipse.ui.part.PluginDropAdapter#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData) */ @Override public boolean validateDrop(Object target, int operation, TransferData transferType) { if (target == null) return false; super.validateDrop(target, operation, transferType); boolean isValid = true; for (Object obj : ((StructuredSelection) getViewer().getSelection()).toArray()) { RepositoryNode sourceNode = (RepositoryNode) obj; if (sourceNode != null) { IRepositoryViewObject object = sourceNode.getObject(); if (object == null) { return false; } if (object.getRepositoryObjectType() == ERepositoryObjectType.JOB_DOC || object.getRepositoryObjectType() == ERepositoryObjectType.JOBLET_DOC) { if (GlobalServiceRegister.getDefault().isServiceRegistered(IDiagramModelService.class)) { IDiagramModelService diagramModelService = (IDiagramModelService) GlobalServiceRegister.getDefault() .getService(IDiagramModelService.class); if (diagramModelService != null && BusinessType.SHAP == diagramModelService.getBusinessModelType(target)) { return true; } } return false; } else if (object.getRepositoryObjectType() == ERepositoryObjectType.ROUTINES) { Property property = object.getProperty(); RoutineItem item = (RoutineItem) property.getItem(); if (item.isBuiltIn() && target instanceof RepositoryNode) { return false; } } else if (object.getRepositoryObjectType() == ERepositoryObjectType.SQLPATTERNS) { Property property = object.getProperty(); SQLPatternItem item = (SQLPatternItem) property.getItem(); if (item.isSystem() && target instanceof RepositoryNode) { return false; } } } switch (operation) { case DND.DROP_COPY: isValid = CopyObjectAction.getInstance().validateAction(sourceNode, (RepositoryNode) target); break; // case DND.DROP_NONE: case DND.DROP_MOVE: isValid = MoveObjectAction.getInstance().validateAction(sourceNode, (RepositoryNode) target, true); break; case DND.DROP_DEFAULT: case DND.Drop: // hywang isValid = MoveObjectAction.getInstance().validateAction(sourceNode, (RepositoryNode) target, true); break; default: isValid = false; } // if (!isValid) { // return isValid; // } } return isValid; } private void runInProgressDialog(final IWorkspaceRunnable op) { final IRunnableWithProgress iRunnableWithProgress = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { IWorkspace workspace = ResourcesPlugin.getWorkspace(); try { ISchedulingRule schedulingRule = workspace.getRoot(); // the update the project files need to be done in the workspace runnable to avoid all // notifications. // of changes before the end of the modifications. workspace.run(op, schedulingRule, IWorkspace.AVOID_UPDATE, monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } } }; RepositoryWorkUnit<Object> repositoryWorkUnit = new RepositoryWorkUnit<Object>("Move or Copy", this) { @Override protected void run() throws LoginException, PersistenceException { try { ProgressMonitorDialog progress = new ProgressMonitorDialog(getViewer().getControl().getShell()); progress.run(false, false, iRunnableWithProgress); } catch (InvocationTargetException e) { ExceptionHandler.process(e); } catch (InterruptedException e) { ExceptionHandler.process(e); } } }; repositoryWorkUnit.setAvoidUnloadResources(true); CoreRuntimePlugin.getInstance().getProxyRepositoryFactory().executeRepositoryWorkUnit(repositoryWorkUnit); } /** * hqzhang. */ class CopyRunnable extends RunnableWithReturnValue { private Object data; private RepositoryNode targetNode; public CopyRunnable(String taskName, Object data, RepositoryNode targetNode) { super(taskName); this.data = data; this.targetNode = targetNode; } public void run(IProgressMonitor monitor) throws CoreException { monitor.beginTask(getTaskName(), IProgressMonitor.UNKNOWN); String copyName = "User action : Copy Object"; //$NON-NLS-1$ RepositoryWorkUnit<Object> repositoryWorkUnit = new RepositoryWorkUnit<Object>(copyName, CopyObjectAction.getInstance()) { @Override protected void run() throws LoginException, PersistenceException { try { for (Object obj : ((StructuredSelection) data).toArray()) { final RepositoryNode sourceNode = (RepositoryNode) obj; CopyObjectAction.getInstance().execute(sourceNode, targetNode); } } catch (Exception e) { throw new PersistenceException(e); } } }; ProxyRepositoryFactory.getInstance().executeRepositoryWorkUnit(repositoryWorkUnit); setReturnValue(true); monitor.done(); } } /** * hqzhang. */ class MoveRunnable extends RunnableWithReturnValue { private Object data; private RepositoryNode targetNode; public MoveRunnable(String taskName, Object data, RepositoryNode targetNode) { super(taskName); this.data = data; this.targetNode = targetNode; } public void run(final IProgressMonitor monitor) throws CoreException { monitor.beginTask(getTaskName(), IProgressMonitor.UNKNOWN); // MOD gdbu 2011-10-9 TDQ-3545 List<?> selectItems = ((org.eclipse.jface.viewers.TreeSelection) data).toList(); for (Object object : selectItems) { if (object instanceof RepositoryNode) { RepositoryNode repositoryNode = (RepositoryNode) object; boolean isLock = false; monitor.subTask(Messages.getString("RepositoryDropAdapter.checkingLockStatus") + repositoryNode.getObject().getLabel()); //$NON-NLS-1$ isLock = MoveObjectAction.getInstance().isLock(repositoryNode); if (isLock) { String errorMsg = null; IRepositoryViewObject objectToCopy = repositoryNode.getObject(); if (ProxyRepositoryFactory.getInstance().getStatus(objectToCopy) == ERepositoryStatus.LOCK_BY_USER) { errorMsg = Messages.getString("RepositoryDropAdapter_lockedByYou"); //$NON-NLS-1$ } if (ProxyRepositoryFactory.getInstance().getStatus(objectToCopy) == ERepositoryStatus.LOCK_BY_OTHER) { errorMsg = Messages.getString("RepositoryDropAdapter_lockedByOthers"); //$NON-NLS-1$ } MessageDialog.openInformation(getViewer().getControl().getShell(), Messages.getString("RepositoryDropAdapter_moveTitle"), //$NON-NLS-1$ errorMsg); //$NON-NLS-1$ setReturnValue(false); return; } ERepositoryObjectType sourceType = (ERepositoryObjectType) repositoryNode .getProperties(EProperties.CONTENT_TYPE); if (sourceType == ERepositoryObjectType.METADATA_CONNECTIONS || sourceType == ERepositoryObjectType.METADATA_FILE_DELIMITED || sourceType == ERepositoryObjectType.METADATA_MDMCONNECTION) { AbstractResourceChangesService resourceChangeService = TDQServiceRegister.getInstance() .getResourceChangeService(AbstractResourceChangesService.class); boolean judgeCanMoveOrNotByDependency = judgeCanMoveOrNotByDependency(repositoryNode, resourceChangeService); if (!judgeCanMoveOrNotByDependency) { setReturnValue(false); return; } } } } // ~TDQ-3545 String moveName = "User action : Move Object"; //$NON-NLS-1$ RepositoryWorkUnit<Object> repositoryWorkUnit = new RepositoryWorkUnit<Object>(moveName, MoveObjectAction.getInstance()) { @Override protected void run() throws LoginException, PersistenceException { final IWorkspaceRunnable op = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { try { for (Object obj : ((StructuredSelection) data).toArray()) { final RepositoryNode sourceNode = (RepositoryNode) obj; monitor.subTask(Messages.getString("RepositoryDropAdapter.moving") + sourceNode.getObject().getLabel()); //$NON-NLS-1$ MoveObjectAction.getInstance().execute(sourceNode, targetNode, true); } } catch (Exception e) { throw new CoreException(new org.eclipse.core.runtime.Status(IStatus.ERROR, FrameworkUtil .getBundle(this.getClass()).getSymbolicName(), "Error", e)); } }; }; IWorkspace workspace = ResourcesPlugin.getWorkspace(); try { ISchedulingRule schedulingRule = workspace.getRoot(); // the update the project files need to be done in the workspace runnable to avoid all // notification // of changes before the end of the modifications. workspace.run(op, schedulingRule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor()); } catch (CoreException e) { throw new PersistenceException(e.getCause()); } } }; ProxyRepositoryFactory.getInstance().executeRepositoryWorkUnit(repositoryWorkUnit); setReturnValue(true); monitor.done(); setReturnValue(true); monitor.done(); } } /** * hqzhang. */ abstract class RunnableWithReturnValue implements IWorkspaceRunnable { public RunnableWithReturnValue(String taskName) { this.taskName = taskName; } private String taskName; private Object returnValue; protected Object getReturnValue() { return this.returnValue; } protected void setReturnValue(Object returnValue) { this.returnValue = returnValue; } protected String getTaskName() { return this.taskName; } protected void setTaskName(String taskName) { this.taskName = taskName; } } }