/******************************************************************************* * 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.core.businessprocess.db; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; import org.apache.commons.collections.ListUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang.builder.EqualsBuilder; import org.eclipse.jubula.client.core.i18n.Messages; import org.eclipse.jubula.client.core.model.ICategoryPO; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.IPersistentObject; import org.eclipse.jubula.client.core.model.IProjectPO; import org.eclipse.jubula.client.core.model.ISpecObjContPO; import org.eclipse.jubula.client.core.model.ISpecTestCasePO; import org.eclipse.jubula.client.core.model.ITestJobPO; import org.eclipse.jubula.client.core.model.ITestSuitePO; import org.eclipse.jubula.client.core.persistence.EditSupport; import org.eclipse.jubula.client.core.persistence.GeneralStorage; import org.eclipse.jubula.client.core.persistence.NodePM; import org.eclipse.jubula.client.core.persistence.PMAlreadyLockedException; import org.eclipse.jubula.client.core.persistence.PMDirtyVersionException; import org.eclipse.jubula.client.core.persistence.PMException; import org.eclipse.jubula.client.core.persistence.PMObjectDeletedException; import org.eclipse.jubula.client.core.persistence.PersistenceManager; import org.eclipse.jubula.client.core.persistence.locking.LockManager; import org.eclipse.jubula.tools.internal.constants.StringConstants; import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author BREDEX GmbH * @created Mar 18, 2010 */ public class NodeBP { /** the logger */ private static final Logger LOG = LoggerFactory.getLogger(NodeBP.class); /** * Utility class */ protected NodeBP() { // do nothing } /** * @param editSupport holding the DB session for locking purposes * @param node node to lock * @throws PMObjectDeletedException * @throws PMDirtyVersionException * @throws PMAlreadyLockedException */ protected static void lockPO(EditSupport editSupport, INodePO node) throws PMObjectDeletedException, PMDirtyVersionException, PMAlreadyLockedException { final EntityManager lockSession = editSupport.getSession(); try { try { // make sure there is no old version // in the session cache lockSession.detach(node); lockSession.find(node.getClass(), node.getId()); } catch (PersistenceException e) { PersistenceManager.handleDBExceptionForEditor(node, e, editSupport); } } catch (PMDirtyVersionException e) { // NOPMD by al on 3/19/07 1:25 PM // ignore, we are not interested in version checking } catch (PMObjectDeletedException e) { // OK, this may happen, just forward to caller throw e; } catch (PMException e) { // Continue since we are just refreshing the cache LOG.error(Messages.StrayPersistenceException + StringConstants.DOT + StringConstants.DOT, e); } if (!LockManager.instance().lockPO(lockSession, node, false)) { throw new PMAlreadyLockedException(node, Messages.OrginalTestcaseLocked + StringConstants.DOT, MessageIDs.E_OBJECT_IN_USE); } } /** * @param type * the type to search for * @return a list of nodes with the given type */ public static List<? extends INodePO> getAllNodesForGivenTypeInCurrentProject(Class type) { if (INodePO.class.isAssignableFrom(type)) { GeneralStorage gs = GeneralStorage.getInstance(); return NodePM.computeListOfNodes(type, gs.getProject().getId(), gs.getMasterSession()); } return ListUtils.EMPTY_LIST; } /** * * @param po The persistent object to check. * @return <code>true</code> if the given node can be modified within * the active project. Otherwise <code>false</code>. */ public static boolean isEditable(IPersistentObject po) { Validate.notNull(po); IProjectPO activeProject = GeneralStorage.getInstance().getProject(); if (activeProject == po) { return true; } return activeProject != null && activeProject.getId().equals(po.getParentProjectId()); } /** * @param node * the node to check * @return whether the given node or one of it's parent is active or not */ public static boolean isNodeActive(INodePO node) { if (node == null || !node.isActive()) { return false; } INodePO parentNode = node.getParentNode(); while (parentNode != null) { if (node != null) { if (!node.isActive()) { return false; } } parentNode = parentNode.getParentNode(); } return true; } /** * @param nodePO * the node to test * @return true if editable --> belongs to current project; false otherwise * or if nodePO == null */ public static boolean belongsToCurrentProject(INodePO nodePO) { IProjectPO currentProject = GeneralStorage.getInstance() .getProject(); if (nodePO != null && currentProject != null) { EqualsBuilder eb = new EqualsBuilder(); eb.append(nodePO.getParentProjectId(), currentProject.getId()); return eb.isEquals(); } return false; } /** * Finds offsprings of a node - should only be called for Categories, SpecTCs, TestSuites and TestJobs * @param nodes the node * @return all offspring */ public static Collection<INodePO> getOffspringCollection( Collection<INodePO> nodes) { for (INodePO node : nodes) { if (!(node instanceof ICategoryPO || node instanceof ITestSuitePO || node instanceof ISpecTestCasePO || node instanceof ITestJobPO)) { throw new UnsupportedOperationException("This method only supports Categories, Test Suites, Spec Test Cases and Test Jobs."); //$NON-NLS-1$ } } List<INodePO> offspring = new ArrayList<INodePO>(); for (INodePO node : nodes) { addOffspring(node, offspring); } return offspring; } /** * Adds the offspring of a node to a collection * @param node the node * @param offspring the offspring */ private static void addOffspring(INodePO node, Collection<INodePO> offspring) { if (node instanceof ICategoryPO) { for (INodePO child : node.getUnmodifiableNodeList()) { addOffspring(child, offspring); } } offspring.add(node); } /** * Determines whether a node comes from the TC or TS Browser * @param node the node * @return whether */ public static boolean isTC(INodePO node) { INodePO top = node; while (top.getParentNode() != null) { top = top.getParentNode(); } return top == ISpecObjContPO.TCB_ROOT_NODE; } }