/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.mapping.ui.actions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchPart;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.mapping.ui.UiConstants;
import org.teiid.designer.mapping.ui.UiPlugin;
import org.teiid.designer.mapping.ui.diagram.MappingDiagramUtil;
import org.teiid.designer.metamodels.transformation.MappingClass;
import org.teiid.designer.ui.common.eventsupport.SelectionUtilities;
import org.teiid.designer.ui.editors.ModelEditor;
/**
* @since 8.0
*/
public class MergeMappingClassesAction extends MappingAction {
private static final String ACTION_DESCRIPTION = "Merge Mapping Classes"; //$NON-NLS-1$
private static final String MERGE_MAPPING_CLASSES_ERROR = "MergeMappingClassesAction: Error merging mapping classes. Object = "; //$NON-NLS-1$
public MergeMappingClassesAction() {
super();
setImageDescriptor(UiPlugin.getDefault().getImageDescriptor(UiConstants.Images.MERGE_MAPPING_CLASSES));
}
/**
* @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
*/
@Override
public void selectionChanged( IWorkbenchPart thePart,
ISelection theSelection ) {
super.selectionChanged(thePart, theSelection);
determineEnablement();
}
/**
* @see org.eclipse.jface.action.IAction#run()
*/
@Override
protected void doRun() {
if (getMappingClassFactory() != null) {
mergeWithProgress();
}
setEnabled(false);
}
private boolean mergeWithProgress() {
boolean success = false;
final IRunnableWithProgress op = new IRunnableWithProgress() {
@Override
public void run( final IProgressMonitor monitor ) {
Object[] mcArray = getOrderedSelectedMappingClasses();
printMCArray(mcArray);
int nWork = 10 * mcArray.length;
monitor.beginTask("Merging Mapping Classes", nWork); //$NON-NLS-1$
mergeMultiple(mcArray, monitor);
}
};
try {
final ProgressMonitorDialog dlg = new ProgressMonitorDialog(getPlugin().getCurrentWorkbenchWindow().getShell());
dlg.setCancelable(false);
dlg.run(false, true, op);
if (dlg.getProgressMonitor().isCanceled()) {
return true;
}
success = true;
} catch (final InterruptedException ignored) {
success = true;
} catch (final Exception err) {
success = false;
}
return success;
}
void mergeMultiple( final Object[] mcArray,
IProgressMonitor monitor ) {
boolean canUndo = IMappingDiagramActionConstants.DiagramActions.UNDO_MERGE_MAPPING_CLASSES;
boolean removeDuplicateAttributes = ModelerCore.getTransformationPreferences().getRemoveDuplicateAttibutes();
// start txn
boolean requiredStart = ModelerCore.startTxn(true, canUndo, ACTION_DESCRIPTION, this);
boolean succeeded = false;
MappingClass firstMC = (MappingClass)mcArray[0];
MappingClass secondMC = null;
try {
String progressMessage = null;
int nMCs = mcArray.length;
for (int i = 1; i < nMCs; i++) {
secondMC = (MappingClass)mcArray[i];
progressMessage = "Merging " + (i + 1) + " of " + nMCs + ": Name = " + secondMC.getName(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
monitor.subTask(progressMessage);
monitor.worked(10);
// Do the work
// System.out.println("\n ACTION ------- Message = " + progressMessage);
getMappingClassFactory().mergeMappingClasses(firstMC, secondMC, removeDuplicateAttributes);
}
succeeded = true;
} catch (ModelerCoreException e) {
String message = MERGE_MAPPING_CLASSES_ERROR + firstMC.toString();
UiConstants.Util.log(IStatus.ERROR, e, message);
} finally {
if (requiredStart) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
}
private boolean enableForMultiple() {
if (this.getPart() instanceof ModelEditor && multipleMappingClassesSelected()) {
Object[] mcArray = getOrderedSelectedMappingClasses();
// Now we need to walk through all the mapping classes two by two and check "can Merge"
// For each mapping class 1....n, check if can merge from j, through 0. If we find ONE, then it can
// merge, if we find NONE, then we can't.
MappingClass firstMC = null;
MappingClass secondMC = null;
boolean canMerge = true;
for (int i = 1; i < mcArray.length; i++) {
for (int j = i - 1; j >= 0; j--) {
firstMC = (MappingClass)mcArray[j];
secondMC = (MappingClass)mcArray[i];
canMerge = getMappingClassFactory().canMergeMappingClasses(firstMC, secondMC);
if (canMerge) return true;
}
}
}
return false;
}
Object[] getOrderedSelectedMappingClasses() {
// Need to order the list of selected mapping classes
List allOrderedMCs = MappingDiagramUtil.getOrderedCoarseMappingClasses();
List selectedMCs = SelectionUtilities.getSelectedEObjects(getSelection());
List orderedSelectedMCs = new ArrayList(selectedMCs.size());
// Now we need to order the selected mapping classes
EObject nextMC = null;
// Walk through the allOrderedMCs, and if an MC exists in selectedMCs, add it to the final list
for (Iterator iter = allOrderedMCs.iterator(); iter.hasNext();) {
nextMC = (EObject)iter.next();
if (selectedMCs.contains(nextMC)) {
orderedSelectedMCs.add(nextMC);
}
}
return orderedSelectedMCs.toArray();
}
private void determineEnablement() {
setEnabled(enableForMultiple());
}
private boolean multipleMappingClassesSelected() {
if (SelectionUtilities.isMultiSelection(getSelection()) && isWritable()) {
List selectedEObjects = SelectionUtilities.getSelectedEObjects(getSelection());
if (selectedEObjects.size() > 1) {
EObject eObj = null;
for (Iterator iter = selectedEObjects.iterator(); iter.hasNext();) {
eObj = (EObject)iter.next();
if (isStagingTable(eObj) || !isMappingClass(eObj)) return false;
}
return true;
}
}
return false;
}
@Override
public String toString() {
return "MergeMappingClassesAction[]"; //$NON-NLS-1$
}
void printMCArray( Object[] mcArray ) {
}
}