/******************************************************************************* * Copyright (c) 2017-2019 DocDoku. * 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: * DocDoku - initial API and implementation *******************************************************************************/ package org.polarsys.eplmp.server.dao; import org.polarsys.eplmp.core.configuration.ProductBaseline; import org.polarsys.eplmp.core.configuration.ProductInstanceIteration; import org.polarsys.eplmp.core.exceptions.CreationException; import org.polarsys.eplmp.core.exceptions.PathToPathLinkAlreadyExistsException; import org.polarsys.eplmp.core.exceptions.PathToPathLinkNotFoundException; import org.polarsys.eplmp.core.product.ConfigurationItem; import org.polarsys.eplmp.core.product.PartLink; import org.polarsys.eplmp.core.product.PartUsageLink; import org.polarsys.eplmp.core.product.PathToPathLink; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.persistence.EntityExistsException; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; /** * @author morgan on 29/04/15. */ @RequestScoped public class PathToPathLinkDAO { private static final Logger LOGGER = Logger.getLogger(PathToPathLinkDAO.class.getName()); public static final String PRODUCT_INSTANCE_ITERATION = "productInstanceIteration"; public static final String PRODUCT_BASELINE = "productBaseline"; public static final String CONFIGURATION_ITEM = "configurationItem"; public static final String SOURCE = "source"; public static final String TARGET = "target"; @Inject private EntityManager em; public PathToPathLinkDAO() { } public void createPathToPathLink(PathToPathLink pPathToPathLink) throws CreationException, PathToPathLinkAlreadyExistsException { try { //the EntityExistsException is thrown only when flush occurs em.persist(pPathToPathLink); em.flush(); } catch (EntityExistsException pEEEx) { LOGGER.log(Level.FINEST,null,pEEEx); throw new PathToPathLinkAlreadyExistsException(pPathToPathLink); } catch (PersistenceException pPEx) { LOGGER.log(Level.FINEST,null,pPEx); //EntityExistsException is case sensitive //whereas MySQL is not thus PersistenceException could be //thrown instead of EntityExistsException throw new CreationException(); } } public PathToPathLink loadPathToPathLink(int pPathToPathLinkId) throws PathToPathLinkNotFoundException { PathToPathLink pathToPathLink = em.find(PathToPathLink.class, pPathToPathLinkId); if(pathToPathLink != null){ return pathToPathLink; } throw new PathToPathLinkNotFoundException(pPathToPathLinkId); } public void removePathToPathLink(PathToPathLink pathToPathLink) { em.remove(pathToPathLink); em.flush(); } public List<String> getDistinctPathToPathLinkTypes(ProductInstanceIteration productInstanceIteration) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkTypesByProductInstanceIteration",String.class) .setParameter(PRODUCT_INSTANCE_ITERATION,productInstanceIteration) .getResultList(); } public List<PathToPathLink> getDistinctPathToPathLink(ProductInstanceIteration productInstanceIteration) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkByProductInstanceIteration",PathToPathLink.class) .setParameter(PRODUCT_INSTANCE_ITERATION,productInstanceIteration) .getResultList(); } public List<String> getDistinctPathToPathLinkTypes(ProductBaseline productBaseline) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkTypesByProductBaseline",String.class) .setParameter(PRODUCT_BASELINE,productBaseline) .getResultList(); } public List<String> getDistinctPathToPathLinkTypes(ConfigurationItem configurationItem) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkTypesByProduct",String.class) .setParameter(CONFIGURATION_ITEM,configurationItem) .getResultList(); } public PathToPathLink getSamePathToPathLink(ConfigurationItem configurationItem, PathToPathLink pathToPathLink){ try { return em.createNamedQuery("PathToPathLink.findSamePathToPathLinkInProduct", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("targetPath", pathToPathLink.getTargetPath()) .setParameter("sourcePath", pathToPathLink.getSourcePath()) .setParameter("type", pathToPathLink.getType()) .getSingleResult(); }catch(NoResultException e){ return null; } } public List<PathToPathLink> getNextPathToPathLinkInProduct(ConfigurationItem configurationItem, PathToPathLink pathToPathLink){ return em.createNamedQuery("PathToPathLink.findNextPathToPathLinkInProduct", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("targetPath", pathToPathLink.getTargetPath()) .setParameter("type", pathToPathLink.getType()) .getResultList(); } public List<PathToPathLink> getPathToPathLinkFromSourceAndTarget(ProductBaseline baseline, String source, String target) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkBySourceAndTargetInBaseline", PathToPathLink.class) .setParameter("baseline", baseline) .setParameter(SOURCE,source) .setParameter(TARGET, target) .getResultList(); } public List<PathToPathLink> getPathToPathLinkFromSourceAndTarget(ProductInstanceIteration productInstanceIteration, String source, String target) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkBySourceAndTargetInProductInstance", PathToPathLink.class) .setParameter(PRODUCT_INSTANCE_ITERATION, productInstanceIteration) .setParameter(SOURCE,source) .setParameter(TARGET, target) .getResultList(); } public List<PathToPathLink> getPathToPathLinkFromSourceAndTarget(ConfigurationItem configurationItem, String source, String target) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkBySourceAndTargetInProduct", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter(SOURCE,source) .setParameter(TARGET, target) .getResultList(); } public List<PathToPathLink> findRootPathToPathLinks(ConfigurationItem configurationItem, String type) { return em.createNamedQuery("PathToPathLink.findRootPathToPathLinkForGivenProductAndType", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("type", type) .getResultList(); } public List<PathToPathLink> findRootPathToPathLinks(ProductBaseline productBaseline, String type) { return em.createNamedQuery("PathToPathLink.findRootPathToPathLinkForGivenProductBaselineAndType", PathToPathLink.class) .setParameter(PRODUCT_BASELINE, productBaseline) .setParameter("type", type) .getResultList(); } public List<PathToPathLink> findRootPathToPathLinks(ProductInstanceIteration productInstanceIteration, String type) { return em.createNamedQuery("PathToPathLink.findRootPathToPathLinkForGivenProductInstanceIterationAndType", PathToPathLink.class) .setParameter(PRODUCT_INSTANCE_ITERATION, productInstanceIteration) .setParameter("type", type) .getResultList(); } public List<PathToPathLink> getPathToPathLinkFromPathList(ConfigurationItem configurationItem, List<String> paths) { return em.createNamedQuery("PathToPathLink.findPathToPathLinkByPathListInProduct", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("paths",paths) .getResultList(); } public List<PathToPathLink> getSourcesPathToPathLinksInProduct(ConfigurationItem configurationItem, String type, String source) { return em.createNamedQuery("PathToPathLink.findSourcesPathToPathLinkInProduct", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("type", type) .setParameter(SOURCE, source) .getResultList(); } public List<PathToPathLink> getSourcesPathToPathLinksInBaseline(ProductBaseline productBaseline, String type, String source) { return em.createNamedQuery("PathToPathLink.findSourcesPathToPathLinkInProductBaseline", PathToPathLink.class) .setParameter(PRODUCT_BASELINE, productBaseline) .setParameter("type", type) .setParameter(SOURCE, source) .getResultList(); } public List<PathToPathLink> getPathToPathLinksFromPartialPath(String usageLinkId){ return em.createNamedQuery("PathToPathLink.findLinksWherePartialPathIsPresent", PathToPathLink.class) .setParameter("inChain", "%" + usageLinkId + "-%") .setParameter("endOfChain", "%" + usageLinkId) .getResultList(); } public void removePathToPathLinks(String usageLinkId) { List<PathToPathLink> pathToPathLinks = getPathToPathLinksFromPartialPath(usageLinkId); for(PathToPathLink pathToPathLink:pathToPathLinks){ try{ ConfigurationItem configurationItem = em.createNamedQuery("ConfigurationItem.findByPathToPathLink", ConfigurationItem.class) .setParameter("pathToPathLink", pathToPathLink) .getSingleResult(); configurationItem.removePathToPathLink(pathToPathLink); } catch (NoResultException e){ // Nothing to remove, continue loop } } } private void upgradePathToPathLink(PartLink oldLink, PartLink newLink){ List<PathToPathLink> oldP2PLinks = getPathToPathLinksFromPartialPath(oldLink.getFullId()); String oldFullId = oldLink.getFullId(); String newFullId = newLink.getFullId(); for(PathToPathLink pathToPathLink:oldP2PLinks){ pathToPathLink.setSourcePath(upgradePath(pathToPathLink.getSourcePath(), oldFullId, newFullId)); pathToPathLink.setTargetPath(upgradePath(pathToPathLink.getTargetPath(), oldFullId, newFullId)); } if(oldLink.getSubstitutes() != null){ int size = oldLink.getSubstitutes().size(); for(int i = 0; i < size; i++){ PartLink oldSubstituteLink = oldLink.getSubstitutes().get(i); PartLink newSubstituteLink = newLink.getSubstitutes().get(i); upgradePathToPathLink(oldSubstituteLink,newSubstituteLink); } } } public void cloneAndUpgradePathToPathLinks(List<PartUsageLink> oldComponents, List<PartUsageLink> newComponents) { int size = oldComponents.size(); //keep a track of p2p to create and add it to the configuration item only once //at the end of the process in order to not create them twice //Map<PathToPathLink,Map<PathToPathLink, ConfigurationItem>> is oldP2P => newP2P => the configuration item into //which it has be added Map<PathToPathLink,Map<PathToPathLink, ConfigurationItem>> modifiedP2P=new HashMap<>(); for(int i = 0; i < size; i++){ PartLink oldLink = oldComponents.get(i); PartLink newLink = newComponents.get(i); cloneAndUpgradePathToPathLink(oldLink, newLink, modifiedP2P); } //to the new p2p to their configuration item for(Map<PathToPathLink, ConfigurationItem> p2pAndConfigItem:modifiedP2P.values()){ Map.Entry<PathToPathLink, ConfigurationItem> pair = p2pAndConfigItem.entrySet().iterator().next(); ConfigurationItem ci = pair.getValue(); ci.addPathToPathLink(pair.getKey()); } } private void cloneAndUpgradePathToPathLink(PartLink oldLink, PartLink newLink, Map<PathToPathLink,Map<PathToPathLink, ConfigurationItem>> modifiedP2P){ List<PathToPathLink> oldP2PLinks = getPathToPathLinksFromPartialPath(oldLink.getFullId()); String oldFullId = oldLink.getFullId(); String newFullId = newLink.getFullId(); PathToPathLink clone; for(PathToPathLink pathToPathLink:oldP2PLinks){ if(modifiedP2P.get(pathToPathLink) !=null){ clone = modifiedP2P.get(pathToPathLink).keySet().iterator().next(); }else{ clone = new PathToPathLink(pathToPathLink.getType(),pathToPathLink.getSourcePath(),pathToPathLink.getTargetPath(),pathToPathLink.getDescription()); } clone.setSourcePath(upgradePath(clone.getSourcePath(), oldFullId, newFullId)); clone.setTargetPath(upgradePath(clone.getTargetPath(), oldFullId, newFullId)); // Add in configuration item list try { ConfigurationItem configurationItem = em.createNamedQuery("ConfigurationItem.findByPathToPathLink", ConfigurationItem.class) .setParameter("pathToPathLink", pathToPathLink) .getSingleResult(); Map<PathToPathLink, ConfigurationItem> p2pToAdd = new HashMap<>(); p2pToAdd.put(clone,configurationItem); modifiedP2P.put(pathToPathLink,p2pToAdd); }catch(NoResultException e){ LOGGER.log(Level.FINEST,null,e); } } if(oldLink.getSubstitutes() != null){ int size = oldLink.getSubstitutes().size(); for(int i = 0; i < size; i++){ PartLink oldSubstituteLink = oldLink.getSubstitutes().get(i); PartLink newSubstituteLink = newLink.getSubstitutes().get(i); cloneAndUpgradePathToPathLink(oldSubstituteLink, newSubstituteLink, modifiedP2P); } } } public String upgradePath(String path, String oldFullId, String newFullId) { return path.replaceAll("("+oldFullId+")(-|$)", newFullId + "$2"); } public List<PathToPathLink> getPathToPathLinkSourceInContext(ConfigurationItem configurationItem, ProductInstanceIteration productInstanceIteration, String path){ if(productInstanceIteration != null){ return em.createNamedQuery("PathToPathLink.isSourceInProductInstanceContext", PathToPathLink.class) .setParameter(PRODUCT_INSTANCE_ITERATION, productInstanceIteration) .setParameter("path", path) .getResultList(); }else{ return em.createNamedQuery("PathToPathLink.isSourceInConfigurationItemContext", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("path", path) .getResultList(); } } public List<PathToPathLink> getPathToPathLinkTargetInContext(ConfigurationItem configurationItem, ProductInstanceIteration productInstanceIteration, String path){ if(productInstanceIteration != null){ return em.createNamedQuery("PathToPathLink.isTargetInProductInstanceContext", PathToPathLink.class) .setParameter(PRODUCT_INSTANCE_ITERATION, productInstanceIteration) .setParameter("path", path) .getResultList(); }else{ return em.createNamedQuery("PathToPathLink.isTargetInConfigurationItemContext", PathToPathLink.class) .setParameter(CONFIGURATION_ITEM, configurationItem) .setParameter("path", path) .getResultList(); } } }