/******************************************************************************* * Copyright (c) 2004, 2011 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.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jubula.client.core.businessprocess.ParamNameBP; import org.eclipse.jubula.client.core.businessprocess.ParamNameBPDecorator; import org.eclipse.jubula.client.core.events.DataEventDispatcher; import org.eclipse.jubula.client.core.events.DataEventDispatcher.DataState; import org.eclipse.jubula.client.core.events.DataEventDispatcher.UpdateState; import org.eclipse.jubula.client.core.model.ICapPO; import org.eclipse.jubula.client.core.model.ICommentPO; import org.eclipse.jubula.client.core.model.ICompNamesPairPO; import org.eclipse.jubula.client.core.model.IControllerPO; import org.eclipse.jubula.client.core.model.IExecTestCasePO; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.IParamDescriptionPO; import org.eclipse.jubula.client.core.model.IParamNodePO; import org.eclipse.jubula.client.core.model.IPersistentObject; import org.eclipse.jubula.client.core.model.ISpecTestCasePO; import org.eclipse.jubula.client.core.model.NodeMaker; import org.eclipse.jubula.client.core.model.PoMaker; import org.eclipse.jubula.client.core.model.TDCell; import org.eclipse.jubula.client.core.persistence.TransactionSupport.ITransaction; import org.eclipse.jubula.client.core.persistence.GeneralStorage; import org.eclipse.jubula.client.core.persistence.PMException; import org.eclipse.jubula.client.core.utils.ModelParamValueConverter; import org.eclipse.jubula.client.core.utils.NativeSQLUtils; import org.eclipse.jubula.client.core.utils.RefToken; import org.eclipse.jubula.client.ui.rcp.actions.TransactionWrapper; import org.eclipse.jubula.client.ui.rcp.controllers.MultipleTCBTracker; import org.eclipse.jubula.client.ui.rcp.views.TestCaseBrowser; /** * @author Markus Tiede * @since 1.2 */ public class SaveAsNewTestCaseHandler extends AbstractRefactorHandler { /** * @author Markus Tiede * @since 1.2 */ private static class CloneTransaction implements ITransaction { /** * the name of the new test case */ private final String m_newTestCaseName; /** * the param nodes to clone */ private final List<INodePO> m_nodesToClone; /** * the new spec test case */ private ISpecTestCasePO m_newSpecTC = null; /** The editor root node */ private IPersistentObject m_oldRoot = null; /** * Constructor * * @param newTestCaseName * the name of the new test case * @param nodesToClone * the param nodes to clone */ public CloneTransaction(String newTestCaseName, List<INodePO> nodesToClone) { m_newTestCaseName = newTestCaseName; m_nodesToClone = nodesToClone; m_oldRoot = m_nodesToClone.get(0).getSpecAncestor(); } /** {@inheritDoc} */ public void run(EntityManager s) throws PMException { ISpecTestCasePO newTc = NodeMaker .createSpecTestCasePO(m_newTestCaseName); final ParamNameBPDecorator pMapper = new ParamNameBPDecorator( ParamNameBP.getInstance()); s.persist(newTc); Map<String, String> oldToNewGuids = new HashMap<String, String>(); for (INodePO node : m_nodesToClone) { addCloneToNode(newTc, node, pMapper, oldToNewGuids, newTc); } registerParamNamesToSave(newTc, pMapper); s.merge(newTc); pMapper.persist(s, GeneralStorage.getInstance().getProject() .getId()); NativeSQLUtils.addNodeAFFECTS(s, newTc, GeneralStorage.getInstance().getProject().getSpecObjCont()); setNewSpecTC(newTc); } /** * @param addTo * the node to add to * @param nodeToCopy * the param node to clone and add * @param pMapper the param name mapper * @param oldToNewGuids the old to new guid map * @param specTC the top-level specTC for the params * @throws PMException in case of an persitence exception */ private void addCloneToNode(INodePO addTo, INodePO nodeToCopy, ParamNameBPDecorator pMapper, Map<String, String> oldToNewGuids, ISpecTestCasePO specTC) throws PMException { INodePO newNode = null; if (nodeToCopy instanceof IExecTestCasePO) { IExecTestCasePO origExec = (IExecTestCasePO) nodeToCopy; IExecTestCasePO newExec = NodeMaker.createExecTestCasePO( origExec.getSpecTestCase()); fillExec(origExec, newExec); newNode = newExec; } else if (nodeToCopy instanceof ICapPO) { ICapPO origCap = (ICapPO) nodeToCopy; ICapPO newCap = NodeMaker.createCapPO( origCap.getName(), origCap.getComponentName(), origCap.getComponentType(), origCap.getActionName()); fillCap(origCap, newCap); newNode = newCap; } else if (nodeToCopy instanceof ICommentPO) { ICommentPO origComment = (ICommentPO) nodeToCopy; ICommentPO newComment = NodeMaker.createCommentPO( origComment.getName()); newNode = newComment; } else if (nodeToCopy instanceof IControllerPO) { newNode = NodeMaker.createControllerPO( (IControllerPO) nodeToCopy); int i = 0; for (INodePO node : nodeToCopy.getUnmodifiableNodeList()) { for (INodePO node2 : node.getUnmodifiableNodeList()) { addCloneToNode(newNode.getUnmodifiableNodeList().get(i), node2, pMapper, oldToNewGuids, specTC); } i++; } } if (newNode != null) { if (newNode instanceof IParamNodePO) { addParamsToSpec(specTC, (IParamNodePO) newNode, pMapper, oldToNewGuids); } addTo.addNode(newNode); } } /** * @param newSpecTC * the new parent to modify * @param newParamChildNode * the new param child node * @param pMapper * the param name mapper * @param oldToNewUuids * the old to new guids map */ private void addParamsToSpec(ISpecTestCasePO newSpecTC, IParamNodePO newParamChildNode, ParamNameBPDecorator pMapper, Map<String, String> oldToNewUuids) { TDCell cell = null; for (Iterator<TDCell> it = newParamChildNode .getParamReferencesIterator(); it.hasNext();) { cell = it.next(); String guid = newParamChildNode.getDataManager() .getUniqueIds().get(cell.getCol()); IParamDescriptionPO childDesc = newParamChildNode .getParameterForUniqueId(guid); // The childDesc can be null if the parameter has been // removed in another session and not yet updated in the // current editor session. if (childDesc != null) { ModelParamValueConverter conv = new ModelParamValueConverter( cell.getTestData(), newParamChildNode, childDesc); List<RefToken> refTokens = conv.getRefTokens(); for (RefToken refToken : refTokens) { String oldUuid = RefToken.extractCore(refToken .getModelString()); String paramName = ParamNameBP.getInstance() .getName(oldUuid, childDesc.getParentProjectId()); IParamDescriptionPO parentParamDescr = newSpecTC .addParameter(childDesc.getType(), paramName, false, pMapper); if (parentParamDescr != null) { String newUuid = parentParamDescr.getUniqueId(); oldToNewUuids.put(oldUuid, newUuid); } // update test data of child with UUID for reference conv.replaceUuidsInReferences(oldToNewUuids); cell.setTestData(conv.getModelString()); } } } } /** * @param origCap * the source * @param newCap * the target */ private void fillCap(ICapPO origCap, ICapPO newCap) { newCap.setActive(origCap.isActive()); newCap.setComment(origCap.getComment()); newCap.setGenerated(origCap.isGenerated()); newCap.setToolkitLevel(origCap.getToolkitLevel()); origCap.getDataManager().deepCopy( newCap.getDataManager()); } /** * @param origExec * the source * @param newExec * the target */ private void fillExec(IExecTestCasePO origExec, IExecTestCasePO newExec) { newExec.setActive(origExec.isActive()); newExec.setComment(origExec.getComment()); newExec.setDataFile(origExec.getDataFile()); newExec.setGenerated(origExec.isGenerated()); ISpecTestCasePO origSpecTC = origExec.getSpecTestCase(); if (!origExec.getName().equals( origSpecTC.getName())) { newExec.setName(origExec.getName()); } newExec.setToolkitLevel(origExec.getToolkitLevel()); if (!origExec.getDataManager().equals( origSpecTC.getDataManager())) { newExec.setHasReferencedTD(false); origExec.getDataManager().deepCopy( newExec.getDataManager()); } else { newExec.setHasReferencedTD(true); } newExec.setReferencedDataCube(origExec.getReferencedDataCube()); for (ICompNamesPairPO origPair : origExec.getCompNamesPairs()) { ICompNamesPairPO newPair = PoMaker.createCompNamesPairPO( origPair.getFirstName(), origPair.getSecondName(), origPair.getType()); newPair.setPropagated(origPair.isPropagated()); newExec.addCompNamesPair(newPair); } } /** * @return the m_newSpecTC */ public ISpecTestCasePO getNewSpecTC() { return m_newSpecTC; } /** * @param newSpecTC the m_newSpecTC to set */ public void setNewSpecTC(ISpecTestCasePO newSpecTC) { m_newSpecTC = newSpecTC; } /** {@inheritDoc} */ public Collection<? extends IPersistentObject> getToLock() { List<IPersistentObject> list = new ArrayList<>(); list.add(GeneralStorage.getInstance().getProject(). getSpecObjCont()); list.add(m_oldRoot); return list; } /** {@inheritDoc} */ public Collection<? extends IPersistentObject> getToRefresh() { List<IPersistentObject> list = new ArrayList<>(); list.add(GeneralStorage.getInstance().getProject(). getSpecObjCont()); return list; } /** {@inheritDoc} */ public Collection<? extends IPersistentObject> getToMerge() { List<IPersistentObject> toMerge = new ArrayList<>(); toMerge.add(m_newSpecTC); return toMerge; } } /** {@inheritDoc} */ public Object executeImpl(ExecutionEvent event) { String newTestCaseName = getNewTestCaseName(event); if (newTestCaseName != null) { ISpecTestCasePO newSpecTC = null; IStructuredSelection ss = getSelection(); final List<INodePO> nodesToClone = new ArrayList<INodePO>(ss.size()); Iterator it = ss.iterator(); while (it.hasNext()) { nodesToClone.add((INodePO) it.next()); } newSpecTC = createAndPerformNodeDuplication(newTestCaseName, nodesToClone); if (newSpecTC == null) { return null; } newSpecTC = GeneralStorage.getInstance().getMasterSession().find( newSpecTC.getClass(), newSpecTC.getId()); DataEventDispatcher.getInstance().fireDataChangedListener( newSpecTC, DataState.Added, UpdateState.all); TestCaseBrowser tcb = MultipleTCBTracker.getInstance().getMainTCB(); if (tcb != null) { tcb.getTreeViewer().setSelection( new StructuredSelection(newSpecTC), true); } } return null; } /** * @param newTestCaseName * the new test case name * @param nodesToClone * the nodes to clone * @return the new spec test case with cloned param nodes * or null if something went wrong */ private ISpecTestCasePO createAndPerformNodeDuplication( String newTestCaseName, List<INodePO> nodesToClone) { final CloneTransaction op = new CloneTransaction(newTestCaseName, nodesToClone); if (TransactionWrapper.executeOperation(op)) { return op.getNewSpecTC(); } return null; } }