// ============================================================================ // // Copyright (C) 2006-2016 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.dataprofiler.core.ui.dialog.message; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.common.util.EList; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.talend.core.model.properties.Property; import org.talend.core.model.repository.ERepositoryObjectType; import org.talend.dataprofiler.core.i18n.internal.DefaultMessagesImpl; import org.talend.dataquality.analysis.Analysis; import org.talend.dq.helper.EObjectHelper; import org.talend.dq.helper.PropertyHelper; import org.talend.dq.helper.ProxyRepositoryManager; import org.talend.dq.helper.RepositoryNodeHelper; import org.talend.repository.model.IRepositoryNode; import orgomg.cwm.objectmodel.core.Dependency; import orgomg.cwm.objectmodel.core.ModelElement; /** * DOC rli class global comment. Detailled comment */ public class DeleteModelElementConfirmDialog { private static final String REQUIRES = "requires"; //$NON-NLS-1$ private static LabelProvider fLabelProvider; private static List<ImpactNode> impactNodes = new ArrayList<ImpactNode>(); /** * DOC rli DeleteModelElementConfirmDialog class global comment. Detailled comment */ static class ImpactNode { List<Object> children = new ArrayList<Object>(); private ModelElement nodeElement = null; private IRepositoryNode node = null; /** * Getter for node. * * @return the node */ public IRepositoryNode getNode() { return this.node; } /** * Sets the node. * * @param node the node to set */ public void setNode(IRepositoryNode node) { this.node = node; } public ImpactNode(ModelElement modelElement) { this.nodeElement = modelElement; } /** * DOC yyin ImpactNode constructor comment. * * @param node */ public ImpactNode(IRepositoryNode node) { this.node = node; } public void addRequireModelElement(Object object) { if (!children.contains(object)) { this.children.add(object); } } public Object[] getChildren() { return children.toArray(new Object[children.size()]); } @Override public String toString() { if (this.nodeElement != null) { return nodeElement.getName(); } else { return this.node.getObject().getLabel(); } } /** * Getter for nodeElement. * * @return the nodeElement */ public ModelElement getNodeElement() { return nodeElement; } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((nodeElement == null) ? 0 : nodeElement.hashCode()); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ImpactNode other = (ImpactNode) obj; if (nodeElement == null) { if (other.nodeElement != null) { return false; } } else if (nodeElement.getName() == other.nodeElement.getName()) { return true; } else if (!nodeElement.getName().equals(other.nodeElement.getName())) { return false; } return true; } } static void addDenpendencyElements(ModelElement[] children) { for (ModelElement element : children) { EList<Dependency> supplierDependencies = element.getSupplierDependency(); ImpactNode impactNode; for (Dependency dependency : supplierDependencies) { EList<ModelElement> clients = dependency.getClient(); for (ModelElement client : clients) { // ~MOD mzhao feature 7488 2009-08-21. // if (DependenciesHandler.isTDQElementProperties(client)) { // continue; // } // ~ if (!client.eIsProxy()) { impactNode = new ImpactNode(client); int index = impactNodes.indexOf(impactNode); if (index == -1) { impactNode.addRequireModelElement(element); impactNodes.add(impactNode); } else { ImpactNode existNode = impactNodes.get(index); existNode.addRequireModelElement(element); } } } } } } static ImpactNode[] getImpactNodes() { return impactNodes.toArray(new ImpactNode[impactNodes.size()]); } static void clear() { impactNodes.clear(); } /** * DOC rli RequirsResourceConfirmDialog class global comment. Detailled comment */ protected static class DialogContentProvider implements ITreeContentProvider { ImpactNode[] treeNode; DialogContentProvider(ImpactNode[] treeNode) { this.treeNode = treeNode; } public Object[] getChildren(Object parentElement) { if (parentElement instanceof ImpactNode) { return ((ImpactNode) parentElement).getChildren(); } return null; } public Object getParent(Object element) { return null; } public boolean hasChildren(Object element) { return element instanceof ImpactNode; } public Object[] getElements(Object inputElement) { return treeNode; } public void dispose() { // do nothing here ??? } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // do nothing here ??? } } /** * DOC bZhou Comment method "showDialog". * * @param parentShell * @param file * @param dependencyElements * @param dialogMessage * @return */ public static boolean showDialog(Shell parentShell, Object obj, ModelElement[] dependencyElements, String dialogMessage, boolean isNeedCheckbox) { // MOD qiongli 2011-3-1 feature 17588.return boolean,add 'dialog.setNeedCheckbox(true)' for (ModelElement element : dependencyElements) { ImpactNode node = new ImpactNode(element); if (!impactNodes.contains(node)) { node.addRequireModelElement(obj); impactNodes.add(node); } } ImpactNode[] impactElements = getImpactNodes(); boolean isChecked = false; if (impactElements.length > 0) { TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(parentShell, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.confirmResourceDelete"), null, dialogMessage, //$NON-NLS-1$ MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL }, 1); dialog.setNeedCheckbox(isNeedCheckbox); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); // MOD qiongli 2012-1-6 if don't click OK button,should return false; int result = dialog.open(); isChecked = dialog.isChecked() && (result == Window.OK); } return isChecked; } /** * * DOC qiongli Comment method "showDialog". * * @param parentShell * @param repositoryNodes * @param dependencyElements * @param dialogMessage * @return */ public static int showDialog(Shell parentShell, List<IRepositoryNode> repositoryNodes, String dialogMessage) { for (IRepositoryNode repNode : repositoryNodes) { List<ModelElement> dependencies = EObjectHelper.getDependencyClients(repNode); Object object = RepositoryNodeHelper.getModelElementFromRepositoryNode(repNode); for (ModelElement element : dependencies) { ImpactNode node = new ImpactNode(element); if (!impactNodes.contains(node)) { node.addRequireModelElement(object); impactNodes.add(node); } else if (!Arrays.asList(node.getChildren()).contains(object)) { int index = impactNodes.indexOf(node); if (index != -1) { impactNodes.get(index).addRequireModelElement(object); } } } } ImpactNode[] impactElements = getImpactNodes(); if (impactElements.length > 0) { TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(parentShell, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.confirmResourceDelete"), null, dialogMessage, //$NON-NLS-1$ MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL }, 1); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); return dialog.open(); } return Window.CANCEL; } /** * DOC bzhou Comment method "showConfirmDialog". * * @param parentShell * @param obj * @param dependencyElements * @param dialogMessage * @return */ public static int showConfirmDialog(Shell parentShell, Object obj, ModelElement[] dependencyElements, String dialogTitle, String dialogMessage) { for (ModelElement element : dependencyElements) { ImpactNode node = new ImpactNode(element); if (!impactNodes.contains(node)) { node.addRequireModelElement(obj); impactNodes.add(node); } } ImpactNode[] impactElements = getImpactNodes(); if (impactElements.length > 0) { TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(parentShell, dialogTitle, null, dialogMessage, MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); return dialog.open(); } return Window.OK; } /** * DOC rli Comment method "showDialog". * * @param parentShell * @param modelElements * @param dialogMessage * @return */ public static int showDialog(Shell parentShell, ModelElement[] modelElements, String dialogMessage) { addDenpendencyElements(modelElements); ImpactNode[] impactElements = getImpactNodes(); if (impactElements.length > 0) { TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(parentShell, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.confirmResourceDelete"), null, dialogMessage, //$NON-NLS-1$ MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL }, 1); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); dialog.open(); return Window.CANCEL; } else { return popConfirmDialog(modelElements); } } /** * * MOD mzhao 2009-03-26, Impact existing analyses when copy remote structure from remote to local on comparison * editor. * * @param parentShell * @param modelElements * @param dialogMessage * @return */ public static int showElementImpactDialog(Shell parentShell, ModelElement[] modelElements, String dialogTitle, String dialogMessage) { addDenpendencyElements(modelElements); ImpactNode[] impactElements = getImpactNodes(); if (impactElements.length > 0) { TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(parentShell, dialogTitle, null, dialogMessage, MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL }, 0); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); int result = dialog.open(); return result; } else { return Window.OK; } } public static int showElementImpactConfirmDialog(Shell parentShell, ModelElement[] modelElements, String dialogTitle, String dialogMessage) { addDenpendencyElements(modelElements); ImpactNode[] impactElements = getImpactNodes(); if (impactElements.length > 0) { TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(parentShell, dialogTitle, null, dialogMessage, MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); int result = dialog.open(); return result; } else { return Window.OK; } } private static int popConfirmDialog(ModelElement[] modelElements) { MessageDialog messageDialog; if (modelElements.length > 1) { messageDialog = new MessageDialog( null, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.confirmResourceDelete"), null, //$NON-NLS-1$ DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.deleleTheseResources"), MessageDialog.WARNING, new String[] { //$NON-NLS-1$ IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); } else { messageDialog = new MessageDialog( null, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.confirmResourcesDelete"), null, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.areYouDelele", modelElements[0].getName()) //$NON-NLS-1$ //$NON-NLS-2$ , MessageDialog.WARNING, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); } return messageDialog.open(); } /** * show all nodes with its dependencies (in nodeWithDependsMap) in one dialog. if the dependency has its own * depends, also show them under this dependsency * * @param nodeWithDependsMap key is the repostiory node and value is the dependencies of this node. * @param dialogMessage the message shown in dialog * @param needCheckBox show the check box or not * @return true if the user choose force delete, false if the user did not choose force delete */ public static boolean showDialog(Map<IRepositoryNode, List<ModelElement>> nodeWithDependsMap, String dialogMessage, boolean needCheckBox) { // for each node in the map, add the node as a ImpactNode, and its children are its depends. Iterator iter = nodeWithDependsMap.entrySet().iterator(); List<ModelElement> lockedByOthersList = new ArrayList<ModelElement>(); while (iter.hasNext()) { Map.Entry<IRepositoryNode, List<ModelElement>> entry = (Map.Entry<IRepositoryNode, List<ModelElement>>) iter.next(); IRepositoryNode node = entry.getKey(); List<ModelElement> dependencies = entry.getValue(); addDenpendencyElements(node, dependencies); findLockedByOthersModelElement(lockedByOthersList, dependencies); } ImpactNode[] impactElements = getImpactNodes(); boolean isChecked = false; // show the dialog if (impactElements.length > 0) { boolean lockedByOthersFlag = !lockedByOthersList.isEmpty(); String message = lockedByOthersFlag ? DefaultMessagesImpl.getString("DQDeleteAction.lockedByOthers") : dialogMessage; //$NON-NLS-1$ String[] buttonLabels = lockedByOthersFlag ? new String[] {} : new String[] { IDialogConstants.OK_LABEL }; TreeMessageInfoDialog dialog = new TreeMessageInfoDialog(null, DefaultMessagesImpl.getString("DeleteModelElementConfirmDialog.confirmResourceDelete"), null, message, //$NON-NLS-1$ MessageDialog.WARNING, buttonLabels, 1); dialog.setNeedCheckbox(lockedByOthersFlag ? false : needCheckBox); dialog.setContentProvider(new DialogContentProvider(impactElements)); dialog.setInput(new Object()); clear(); // MOD qiongli 2012-1-6 if don't click OK button,should return false; int result = dialog.open(); isChecked = dialog.isChecked() && (result == Window.OK); } return isChecked; } /** * it the ModelElement is locked by others, add it into lockedByOthers. * * @param lockedByOthers * @param dependencies */ private static void findLockedByOthersModelElement(List<ModelElement> lockedByOthers, List<ModelElement> dependencies) { for (ModelElement me : dependencies) { if (lockedByOthers(me)) { lockedByOthers.add(me); } } } /** * if the ModelElement locked by others return true, else return false. * * @param me ModelElement * @return */ private static boolean lockedByOthers(ModelElement me) { boolean result = false; Property property = PropertyHelper.getProperty(me); if (property != null) { result = ProxyRepositoryManager.getInstance().isLockByOthers(property.getItem()); } return result; } /** * The first level node is (connection, DQ rule, Pattern), the second level is analysis, Jrxml, the third is report * only for analysis , need to check if there are some reports depends on this analysis and list them if any. * * @param node * @param dependencies */ private static void addDenpendencyElements(IRepositoryNode node, List<ModelElement> dependencies) { ImpactNode impactNode; // if node is a jrxml if (ERepositoryObjectType.TDQ_JRAXML_ELEMENT.equals(node.getObject().getRepositoryObjectType())) { impactNode = new ImpactNode(node); } else { impactNode = new ImpactNode(RepositoryNodeHelper.getModelElementFromRepositoryNode(node)); } for (ModelElement element : dependencies) { // only for analysis if (element instanceof Analysis) { List<ModelElement> dependReports = EObjectHelper.getDependencyClients(element); if (dependReports.size() > 0) { ImpactNode anaNode = new ImpactNode(element); for (ModelElement report : dependReports) { anaNode.addRequireModelElement(report); } // impactNodes.add(anaNode); impactNode.addRequireModelElement(anaNode); } else { impactNode.addRequireModelElement(element); } } else { impactNode.addRequireModelElement(element); } } impactNodes.add(impactNode); } }