/*******************************************************************************
* Copyright (c) 2004, 2010 BREDEX GmbH.
* 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:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.client.ui.rcp.handlers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.jubula.client.core.businessprocess.AbstractParamInterfaceBP;
import org.eclipse.jubula.client.core.businessprocess.ParamNameBPDecorator;
import org.eclipse.jubula.client.core.businessprocess.TestCaseParamBP;
import org.eclipse.jubula.client.core.model.IModifiableParameterInterfacePO;
import org.eclipse.jubula.client.core.model.IParamDescriptionPO;
import org.eclipse.jubula.client.core.model.ISpecTestCasePO;
import org.eclipse.jubula.client.core.model.ITestDataCubePO;
import org.eclipse.jubula.client.ui.handlers.AbstractHandler;
import org.eclipse.jubula.client.ui.rcp.dialogs.AbstractEditParametersDialog.Parameter;
import org.eclipse.jubula.client.ui.rcp.editors.IJBEditor;
import org.eclipse.jubula.client.ui.rcp.i18n.Messages;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.exception.Assert;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* @author BREDEX GmbH
* @created Jul 14, 2010
*/
public abstract class AbstractEditParametersHandler extends AbstractHandler {
/**
*
* @param event The execution event containing the context in which the
* receiver was executed.
* @return the editor on which the receiver should operate.
*/
protected IJBEditor getEditor(ExecutionEvent event) {
// Use activePart rather than activeEditor because we want to make sure
// that the editor is the active part. It is possible, for example, for
// an editor to be the active editor (editor label is rendered with
// a different background color than the labels for the other editors)
// even though it is *not* the active part because a view is currently
// active (view's label is highlighted).
final IWorkbenchPart activeEditor = HandlerUtil.getActivePart(event);
if (activeEditor != null) {
final Object adapter =
activeEditor.getAdapter(IJBEditor.class);
if (adapter != null) {
return (IJBEditor)adapter;
}
}
return null;
}
/**
* Gets the new index of the Parameter with the given paramDesc.
* @param paramDesc the paramDesc
* @param paramList the List of Parameters
* @return the zero based index or -1 if not found.
*/
protected static int getNewParamIndex(IParamDescriptionPO paramDesc,
List<Parameter> paramList) {
// 1. search for GUID
for (int i = 0; i < paramList.size(); i++) {
String paramGuid = paramList.get(i).getGuid();
if ((paramGuid != null)
&& (paramGuid.equals(paramDesc.getUniqueId()))) {
return i;
}
}
// 2. search for same name
for (int i = 0; i < paramList.size(); i++) {
if (paramList.get(i).getName().equals(paramDesc.getName())) {
return i;
}
}
return -1;
}
/**
* @param <T> The type of the main persistence object to modify, e.g.
* {@link ISpecTestCase} or {@link ITestDataCubePO}
* @param paramIntObj
* the {@link IModifiableParameterInterfacePO} which is to modify.
* @param parameters
* the
* {@link org.eclipse.jubula.client.ui.rcp.dialogs.EditParametersDialog.Parameter}
* .
* @param isInterfaceLocked
* the Lock Interface flag
* @param mapper
* for management of param names
* @param paramInterfaceBP
* the param interface business process to use for model changes
* @return if occurs any modification of parameters
*/
protected static
<T extends IModifiableParameterInterfacePO> boolean editParameters(
T paramIntObj,
List<Parameter> parameters,
boolean isInterfaceLocked,
ParamNameBPDecorator mapper,
AbstractParamInterfaceBP<T> paramInterfaceBP) {
Map<String, IParamDescriptionPO> oldParamsMap =
createOldParamsMap(paramIntObj);
// find new parameters
List<Parameter> paramsToAdd = new ArrayList<Parameter>();
List<Parameter> params = new ArrayList<Parameter>(parameters);
for (Parameter parameter : parameters) {
if (parameter.getGuid() == null) {
paramsToAdd.add(parameter);
params.remove(parameter);
}
}
// Find renamed parameters and parameters, which changed the usage,
// if they have the same new name.
Map<IParamDescriptionPO, String> paramsToRename =
new HashMap<IParamDescriptionPO, String>();
Map<IParamDescriptionPO, String> paramsToChangeUsage =
new HashMap<IParamDescriptionPO, String>();
for (Parameter param : params) {
IParamDescriptionPO paramDescr = oldParamsMap.get(param.getGuid());
if (paramDescr != null) {
if (!(paramDescr.getName().equals(param.getName()))) {
Parameter paramNotRenamed = getNotRenamedParamWithSameName(
oldParamsMap, params, param);
if (paramNotRenamed == null) {
// rename the first usage
paramsToRename.put(paramDescr, param.getName());
} else {
// change the usage to the first parameter with the same name
paramsToChangeUsage.put(paramDescr,
paramNotRenamed.getGuid());
}
}
} else {
Assert.notReached(Messages.UnexpectedError
+ StringConstants.COLON + StringConstants.SPACE
+ Messages.ModificationOfNonExistingParameter
+ StringConstants.DOT);
}
}
// find parameters to remove
List<IParamDescriptionPO> paramsToRemove = findParamsToRemove(
parameters, oldParamsMap);
boolean isInterfaceLockedChanged = false;
ISpecTestCasePO specTc = null;
if (paramIntObj instanceof ISpecTestCasePO) {
specTc = (ISpecTestCasePO)paramIntObj;
isInterfaceLockedChanged = !((specTc).isInterfaceLocked()
== isInterfaceLocked);
TestCaseParamBP.setInterfaceLocked(specTc, isInterfaceLocked);
}
// update model
updateModel(paramIntObj, mapper, paramInterfaceBP, paramsToAdd,
paramsToRename, paramsToChangeUsage, paramsToRemove);
final boolean moved = moveParameters(paramIntObj, parameters);
// changes have been made, if one or more lists/maps are not empty
return !paramsToRemove.isEmpty()
|| !paramsToAdd.isEmpty()
|| !paramsToRename.isEmpty()
|| !paramsToChangeUsage.isEmpty()
|| moved
|| isInterfaceLockedChanged;
}
/**
* Notify the abstract parameter interface BP of the calculated parameters,
* which are new, removed, renamed or the usage have been changed.
* @param <T> The type of the node working at.
* @param paramIntObj The node working at.
* @param mapper The parameter name mapping.
* @param paramInterfaceBP The parameter interface BP.
* @param paramsToAdd The list of parameters to add.
* @param paramsToRename The map of renamed parameters.
* @param paramsToChangeUsage The map of changed parameters.
* @param paramsToRemove The list of removed parameter descriptions.
*/
private static <T extends IModifiableParameterInterfacePO> void updateModel(
T paramIntObj, ParamNameBPDecorator mapper,
AbstractParamInterfaceBP<T> paramInterfaceBP,
List<Parameter> paramsToAdd,
Map<IParamDescriptionPO, String> paramsToRename,
Map<IParamDescriptionPO, String> paramsToChangeUsage,
List<IParamDescriptionPO> paramsToRemove) {
// add
for (Parameter addParam : paramsToAdd) {
paramInterfaceBP.addParameter(addParam.getName(), addParam
.getType(), paramIntObj, mapper);
}
// remove
for (IParamDescriptionPO desc : paramsToRemove) {
paramInterfaceBP.removeParameter(desc, paramIntObj);
}
// rename
for (IParamDescriptionPO desc : paramsToRename.keySet()) {
paramInterfaceBP.renameParameters(
desc, paramsToRename.get(desc), mapper);
}
// usage changed
for (IParamDescriptionPO desc : paramsToChangeUsage.keySet()) {
paramInterfaceBP.changeUsageParameter(paramIntObj,
desc, paramsToChangeUsage.get(desc), mapper);
}
}
/**
* @param parameters The list of new parameters.
* @param oldParams The map of old parameter GUIDs to
* their parameter description.
* @return The list of parameter descriptions to be removed.
*/
private static List<IParamDescriptionPO> findParamsToRemove(
List<Parameter> parameters,
Map<String, IParamDescriptionPO> oldParams) {
List<String> oldGuids = new ArrayList<String>(oldParams.keySet());
for (Parameter parameter : parameters) {
oldGuids.remove(parameter.getGuid());
}
List<IParamDescriptionPO> paramsToRemove =
new ArrayList<IParamDescriptionPO>();
for (String oldGuid : oldGuids) {
paramsToRemove.add(oldParams.get(oldGuid));
}
return paramsToRemove;
}
/**
* @param paramIntObj The node working on.
* @return The map of parameter description UUIDs to it parameter description.
*/
private static Map<String, IParamDescriptionPO> createOldParamsMap(
IModifiableParameterInterfacePO paramIntObj) {
Map<String, IParamDescriptionPO> oldParams =
new HashMap<String, IParamDescriptionPO>();
List<IParamDescriptionPO> paramList = paramIntObj.getParameterList();
for (IParamDescriptionPO oldDesc : paramList) {
oldParams.put(oldDesc.getUniqueId(), oldDesc);
}
return oldParams;
}
/**
* @param oldParamsMap The map of GUIDs to old parameter descriptions.
* @param params The list of new parameters.
* @param param The parameter searching for in the list.
* @return The first different not renamed parameter with the same name
* as the given parameter, or null, if it has not been found.
*/
private static Parameter getNotRenamedParamWithSameName(
Map<String, IParamDescriptionPO> oldParamsMap,
List<Parameter> params,
Parameter param) {
for (Parameter paramSearch : params) {
if (paramSearch != param) {
IParamDescriptionPO oldParam =
oldParamsMap.get(paramSearch.getGuid());
if (oldParam.getName().equals(param.getName())) {
return paramSearch;
}
}
}
return null;
}
/**
* Moves the Parameters of the given IModifiableParameterInterfacePO into
* the order of the given parameter List (parameters).<br>
* <b>Note: Call this method after all other model changes!</b>
*
* @param paramIntObj
* the IParameterInterfacePO.
* @param parameters
* the Parameter List with the new order.
* @return true if oe or more parameters were moved, false otherwise.
*/
private static boolean moveParameters(
IModifiableParameterInterfacePO paramIntObj,
List<Parameter> parameters) {
boolean moved = false;
final List<IParamDescriptionPO> paramList =
new LinkedList<IParamDescriptionPO>(
paramIntObj.getParameterList());
for (IParamDescriptionPO paramDesc : paramList) {
final int currIdx = paramList.indexOf(paramDesc);
final int newIdx = getNewParamIndex(paramDesc, parameters);
if (currIdx != newIdx) {
paramIntObj.moveParameter(paramDesc.getUniqueId(), newIdx);
moved = true;
}
}
return moved;
}
/**
* @param paramIntObj
* the {@link IModifiableParameterInterfacePO} which is to
* modify.
* @param parameters
* the
* {@link org.eclipse.jubula.client.ui.rcp.dialogs.EditParametersDialog.Parameter}
* .
* @param mapper
* for management of param names
* @param paramInterfaceBP
* the param interface business process to use for model changes
* @return if occurs any modification of parameters
*/
public static boolean editParameters(
ITestDataCubePO paramIntObj,
List<Parameter> parameters, ParamNameBPDecorator mapper,
AbstractParamInterfaceBP<ITestDataCubePO> paramInterfaceBP) {
return editParameters(paramIntObj, parameters, false, mapper,
paramInterfaceBP);
}
}