/******************************************************************************* * 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.businessprocess; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Stack; import org.eclipse.jubula.client.core.businessprocess.CompNameManager; import org.eclipse.jubula.client.core.businessprocess.IWritableComponentNameCache; import org.eclipse.jubula.client.core.businessprocess.ObjectMappingEventDispatcher; 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.IComponentNamePO; import org.eclipse.jubula.client.core.model.IObjectMappingAssoziationPO; import org.eclipse.jubula.client.core.model.IObjectMappingCategoryPO; import org.eclipse.jubula.client.core.model.IObjectMappingPO; import org.eclipse.jubula.client.core.model.PoMaker; import org.eclipse.jubula.client.ui.rcp.controllers.dnd.objectmapping.OMEditorDndSupport; import org.eclipse.jubula.client.ui.rcp.editors.ObjectMappingMultiPageEditor; /** * BusinessProcess class for the OM Editor. * * @author BREDEX GmbH * @created 02.03.2006 */ public class OMEditorBP { /** when mapping a technical name, it will be created in here */ private transient IObjectMappingCategoryPO m_categoryToCreateIn; /** editor */ private ObjectMappingMultiPageEditor m_editor; /** * Constructor. * @param editor ObjectMappingEditor. */ public OMEditorBP(ObjectMappingMultiPageEditor editor) { setEditor(editor); } /** * @return Returns the categoryToCreateIn. */ public IObjectMappingCategoryPO getCategoryToCreateIn() { return m_categoryToCreateIn; } /** * @param categoryToCreateIn The categoryToCreateIn to set. */ public void setCategoryToCreateIn( IObjectMappingCategoryPO categoryToCreateIn) { m_categoryToCreateIn = categoryToCreateIn; ObjectMappingEventDispatcher.setCategoryToCreateIn( categoryToCreateIn); } /** * Deletes the given category and all children from the object map. * * @param toDelete The category to delete. * @return the parent of the category before it was * deleted. */ public IObjectMappingCategoryPO deleteCategory( IObjectMappingCategoryPO toDelete) { changeReuseOfCompNames(toDelete); IObjectMappingCategoryPO parent = toDelete.getParent(); parent.removeCategory(toDelete); DataEventDispatcher.getInstance().fireDataChangedListener( parent, DataState.StructureModified, UpdateState.onlyInEditor); DataEventDispatcher.getInstance().fireDataChangedListener( toDelete, DataState.Deleted, UpdateState.onlyInEditor); return parent; } /** * Removes the used Component Names * @param toDelete the category to delete */ private void changeReuseOfCompNames(IObjectMappingCategoryPO toDelete) { for (IObjectMappingAssoziationPO assoc : toDelete.getUnmodifiableAssociationList()) { removeCompNames(assoc); } for (IObjectMappingCategoryPO cat : toDelete.getUnmodifiableCategoryList()) { changeReuseOfCompNames(cat); } } /** * Deletes the given Component Name from the object map. * * @param toDelete The Component Name to delete. * @param fromEditor indicates that the deletion initiated from the Editor * @return the category to which the Component Name belonged before it was * deleted. */ public IObjectMappingCategoryPO deleteCompName( IComponentNamePO toDelete, boolean fromEditor) { IObjectMappingCategoryPO originalCategory = null; IWritableComponentNameCache cNCache = getEditor().getCompNameCache(); IObjectMappingAssoziationPO parent = getAssociation(toDelete.getGuid()); if (parent == null) { return null; } cNCache.changeReuse(parent, toDelete.getGuid(), null); IObjectMappingCategoryPO category = parent.getCategory(); originalCategory = category; if (parent.getLogicalNames().isEmpty()) { if (originalCategory != null) { // can be null when the Component Name was never in the database originalCategory.removeAssociation(parent); } if (parent.getTechnicalName() != null) { // Move association to appropriate section/category Stack<String> catPath = new Stack<String>(); while (category.getParent() != null) { catPath.push(category.getName()); category = category.getParent(); } IObjectMappingCategoryPO newCategory = getEditor().getAut() .getObjMap().getUnmappedTechnicalCategory(); while (!catPath.isEmpty()) { String catName = catPath.pop(); IObjectMappingCategoryPO subcategory = findSubcategory(newCategory, catName); if (subcategory == null) { // Create new category subcategory = PoMaker.createObjectMappingCategoryPO(catName); newCategory.addCategory(subcategory); } newCategory = subcategory; } newCategory.addAssociation(parent); } else { // Delete empty association from session getEditor().getEntityManager().remove(parent); } } if (fromEditor && CompNameManager.getInstance() .getResCompNamePOByGuid(toDelete.getGuid()) == null) { // Comp Name is not in the DB, so we need to remove it from the cache // if it is still in the DB, we cannot throw it, because its type may have changed // due to removal from the Editor cNCache.removeCompName(toDelete.getGuid()); } DataEventDispatcher.getInstance().fireDataChangedListener( getEditor().getAut().getObjMap(), DataState.StructureModified, UpdateState.onlyInEditor); return originalCategory; } /** * Deletes the association from the object map. The corresponding Technical * Name is deleted as well. * * @param toDelete The association to delete. * @return the category to which the association belonged before deletion. */ public IObjectMappingCategoryPO deleteAssociation( IObjectMappingAssoziationPO toDelete) { removeCompNames(toDelete); IObjectMappingCategoryPO parent = toDelete.getCategory(); parent.removeAssociation(toDelete); getEditor().getAut().getObjMap().removeAssociationFromCache(toDelete); DataEventDispatcher.getInstance().fireDataChangedListener( parent, DataState.StructureModified, UpdateState.onlyInEditor); return parent; } /** * Changes the usage of the Component Names in the association * @param assoc the association */ private void removeCompNames(IObjectMappingAssoziationPO assoc) { // making a copy to avoid Concurrent Modification List<String> guids = new ArrayList<>(assoc.getLogicalNames()); for (String guid : guids) { getEditor().getCompNameCache().changeReuse(assoc, guid, null); } } /** * * @param category The category in which to look for the subcategory. * @param subcategoryName The name of the subcategory to find. * @return the category that is a child of <code>category</code> with name * <code>subcategoryName</code>, or <code>null</code> if no such * category can be found. */ private IObjectMappingCategoryPO findSubcategory( IObjectMappingCategoryPO category, String subcategoryName) { for (IObjectMappingCategoryPO subcategory : category.getUnmodifiableCategoryList()) { if (subcategoryName.equals(subcategory.getName())) { return subcategory; } } return null; } /** * * @param compNameGuid The GUID of the Component Name for which to find * the corresponding association. * @return The association for the Component Name with the given GUID. */ public IObjectMappingAssoziationPO getAssociation(String compNameGuid) { IObjectMappingPO objMap = getEditor().getAut().getObjMap(); return objMap.getLogicalNameAssoc(compNameGuid); } /** * checks if a category name exists * * !! does not work recursivly, just checks in given INodePO !! * * @param name String * @param start GuiNode * @return boolean */ public boolean existCategory(IObjectMappingCategoryPO start, String name) { for (IObjectMappingCategoryPO child : start.getUnmodifiableCategoryList()) { if (child.getName().equals(name)) { return true; } } return false; } /** * * @param compNamePo The Component Name to check. * @return the top-level category to which the given Component Name belongs. */ public IObjectMappingCategoryPO getSection( IComponentNamePO compNamePo) { IObjectMappingAssoziationPO assoc = getAssociation(compNamePo.getGuid()); if (assoc != null) { return OMEditorDndSupport.getSection(assoc); } return null; } /** * * @param compNamePo The Component Name for which to find the category. * @return the category to which <code>compNamePo</code> belongs. */ public IObjectMappingCategoryPO getCategory( final IComponentNamePO compNamePo) { IObjectMappingAssoziationPO assoc = getAssociation(compNamePo.getGuid()); return assoc.getCategory(); } /** * Creates and returns a category. The new category has the same path as * <code>subcategory</code> except for the top-level element of the path * (based on <code>section</code>), which may be different. * * If the category to create already exists, then no category is created, * and the existing category is returned. * * @param section The top-level category in which to create the new * category. * @param subcategory The category with the path to use for the new * category. * @return the created or pre-existing category. */ public IObjectMappingCategoryPO createCategory( IObjectMappingCategoryPO section, IObjectMappingCategoryPO subcategory) { IObjectMappingCategoryPO curCat = section; for (String pathEntry : getCatPath(subcategory)) { boolean childExists = false; for (IObjectMappingCategoryPO child : curCat.getUnmodifiableCategoryList()) { if (child.getName().equals(pathEntry)) { curCat = child; childExists = true; break; } } if (!childExists) { IObjectMappingCategoryPO newCat = PoMaker.createObjectMappingCategoryPO(pathEntry); curCat.addCategory(newCat); curCat = newCat; } } return curCat; } /** * * @param category The category for which to get the path. * @return the path for the given category, excluding the section. */ private List<String> getCatPath(IObjectMappingCategoryPO category) { List<String> catPath = new ArrayList<String>(); IObjectMappingCategoryPO curCat = category; while (curCat.getParent() != null) { catPath.add(curCat.getName()); curCat = curCat.getParent(); } Collections.reverse(catPath); return catPath; } /** * collect new logical component names / refresh object mapping editor */ public void collectNewLogicalComponentNames() { if (getEditor().cleanupNames() > 0) { DataEventDispatcher.getInstance().fireDataChangedListener( getEditor().getAut().getObjMap(), DataState.StructureModified, UpdateState.onlyInEditor); } } /** * @param editor the editor to set */ private void setEditor(ObjectMappingMultiPageEditor editor) { m_editor = editor; } /** * @return the editor */ private ObjectMappingMultiPageEditor getEditor() { return m_editor; } }