Java tutorial
/******************************************************************************* * 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.archive; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import javax.persistence.EntityManager; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.Converter; import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jubula.client.archive.converter.AbstractXmlConverter; import org.eclipse.jubula.client.archive.converter.AutIdGenerationConverter; import org.eclipse.jubula.client.archive.converter.HTMLTechnicalComponentIndexConverter; import org.eclipse.jubula.client.archive.converter.IXmlConverter; import org.eclipse.jubula.client.archive.converter.V4C001; import org.eclipse.jubula.client.archive.converter.WinToolkitIdConverter; import org.eclipse.jubula.client.archive.i18n.Messages; import org.eclipse.jubula.client.archive.output.NullImportOutput; import org.eclipse.jubula.client.archive.schema.Aut; import org.eclipse.jubula.client.archive.schema.AutConfig; import org.eclipse.jubula.client.archive.schema.Cap; import org.eclipse.jubula.client.archive.schema.Category; import org.eclipse.jubula.client.archive.schema.CheckActivatedContext; import org.eclipse.jubula.client.archive.schema.CheckAttribute; import org.eclipse.jubula.client.archive.schema.CheckConfiguration; import org.eclipse.jubula.client.archive.schema.CompNames; import org.eclipse.jubula.client.archive.schema.ComponentName; import org.eclipse.jubula.client.archive.schema.EventHandler; import org.eclipse.jubula.client.archive.schema.EventTestCase; import org.eclipse.jubula.client.archive.schema.ExecCategory; import org.eclipse.jubula.client.archive.schema.I18NString; import org.eclipse.jubula.client.archive.schema.MapEntry; import org.eclipse.jubula.client.archive.schema.MonitoringValues; import org.eclipse.jubula.client.archive.schema.NamedTestData; import org.eclipse.jubula.client.archive.schema.ObjectMapping; import org.eclipse.jubula.client.archive.schema.ObjectMappingProfile; import org.eclipse.jubula.client.archive.schema.OmCategory; import org.eclipse.jubula.client.archive.schema.OmEntry; import org.eclipse.jubula.client.archive.schema.ParamDescription; import org.eclipse.jubula.client.archive.schema.Project; import org.eclipse.jubula.client.archive.schema.RefTestCase; import org.eclipse.jubula.client.archive.schema.RefTestSuite; import org.eclipse.jubula.client.archive.schema.ReusedProject; import org.eclipse.jubula.client.archive.schema.SummaryAttribute; import org.eclipse.jubula.client.archive.schema.TechnicalName; import org.eclipse.jubula.client.archive.schema.TestCase; import org.eclipse.jubula.client.archive.schema.TestCase.Teststep; import org.eclipse.jubula.client.archive.schema.TestData; import org.eclipse.jubula.client.archive.schema.TestDataCategory; import org.eclipse.jubula.client.archive.schema.TestDataCell; import org.eclipse.jubula.client.archive.schema.TestDataRow; import org.eclipse.jubula.client.archive.schema.TestJobs; import org.eclipse.jubula.client.archive.schema.TestSuite; import org.eclipse.jubula.client.archive.schema.TestresultSummaries; import org.eclipse.jubula.client.archive.schema.TestresultSummary; import org.eclipse.jubula.client.archive.schema.UsedToolkit; import org.eclipse.jubula.client.core.businessprocess.ComponentNamesBP.CompNameCreationContext; import org.eclipse.jubula.client.core.businessprocess.IParamNameMapper; import org.eclipse.jubula.client.core.businessprocess.IWritableComponentNameCache; import org.eclipse.jubula.client.core.businessprocess.ProjectNameBP; import org.eclipse.jubula.client.core.businessprocess.TestDataCubeBP; import org.eclipse.jubula.client.core.businessprocess.UsedToolkitBP; import org.eclipse.jubula.client.core.businessprocess.UsedToolkitBP.ToolkitPluginError; import org.eclipse.jubula.client.core.businessprocess.UsedToolkitBP.ToolkitPluginError.ERROR; import org.eclipse.jubula.client.core.model.IAUTConfigPO; import org.eclipse.jubula.client.core.model.IAUTConfigPO.ActivationMethod; import org.eclipse.jubula.client.core.model.IAUTMainPO; import org.eclipse.jubula.client.core.model.ICapPO; import org.eclipse.jubula.client.core.model.ICategoryPO; import org.eclipse.jubula.client.core.model.ICheckConfContPO; import org.eclipse.jubula.client.core.model.ICheckConfPO; import org.eclipse.jubula.client.core.model.ICompNamesPairPO; import org.eclipse.jubula.client.core.model.IComponentNamePO; import org.eclipse.jubula.client.core.model.IEventExecTestCasePO; import org.eclipse.jubula.client.core.model.IExecTestCasePO; import org.eclipse.jubula.client.core.model.INodePO; 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.IObjectMappingProfilePO; import org.eclipse.jubula.client.core.model.IParamDescriptionPO; import org.eclipse.jubula.client.core.model.IParamNodePO; import org.eclipse.jubula.client.core.model.IParameterInterfacePO; import org.eclipse.jubula.client.core.model.IProjectPO; import org.eclipse.jubula.client.core.model.IProjectPropertiesPO; import org.eclipse.jubula.client.core.model.IRefTestSuitePO; import org.eclipse.jubula.client.core.model.IReusedProjectPO; import org.eclipse.jubula.client.core.model.ISpecTestCasePO; import org.eclipse.jubula.client.core.model.ITDManager; import org.eclipse.jubula.client.core.model.ITestDataCategoryPO; import org.eclipse.jubula.client.core.model.ITestDataCubePO; import org.eclipse.jubula.client.core.model.ITestDataPO; import org.eclipse.jubula.client.core.model.ITestJobPO; import org.eclipse.jubula.client.core.model.ITestResultSummary; import org.eclipse.jubula.client.core.model.ITestResultSummaryPO; import org.eclipse.jubula.client.core.model.ITestSuitePO; import org.eclipse.jubula.client.core.model.IUsedToolkitPO; import org.eclipse.jubula.client.core.model.NodeMaker; import org.eclipse.jubula.client.core.model.PoMaker; import org.eclipse.jubula.client.core.model.ReentryProperty; import org.eclipse.jubula.client.core.persistence.IExecPersistable; import org.eclipse.jubula.client.core.persistence.ISpecPersistable; import org.eclipse.jubula.client.core.persistence.NodePM; import org.eclipse.jubula.client.core.persistence.PersistenceUtil; import org.eclipse.jubula.client.core.persistence.Persistor; import org.eclipse.jubula.client.core.persistence.TestResultSummaryPM; import org.eclipse.jubula.client.core.progress.IProgressConsole; import org.eclipse.jubula.client.core.utils.AbstractNonPostOperatingTreeNodeOperation; import org.eclipse.jubula.client.core.utils.ITreeTraverserContext; import org.eclipse.jubula.client.core.utils.LocaleUtil; import org.eclipse.jubula.client.core.utils.ModelParamValueConverter; import org.eclipse.jubula.client.core.utils.TreeTraverser; import org.eclipse.jubula.toolkit.common.xml.businessprocess.ComponentBuilder; import org.eclipse.jubula.tools.constants.AutConfigConstants; import org.eclipse.jubula.tools.constants.StringConstants; import org.eclipse.jubula.tools.exception.Assert; import org.eclipse.jubula.tools.exception.InvalidDataException; import org.eclipse.jubula.tools.exception.JBVersionException; import org.eclipse.jubula.tools.i18n.CompSystemI18n; import org.eclipse.jubula.tools.jarutils.IVersion; import org.eclipse.jubula.tools.messagehandling.MessageIDs; import org.eclipse.jubula.tools.objects.ComponentIdentifier; import org.eclipse.jubula.tools.objects.IComponentIdentifier; import org.eclipse.jubula.tools.objects.IMonitoringValue; import org.eclipse.jubula.tools.objects.MonitoringValue; import org.eclipse.jubula.tools.xml.businessmodell.Component; import org.eclipse.jubula.tools.xml.businessmodell.ConcreteComponent; import org.eclipse.jubula.tools.xml.businessmodell.ToolkitPluginDescriptor; import org.eclipse.osgi.util.NLS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.thoughtworks.xstream.converters.ConversionException; /** * @author BREDEX GmbH * @created 13.01.2006 */ class XmlImporter { /** * Pattern for date serialization format. * Due to the fact that this constant is used for serialization and * deserialization, it is very important that:<ul> * <li><b>any</b> change to the format be carefully considered such that * deserialization of dates from exported projects still works</li> * <li>the format <b>only</b> contains numbers, as language differences * might otherwise break deserialization (e.g. American English has * no way to meaningfully parse the German "Mai")</li> * </ul> */ public static final String DATE_PATTERN = "yyyy-MM-dd hh:mm:ss.S"; //$NON-NLS-1$ /** * Utility for converting between Strings and model objects for use in * import/export operations. This is available for use but should not be * modified (registration/deregistration of converters). */ public static final BeanUtilsBean BEAN_UTILS = new BeanUtilsBean(); static { DateLocaleConverter converter = new DateLocaleConverter(Locale.getDefault(), DATE_PATTERN); converter.setLenient(true); final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_PATTERN); Converter stringConverter = new Converter() { @SuppressWarnings({ "rawtypes", "unused" }) protected Class getDefaultType() { return String.class; } @SuppressWarnings({ "rawtypes", "unused" }) protected Object convertToType(Class type, Object value) throws Throwable { return value.toString(); } protected String convertToString(Object value) throws Throwable { if (value instanceof Date) { return dateFormatter.format((Date) value); } return value.toString(); } public Object convert(Class arg0, Object arg1) { if (arg0.isAssignableFrom(String.class)) { try { return convertToString(arg1); } catch (Throwable e) { throw new ConversionException(e); } } throw new ConversionException("Can convert only strings"); } }; BEAN_UTILS.getConvertUtils().register(stringConverter, String.class); BEAN_UTILS.getConvertUtils().register(converter, Date.class); } /** number of characters of a guid */ private static final int GUID_LENGTH = 32; /** standard logging */ private static Logger log = LoggerFactory.getLogger(XmlImporter.class); /** Remember which instance belongs to the id used in the XML element */ private Map<String, IAUTConfigPO> m_autConfRef = new HashMap<String, IAUTConfigPO>(); /** Remember which instance belongs to the id used in the XML element */ private Map<String, IAUTMainPO> m_autRef = new HashMap<String, IAUTMainPO>(); /** Remember which instance belongs to the id/guid used in the XML element */ private Map<String, ISpecTestCasePO> m_tcRef = new HashMap<String, ISpecTestCasePO>(); /** Remember which instance belongs to the id/guid used in the XML element */ private Map<String, ICategoryPO> m_execCategoryCache = new HashMap<String, ICategoryPO>(); /** Mapping between old and new GUIDs. Only used when assigning new GUIDs */ private Map<String, String> m_oldToNewGuids = new HashMap<String, String>(); /** The progress monitor for this importer. */ private IProgressMonitor m_monitor; /** The import output. */ private IProgressConsole m_io; /** Parameters that could not be parsed during import */ private List<String> m_unparseableParameters = new ArrayList<String>(); /** * Constructor * * @param monitor * The progress monitor for this import operation. * @param io * the import output device during import progress */ public XmlImporter(IProgressMonitor monitor, IProgressConsole io) { m_monitor = monitor; m_io = io; } /** * Constructor * * @param monitor * The progress monitor for this import operation. */ public XmlImporter(IProgressMonitor monitor) { m_monitor = monitor; m_io = new NullImportOutput(); } /** * Creates the instance of the persistent object which is defined by the XML * element used as prameter. The method generates all dependend objects as * well. * * @param xml * Abstraction of the XML element (see Apache XML Beans) * @param paramNameMapper * mapper to resolve param names * @param compNameCache * cache to resolve component names * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException * if some data is invalid when constructing an object. This * should not happen for exported project, but may happen when * someone generates XML project description outside of * GUIdancer. * @throws JBVersionException * in case of version conflict between used toolkits of imported * project and the installed Toolkit Plugins * @throws InterruptedException * if the operation was canceled. */ public IProjectPO createProject(Project xml, IParamNameMapper paramNameMapper, IWritableComponentNameCache compNameCache) throws InvalidDataException, JBVersionException, InterruptedException { return createProject(xml, false, paramNameMapper, compNameCache); } /** * Creates the instance of the persistent object which is defined by the XML * element used as parameter. The method generates all dependend objects as * well. This method also assigns a new version number to the persistent * object. * * @param xml * Abstraction of the XML element (see Apache XML Beans) * @param majorVersion * Major version number for the created object. * @param minorVersion * Minor version number for the created object. * @param paramNameMapper * mapper to resolve param names * @param compNameCache * cache to resolve component names * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException * if some data is invalid when constructing an object. This * should not happen for exported project, but may happen when * someone generates XML project description outside of * GUIdancer. * @throws JBVersionException * in case of version conflict between used toolkits of imported * project and the installed Toolkit Plugins * @throws InterruptedException * if the operation was canceled. */ public IProjectPO createProject(Project xml, Integer majorVersion, Integer minorVersion, IParamNameMapper paramNameMapper, IWritableComponentNameCache compNameCache) throws InvalidDataException, JBVersionException, InterruptedException { xml.setMajorProjectVersion(majorVersion); xml.setMinorProjectVersion(minorVersion); return createProject(xml, false, paramNameMapper, compNameCache); } /** * Creates the instance of the persistent object which is defined by the XML * element used as prameter. The method generates all dependend objects as * well. * * @param xml * Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid * <code>true</code> if the project and all subnodes should be * assigned new GUIDs. Otherwise <code>false</code>. * @param paramNameMapper * mapper to resolve param names * @param compNameCache * cache to resolve component names * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException * if some data is invalid when constructing an object. This * should not happen for exported project, but may happen when * someone generates XML project description outside of * GUIdancer. * @throws InterruptedException * if the operation was canceled * @throws JBVersionException * in case of version conflict between used toolkits of imported * project and the installed Toolkit Plugins */ public IProjectPO createProject(Project xml, boolean assignNewGuid, IParamNameMapper paramNameMapper, IWritableComponentNameCache compNameCache) throws InvalidDataException, InterruptedException, JBVersionException { checkMinimumRequiredXMLVersion(xml); documentRequiredProjects(xml); checkUsedToolkits(xml); List<AbstractXmlConverter> listOfConverter = new LinkedList<AbstractXmlConverter>(); // ======= register converter here ======= listOfConverter.add(new AutIdGenerationConverter()); listOfConverter.add(new V4C001()); listOfConverter.add(new HTMLTechnicalComponentIndexConverter()); listOfConverter.add(new WinToolkitIdConverter()); // ======================================= for (IXmlConverter c : listOfConverter) { c.convert(xml); } IProjectPO proj = create(xml, assignNewGuid, paramNameMapper, compNameCache); if (!m_unparseableParameters.isEmpty()) { m_io.writeErrorLine(Messages.UnparseableParameters); for (String param : m_unparseableParameters) { m_io.writeErrorLine(param); } m_io.writeLine(StringUtils.EMPTY); } return proj; } /** * @param xml * the project xml * @throws JBVersionException * in case of version conflict between given xml and minimum xml * version number; if these versions do not fit the current * available converter are not able to convert the given project * xml properly. */ private void checkMinimumRequiredXMLVersion(Project xml) throws JBVersionException { if (!xml.isSetMetaDataVersion() || xml.getMetaDataVersion() < IVersion.JB_CLIENT_MIN_XML_METADATA_VERSION) { List<String> errorMsgs = new ArrayList<String>(); errorMsgs.add(Messages.XmlImporterProjectXMLTooOld); throw new JBVersionException(Messages.XmlImporterProjectXMLTooOld, MessageIDs.E_LOAD_PROJECT_XML_VERSION_ERROR, errorMsgs); } } /** * @param xml * the xml project * @throws JBVersionException * in case of version conflict between used toolkits of imported * project and the installed Toolkit Plugins */ private void checkUsedToolkits(Project xml) throws JBVersionException { Set<IUsedToolkitPO> usedTK = new HashSet<IUsedToolkitPO>(); for (UsedToolkit usedToolkit : xml.getUsedToolkitList()) { usedTK.add(PoMaker.createUsedToolkitsPO(usedToolkit.getName(), usedToolkit.getMajorVersion(), usedToolkit.getMinorVersion(), null)); } List<String> errorMsgs = new ArrayList<String>(); if (!validateToolkitVersion(usedTK, xml.getName(), errorMsgs)) { throw new JBVersionException(Messages.IncompatibleToolkitVersion, MessageIDs.E_LOAD_PROJECT_TOOLKIT_MAJOR_VERSION_ERROR, errorMsgs); } } /** * @param xml * the datasource to get additional information from */ private void documentRequiredProjects(Project xml) { if (xml.getReusedProjectsList().size() > 0) { m_io.writeLine(NLS.bind(Messages.XmlImporterProjectDependency, new Object[] { xml.getName(), xml.getMajorProjectVersion(), xml.getMinorProjectVersion() })); for (ReusedProject rp : xml.getReusedProjectsList()) { String requiredProjectString = rp.getProjectName() != null ? NLS.bind(Messages.XmlImporterRequiredProject, new Object[] { rp.getProjectName(), rp.getMajorProjectVersion(), rp.getMinorProjectVersion() }) : NLS.bind(Messages.XmlImporterRequiredProjectWithoutName, new Object[] { rp.getProjectGUID(), rp.getMajorProjectVersion(), rp.getMinorProjectVersion() }); m_io.writeLine(requiredProjectString); } } } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xmlProj the XML-Project * @param proj the IProjectPO * @param compNameCache The cache for storing and retrieving * Component Names in memory. * @param assignNewGuid <code>true</code> if the project and all subnodes * should be assigned new GUIDs. Otherwise <code>false</code>. */ private void createComponentNames(Project xmlProj, IProjectPO proj, IWritableComponentNameCache compNameCache, boolean assignNewGuid) { final List<ComponentName> componentNamesList = xmlProj.getComponentNamesList(); final Map<String, String> oldToNewGUID = new HashMap<String, String>(componentNamesList.size()); Set<IComponentNamePO> createdCompNames = new HashSet<IComponentNamePO>(); for (ComponentName compName : componentNamesList) { String guid = compName.getGUID(); if (assignNewGuid) { final String newGuid = PersistenceUtil.generateGuid(); oldToNewGUID.put(guid, newGuid); guid = newGuid; } final String name = compName.getCompName(); final String type = compName.getCompType(); if (!componentHasDefaultMapping(type)) { final String creationContext = compName.getCreationContext(); final CompNameCreationContext ctx = CompNameCreationContext.forName(creationContext); final IComponentNamePO componentNamePO = PoMaker.createComponentNamePO(guid, name, type, ctx, proj.getId()); componentNamePO.setReferencedGuid(compName.getRefGuid()); createdCompNames.add(componentNamePO); compNameCache.addComponentNamePO(componentNamePO); } } if (assignNewGuid) { for (IComponentNamePO createdName : createdCompNames) { String newGuid = oldToNewGUID.get(createdName.getReferencedGuid()); if (newGuid != null) { createdName.setReferencedGuid(newGuid); } } switchCompNamesGuids(proj, oldToNewGUID); } } /** * @param proj the IProjectPO * @param oldToNewGUID a Map with old to new GUID. */ private void switchCompNamesGuids(IProjectPO proj, final Map<String, String> oldToNewGUID) { /** */ class SwitchCompNamesGuidsOp extends AbstractNonPostOperatingTreeNodeOperation<INodePO> { /** {@inheritDoc} */ public boolean operate(ITreeTraverserContext<INodePO> ctx, INodePO parent, INodePO node, boolean alreadyVisited) { if (node instanceof ICapPO) { switchCapCompNameGuids((ICapPO) node); } else if (node instanceof IExecTestCasePO) { switchExecTcCompNameGuids((IExecTestCasePO) node); } return true; } /** * @param execTc an IExecTestCasePO */ private void switchExecTcCompNameGuids(IExecTestCasePO execTc) { for (ICompNamesPairPO pair : new ArrayList<ICompNamesPairPO>(execTc.getCompNamesPairs())) { final String oldGuid = pair.getFirstName(); final String newGuid = oldToNewGUID.get(oldGuid); if (newGuid != null) { pair.setFirstName(newGuid); execTc.removeCompNamesPair(oldGuid); execTc.addCompNamesPair(pair); } final String oldSecGuid = pair.getSecondName(); final String newSecGuid = oldToNewGUID.get(oldSecGuid); if (newSecGuid != null) { pair.setSecondName(newSecGuid); } } } /** * @param cap an IcapPO */ private void switchCapCompNameGuids(ICapPO cap) { final String oldGuid = cap.getComponentName(); final String newGuid = oldToNewGUID.get(oldGuid); if (newGuid != null) { cap.setComponentName(newGuid); } } } final SwitchCompNamesGuidsOp switchGuidOp = new SwitchCompNamesGuidsOp(); TreeTraverser ttv = new TreeTraverser(proj, switchGuidOp, true); ttv.traverse(true); ttv = new TreeTraverser(proj, switchGuidOp, false); ttv.traverse(true); for (IAUTMainPO autMain : proj.getAutMainList()) { final IObjectMappingPO objMap = autMain.getObjMap(); for (IObjectMappingAssoziationPO oma : objMap.getMappings()) { List<String> namesToUpdate = new ArrayList<String>(); for (String oldLogicName : oma.getLogicalNames()) { if (oldToNewGUID.containsKey(oldLogicName)) { namesToUpdate.add(oldLogicName); } } for (String oldLogicName : namesToUpdate) { oma.removeLogicalName(oldLogicName); oma.addLogicalName(oldToNewGUID.get(oldLogicName)); } } } } /** * @param usedTK toolkits used from project to import * @param projName name of project to import * @param errorMsgs list with strings of detailled error messages * @return if project uses toolkits which client supports */ private boolean validateToolkitVersion(Set<IUsedToolkitPO> usedTK, String projName, List<String> errorMsgs) { List<ToolkitPluginError> errors = UsedToolkitBP.getInstance().checkUsedToolkitPluginVersions(usedTK); if (errors.isEmpty()) { return true; } boolean loadProject = true; for (ToolkitPluginError error : errors) { final StringBuilder strBuilder = new StringBuilder(); String toolkitId = error.getToolkitId(); ToolkitPluginDescriptor desc = ComponentBuilder.getInstance().getCompSystem() .getToolkitPluginDescriptor(toolkitId); String toolkitName = desc != null ? desc.getName() : toolkitId; strBuilder.append(Messages.OpenProjectActionToolkitVersionConflict2).append(toolkitName) .append(Messages.XmlImporterToolkitVersionConflict3a).append(projName) .append(Messages.XmlImporterToolkitVersionConflict3b); final ERROR errorType = error.getError(); final String descr = Messages.OpenProjectActionToolkitVersionConflict5; switch (errorType) { case MAJOR_VERSION_ERROR: strBuilder.append(Messages.OpenProjectActionToolkitVersionConflict4a); strBuilder.append(descr); errorMsgs.add(strBuilder.toString()); loadProject = false; break; case MINOR_VERSION_HIGHER: strBuilder.append(Messages.OpenProjectActionToolkitVersionConflict4b); strBuilder.append(descr); errorMsgs.add(strBuilder.toString()); loadProject = false; break; case MINOR_VERSION_LOWER: break; default: Assert.notReached(Messages.UnknownErrorType + String.valueOf(errorType)); } } return loadProject; } /** * * @param xml XML * @param assignNewGuid <code>true</code> if the project and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @param mapper a mapper * @param cNC the component name cache to use during project creation * @return The ProjectPO * @throws InvalidDataException * @see createProject(Project xml, boolean assignNewGuid, * IParamNameMapper mapper) */ private IProjectPO create(Project xml, boolean assignNewGuid, IParamNameMapper mapper, IWritableComponentNameCache cNC) throws InvalidDataException, InterruptedException { IProjectPO proj = initProject(xml, assignNewGuid); EntityManager attrDescSession = Persistor.instance().openSession(); try { fillProject(proj, xml, attrDescSession, assignNewGuid, mapper, cNC); } finally { Persistor.instance().dropSession(attrDescSession); } return proj; } /** * @param proj The project that will be filled. * @param attrDescSession The attribute session. * @param xml XML * @param assignNewGuid <code>true</code> if the project and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @param mapper a mapper * @param cNC the component name cache to use during project creation * @throws InvalidDataException * @see createProject(Project xml, boolean assignNewGuid, * IParamNameMapper mapper) */ private void fillProject(IProjectPO proj, Project xml, EntityManager attrDescSession, boolean assignNewGuid, IParamNameMapper mapper, IWritableComponentNameCache cNC) throws InvalidDataException, InterruptedException { IProjectPropertiesPO projectProperties = fillProjectProperties(proj, xml); if (xml.isSetTestResultDetailsCleanupInterval()) { proj.setTestResultCleanupInterval(xml.getTestResultDetailsCleanupInterval()); } else { proj.setTestResultCleanupInterval(IProjectPO.CLEANUP_DEFAULT); } for (ReusedProject reusedProj : xml.getReusedProjectsList()) { checkCancel(); proj.addUsedProject(createReusedProject(reusedProj)); } for (String projLang : xml.getProjectLanguageList()) { proj.getLangHelper().addLanguageToList(LocaleUtil.convertStrToLocale(projLang)); } for (Aut autXml : xml.getAutList()) { checkCancel(); proj.addAUTMain(createAUTMain(autXml, assignNewGuid)); } for (TestDataCategory testDataCategory : xml.getTestDataCategoryList()) { checkCancel(); proj.getTestDataCubeCont().addCategory(createTestDataCategory(testDataCategory, assignNewGuid, mapper)); } for (NamedTestData testDataCube : xml.getNamedTestDataList()) { checkCancel(); proj.getTestDataCubeCont().addTestData(createTestDataCube(testDataCube, assignNewGuid, mapper)); } for (Category catXml : xml.getCategoryList()) { checkCancel(); proj.getSpecObjCont().addSpecObject(createCategory(proj, catXml, assignNewGuid, mapper)); } for (TestCase tcXml : xml.getTestcaseList()) { checkCancel(); initTestCase(assignNewGuid, mapper, proj, tcXml); } for (Category catXml : xml.getCategoryList()) { checkCancel(); rerunCategories(proj, catXml, assignNewGuid, attrDescSession); } for (TestCase tcXml : xml.getTestcaseList()) { checkCancel(); completeTestCase(proj, tcXml, assignNewGuid, attrDescSession); } // BEGIN - pre 1.2 xml data model handling handleOldTestSuitesAndTestJobs(proj, xml, attrDescSession, assignNewGuid); // END - pre 1.2 xml data model handling handleTestSuitesAndTestJobsAndCategories(proj, xml, assignNewGuid); for (CheckConfiguration xmlConf : xml.getCheckConfigurationList()) { checkCancel(); initCheckConf(xmlConf, projectProperties.getCheckConfCont()); } if (xml.getTestresultSummaries() != null) { initTestResultSummaries(xml.getTestresultSummaries(), proj); } createComponentNames(xml, proj, cNC, assignNewGuid); } /** * @param proj * the project * @param xml * the project * @return the project properties */ public IProjectPropertiesPO fillProjectProperties(IProjectPO proj, Project xml) { proj.setComment(xml.getComment()); proj.setDefaultLanguage(LocaleUtil.convertStrToLocale(xml.getDefaultLanguage())); proj.setToolkit(xml.getAutToolKit()); proj.setIsReusable(xml.getIsReusable()); proj.setIsProtected(xml.getIsProtected()); IProjectPropertiesPO projectProperties = proj.getProjectProperties(); projectProperties.setALMRepositoryName(xml.getAlmRepositoryName()); projectProperties.setIsReportOnSuccess(xml.getIsReportOnSuccess()); projectProperties.setIsReportOnFailure(xml.getIsReportOnFailure()); projectProperties.setDashboardURL(xml.getDashboardURL()); projectProperties.getCheckConfCont().setEnabled(xml.getTeststyleEnabled()); return projectProperties; } /** * @param proj * the project po * @param xml * the project xml * @param assignNewGuid * flag to indicate whether new ids should be assigned * @throws InterruptedException * in case of interruption * @throws InvalidDataException * in case of invalid data */ private void handleTestSuitesAndTestJobsAndCategories(IProjectPO proj, Project xml, boolean assignNewGuid) throws InterruptedException, InvalidDataException { for (ExecCategory catXml : xml.getExecCategoriesList()) { checkCancel(); List<IExecPersistable> tsAndCats = createListOfCategoriesAndTestsuites(proj, catXml, assignNewGuid); for (IExecPersistable exec : tsAndCats) { proj.getExecObjCont().addExecObject(exec); } } for (ExecCategory catXml : xml.getExecCategoriesList()) { checkCancel(); List<IExecPersistable> tjs = createListOfTestJobs(catXml, assignNewGuid); for (IExecPersistable exec : tjs) { proj.getExecObjCont().addExecObject(exec); } } } /** * Handle "old"-XML data structure for pre 1.2 datamodel * * @param proj * the project * @param xml * the project xml * @param attrDescSession * the attribute description * @param assignNewGuid * whether new GUIDs should be assigned or not * @throws InterruptedException * in case of an interruption * @throws InvalidDataException * if some data is invalid when constructing an object. This * should not happen for exported project, but may happen when * someone generates XML project description outside of * GUIdancer. */ private void handleOldTestSuitesAndTestJobs(IProjectPO proj, Project xml, EntityManager attrDescSession, boolean assignNewGuid) throws InterruptedException, InvalidDataException { if (!xml.getTestsuiteList().isEmpty()) { ICategoryPO catTS = NodeMaker.createCategoryPO("Test Suites"); for (TestSuite tsXml : xml.getTestsuiteList()) { checkCancel(); ITestSuitePO tsPO = createTestSuite(proj, tsXml, assignNewGuid); catTS.addNode(tsPO); } proj.getExecObjCont().addExecObject(catTS); } if (!xml.getTestsuiteList().isEmpty()) { ICategoryPO catTJ = NodeMaker.createCategoryPO("Test Jobs"); for (TestJobs tjXml : xml.getTestJobsList()) { checkCancel(); catTJ.addNode(createTestJob(tjXml, assignNewGuid)); } proj.getExecObjCont().addExecObject(catTJ); } } /** * @param xmlConf * The source of the check configuration * @param checkConfCont * The destiny of the check configuration (will be persisted) */ private void initCheckConf(CheckConfiguration xmlConf, ICheckConfContPO checkConfCont) { if (xmlConf.getSeverity().matches("(0|1|2|3)")) { //$NON-NLS-1$ return; // its an old exported xml, just don't create the conf } ICheckConfPO chkConf = checkConfCont.createCheckConf(); chkConf.setSeverity(xmlConf.getSeverity()); chkConf.setActive(xmlConf.getActivated()); for (CheckAttribute xmlAttr : xmlConf.getCheckAttributeList()) { chkConf.getAttr().put(xmlAttr.getName(), xmlAttr.getValue()); } for (CheckActivatedContext xmlCxt : xmlConf.getActiveContextList()) { boolean active = xmlCxt.getActive(); chkConf.getContexts().put(xmlCxt.getClass1(), active); } checkConfCont.addCheckConf(xmlConf.getCheckId(), chkConf); } /** * @param xml XML storage for the project * @param assignNewGuid <code>true</code> if the project and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a new IProjectPO */ private IProjectPO initProject(Project xml, boolean assignNewGuid) { IProjectPO proj = null; if (xml.getGUID() != null && !assignNewGuid) { Integer majorProjVersion = xml.isSetMajorProjectVersion() ? xml.getMajorProjectVersion() : xml.getMajorNumber(); Integer minorProjVersion = xml.isSetMinorProjectVersion() ? xml.getMinorProjectVersion() : xml.getMinorNumber(); proj = NodeMaker.createProjectPO(IVersion.JB_CLIENT_METADATA_VERSION, majorProjVersion, minorProjVersion, xml.getGUID()); ProjectNameBP.getInstance().setName(xml.getGUID(), xml.getName(), false); } else { proj = NodeMaker.createProjectPO(xml.getName(), IVersion.JB_CLIENT_METADATA_VERSION); if (assignNewGuid) { m_oldToNewGuids.put(xml.getGUID(), proj.getGuid()); } } return proj; } /** * @param proj The project to which the test result summaries belongs. * @param trsListXml * The XML element for the test result summaries */ private void initTestResultSummaries(TestresultSummaries trsListXml, IProjectPO proj) { PropertyDescriptor[] propertiesToImport = BEAN_UTILS.getPropertyUtils() .getPropertyDescriptors(ITestResultSummary.class); for (TestresultSummary trsXml : trsListXml.getTestresultSummaryList()) { ITestResultSummaryPO summary = PoMaker.createTestResultSummaryPO(); summary.setInternalProjectGuid(proj.getGuid()); for (PropertyDescriptor pd : propertiesToImport) { List<SummaryAttribute> entries = trsXml.getAttributeList(); String propertyNameToSet = pd.getName(); boolean found = false; int pos = 0; for (SummaryAttribute me : entries) { if (me.getKey().equals(propertyNameToSet)) { found = true; break; } pos++; } if (found) { SummaryAttribute sa = entries.get(pos); if (!sa.isNilValue()) { try { BEAN_UTILS.setProperty(summary, propertyNameToSet, sa.getValue()); } catch (IllegalAccessException e) { log.warn(e.getLocalizedMessage(), e); } catch (InvocationTargetException e) { log.warn(e.getLocalizedMessage(), e); } } } else { log.warn(Messages.Property + StringConstants.SPACE + propertyNameToSet + StringConstants.SPACE + Messages.NotFound + StringConstants.DOT); } } List<MonitoringValues> tmpList = trsXml.getMonitoringValueList(); Map<String, IMonitoringValue> tmpMap = new HashMap<String, IMonitoringValue>(); for (int i = 0; i < tmpList.size(); i++) { MonitoringValues tmpMon = tmpList.get(i); MonitoringValue tmp = new MonitoringValue(); tmp.setCategory(tmpMon.getCategory()); tmp.setSignificant(tmpMon.getIsSignificant()); tmp.setType(tmpMon.getType()); tmp.setValue(tmpMon.getValue()); tmpMap.put(tmpMon.getKey(), tmp); } summary.setMonitoringValues(tmpMap); if (!TestResultSummaryPM.doesTestResultSummaryExist(summary)) { TestResultSummaryPM.storeTestResultSummaryInDB(summary); } } } /** * Creates and initializes a test case. * * @param assignNewGuid <code>true</code> if the test case and all * sub-elements should be assigned new GUIDs. Otherwise * <code>false</code>. * @param mapper Mapper to resolve param names. * @param proj The project to which the test case belongs. * @param tcXml The XML element for the test case. */ private void initTestCase(boolean assignNewGuid, IParamNameMapper mapper, IProjectPO proj, TestCase tcXml) { ISpecTestCasePO tcPO = createTestCaseBase(proj, tcXml, assignNewGuid, mapper); proj.getSpecObjCont().addSpecObject(tcPO); } /** * Checks whether the operation has been canceled. If the operation has been * canceled, an <code>InterruptedException</code> will be thrown. * * @throws InterruptedException if the operation has been canceled. */ private void checkCancel() throws InterruptedException { if (m_monitor.isCanceled()) { throw new InterruptedException(); } } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the testcase and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @param attrDescSession The session used for locating attribute * descriptions in the database. * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private ISpecTestCasePO completeTestCase(IProjectPO proj, TestCase xml, boolean assignNewGuid, EntityManager attrDescSession) throws InvalidDataException { ISpecTestCasePO tc; if (xml.getId() != null) { tc = m_tcRef.get(xml.getId()); } else if (assignNewGuid) { tc = m_tcRef.get(m_oldToNewGuids.get(xml.getGUID())); } else { tc = m_tcRef.get(xml.getGUID()); } for (Teststep stepXml : xml.getTeststepList()) { if (stepXml.getCap() != null) { tc.addNode(createCap(proj, stepXml.getCap(), assignNewGuid)); } else { tc.addNode(createExecTestCase(proj, stepXml.getUsedTestcase(), assignNewGuid)); } } for (EventTestCase evTcXml : xml.getEventTestcaseList()) { tc.addEventTestCase(createEventExecTestCase(proj, tc, evTcXml, assignNewGuid)); } return tc; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the AUT Config * should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element */ private IAUTConfigPO createAUTConfig(AutConfig xml, boolean assignNewGuid) { IAUTConfigPO conf = null; if (xml.getGUID() != null && !assignNewGuid) { // GUID is available conf = PoMaker.createAUTConfigPO(xml.getGUID()); } else { conf = PoMaker.createAUTConfigPO(); } m_autConfRef.put(xml.getId(), conf); // FIXME BEGIN : only for compatibility reasons. Remove in version > 2.0 conf.setValue(AutConfigConstants.CLASSNAME, xml.getClassname()); conf.setValue(AutConfigConstants.CLASSPATH, xml.getClasspath()); conf.setValue(AutConfigConstants.JAR_FILE, xml.getJarfile()); conf.setValue(AutConfigConstants.AUT_ARGUMENTS, xml.getParameter()); conf.setValue(AutConfigConstants.WORKING_DIR, xml.getWorkingDir()); conf.setValue(AutConfigConstants.JRE_BINARY, xml.getJreDir()); conf.setValue(AutConfigConstants.JRE_PARAMETER, xml.getJreParameter()); conf.setValue(AutConfigConstants.SERVER, xml.getServer()); conf.setValue(AutConfigConstants.ENVIRONMENT, xml.getEnvironment()); conf.setValue(AutConfigConstants.ACTIVATE_APPLICATION, String.valueOf(xml.getActivateApp())); conf.setValue(AutConfigConstants.CONFIG_NAME, String.valueOf(xml.getName())); conf.setValue(AutConfigConstants.ACTIVATION_METHOD, ActivationMethod.getRCString(xml.getActivationMethod().toString())); // FIXME END final List<MapEntry> confAttrMapList = xml.getConfAttrMapEntryList(); for (MapEntry entry : confAttrMapList) { final String key = entry.getKey(); final String value = entry.getValue(); conf.setValue(key, value); } return conf; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the AUT and all corresponding * AUT Configs should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element */ private IAUTMainPO createAUTMain(Aut xml, boolean assignNewGuid) { IAUTMainPO aut = null; if (xml.getGUID() != null && !assignNewGuid) { // GUID is available aut = PoMaker.createAUTMainPO(xml.getName(), xml.getGUID()); } else { aut = PoMaker.createAUTMainPO(xml.getName()); } aut.setToolkit(xml.getAutToolkit()); aut.setGenerateNames(xml.getGenerateNames()); m_autRef.put(xml.getId(), aut); aut.setObjMap(createOM(xml)); for (String lang : xml.getLanguageList()) { aut.getLangHelper().addLanguageToList(LocaleUtil.convertStrToLocale(lang)); } for (AutConfig confXml : xml.getConfigList()) { aut.addAutConfigToSet(createAUTConfig(confXml, assignNewGuid)); } for (String autId : xml.getAutIdList()) { aut.getAutIds().add(autId); } return aut; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans) * @return a persistent object generated from the information in the XML * element */ private IReusedProjectPO createReusedProject(ReusedProject xml) { Integer majorProjVersion = xml.isSetMajorProjectVersion() ? xml.getMajorProjectVersion() : xml.getMajorNumber(); Integer minorProjVersion = xml.isSetMinorProjectVersion() ? xml.getMinorProjectVersion() : xml.getMinorNumber(); IReusedProjectPO reusedProject = PoMaker.createReusedProjectPO(xml.getProjectGUID(), majorProjVersion, minorProjVersion); return reusedProject; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the cap * should be assigned a new GUID. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element */ private ICapPO createCap(IProjectPO proj, Cap xml, boolean assignNewGuid) { final ICapPO cap; String componentname = xml.getComponentName(); if (componentHasDefaultMapping(xml.getComponentType())) { componentname = null; } if (xml.getGUID() != null && !assignNewGuid) { // GUID is available cap = NodeMaker.createCapPO(xml.getName(), componentname, xml.getComponentType(), xml.getActionName(), proj, xml.getGUID()); } else { cap = NodeMaker.createCapPO(xml.getName(), componentname, xml.getComponentType(), xml.getActionName(), proj); } cap.setDataFile(xml.getDatafile()); if (xml.isSetActive()) { cap.setActive(xml.getActive()); } else { cap.setActive(true); } if (xml.getComment() != null) { cap.setComment(xml.getComment()); } if (xml.getTestdata() != null) { ITDManager tdman = fillTDManager(cap, xml); cap.setDataManager(tdman); } return cap; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the category and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @param mapper mapper to resolve param names * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private ISpecPersistable createCategory(IProjectPO proj, Category xml, boolean assignNewGuid, IParamNameMapper mapper) throws InvalidDataException { ICategoryPO cat; if (xml.getGUID() != null && !assignNewGuid) { cat = NodeMaker.createCategoryPO(xml.getName(), xml.getGUID()); } else { cat = NodeMaker.createCategoryPO(xml.getName()); } cat.setGenerated(xml.getGenerated()); cat.setComment(xml.getComment()); cat.setTaskId(xml.getTaskId()); for (Category catXml : xml.getCategoryList()) { cat.addNode(createCategory(proj, catXml, assignNewGuid, mapper)); } for (TestCase tcXml : xml.getTestcaseList()) { cat.addNode(createTestCaseBase(proj, tcXml, assignNewGuid, mapper)); } return cat; } /** * Creates the instance of the persistent object which is defined by the * XML element used as parameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the category and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private List<IExecPersistable> createListOfCategoriesAndTestsuites(IProjectPO proj, ExecCategory xml, boolean assignNewGuid) throws InvalidDataException { List<IExecPersistable> execNodes = new ArrayList<IExecPersistable>(); for (ExecCategory catXml : xml.getCategoryList()) { execNodes.add(createExecObjects(proj, catXml, assignNewGuid)); } for (TestSuite tsXml : xml.getTestsuiteList()) { execNodes.add(createTestSuite(proj, tsXml, assignNewGuid)); } return execNodes; } /** * Creates the instance of the persistent object which is defined by the * XML element used as parameter. The method generates all dependend objects * as well. * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the category and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private List<IExecPersistable> createListOfTestJobs(ExecCategory xml, boolean assignNewGuid) throws InvalidDataException { List<IExecPersistable> execNodes = new ArrayList<IExecPersistable>(); for (ExecCategory catXml : xml.getCategoryList()) { createTestJobs(catXml, assignNewGuid); } for (TestJobs tjXml : xml.getTestjobList()) { execNodes.add(createTestJob(tjXml, assignNewGuid)); } return execNodes; } /** * Creates the instance of the persistent object which is defined by the * XML element used as parameter. The method generates all dependend objects * as well. * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the category and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private void createTestJobs(ExecCategory xml, boolean assignNewGuid) throws InvalidDataException { for (ExecCategory catXml : xml.getCategoryList()) { createTestJobs(catXml, assignNewGuid); } String guid = xml.getGUID(); if (assignNewGuid) { guid = m_oldToNewGuids.get(guid); } ICategoryPO cat = m_execCategoryCache.get(guid); for (TestJobs tjXml : xml.getTestjobList()) { cat.addNode(createTestJob(tjXml, assignNewGuid)); } } /** * Creates the instance of the persistent object which is defined by the * XML element used as parameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the category and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private IExecPersistable createExecObjects(IProjectPO proj, ExecCategory xml, boolean assignNewGuid) throws InvalidDataException { ICategoryPO cat; if (xml.getGUID() != null && !assignNewGuid) { cat = NodeMaker.createCategoryPO(xml.getName(), xml.getGUID()); m_execCategoryCache.put(xml.getGUID(), cat); } else { cat = NodeMaker.createCategoryPO(xml.getName()); m_execCategoryCache.put(cat.getGuid(), cat); m_oldToNewGuids.put(xml.getGUID(), cat.getGuid()); } cat.setGenerated(xml.getGenerated()); cat.setComment(xml.getComment()); cat.setTaskId(xml.getTaskId()); for (ExecCategory catXml : xml.getCategoryList()) { cat.addNode(createExecObjects(proj, catXml, assignNewGuid)); } for (TestSuite tsXml : xml.getTestsuiteList()) { cat.addNode(createTestSuite(proj, tsXml, assignNewGuid)); } return cat; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param tc Testcase which holds the newly created EventExecTC. * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the test case * should be assigned a new GUID. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private IEventExecTestCasePO createEventExecTestCase(IProjectPO proj, ISpecTestCasePO tc, EventTestCase xml, boolean assignNewGuid) throws InvalidDataException { IEventExecTestCasePO evTc; ISpecTestCasePO refTc; if (xml.getTestcaseRef() != null) { refTc = findReferencedTC(xml.getTestcaseRef()); } else { refTc = findReferencedTCByGuid(xml.getTestcaseGuid(), xml.getProjectGuid(), proj, assignNewGuid); } if (refTc == null) { // SpectTC is not yet available in this DB if (assignNewGuid) { evTc = NodeMaker.createEventExecTestCasePO(xml.getTestcaseGuid(), xml.getProjectGuid(), tc); } else { evTc = NodeMaker.createEventExecTestCasePO(xml.getTestcaseGuid(), xml.getProjectGuid(), tc, xml.getGUID()); } } else { if (xml.getGUID() != null && !assignNewGuid) { evTc = NodeMaker.createEventExecTestCasePO(refTc, tc, xml.getGUID()); } else { evTc = NodeMaker.createEventExecTestCasePO(refTc, tc); } } fillExecTestCase(proj, xml, evTc, assignNewGuid); evTc.setEventType(xml.getEventType()); ReentryProperty reentryProperty = ReentryProperty.getProperty(xml.getReentryProperty().intValue()); evTc.setReentryProp(reentryProperty); if (reentryProperty == ReentryProperty.RETRY) { evTc.setMaxRetries(xml.isSetMaxRetries() ? xml.getMaxRetries() : 1); } // Clear the cached specTc to avoid LazyInitializationExceptions evTc.clearCachedSpecTestCase(); return evTc; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the testcase and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element */ private IExecTestCasePO createExecTestCase(IProjectPO proj, RefTestCase xml, boolean assignNewGuid) { IExecTestCasePO exec; ISpecTestCasePO refTc; if (xml.getTestcaseRef() != null) { refTc = findReferencedTC(xml.getTestcaseRef()); } else { refTc = findReferencedTCByGuid(xml.getTestcaseGuid(), xml.getProjectGuid(), proj, assignNewGuid); } if (refTc == null) { // SpectTC is not yet available in this DB if (!assignNewGuid) { exec = NodeMaker.createExecTestCasePO(xml.getTestcaseGuid(), xml.getProjectGuid(), xml.getGUID()); } else { exec = NodeMaker.createExecTestCasePO(xml.getTestcaseGuid(), xml.getProjectGuid()); } } else { if (xml.getGUID() != null && !assignNewGuid) { // GUID is available exec = NodeMaker.createExecTestCasePO(refTc, xml.getGUID()); } else { exec = NodeMaker.createExecTestCasePO(refTc); } } fillExecTestCase(proj, xml, exec, assignNewGuid); // Clear the cached specTc to avoid LazyInitializationExceptions exec.clearCachedSpecTestCase(); return exec; } /** * Creates the instance of the persistent object which is defined by the * XML element used as parameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans) * @return a persistent object generated from the information in the XML * element */ private IObjectMappingPO createOM(Aut xml) { IObjectMappingPO om = PoMaker.createObjectMappingPO(); ObjectMapping omXml = xml.getObjectMapping(); ObjectMappingProfile profileXml = omXml.getProfile(); if (profileXml != null) { // Use the profile defined in the imported project IObjectMappingProfilePO profilePo = PoMaker.createObjectMappingProfile(); profilePo.setContextFactor(profileXml.getContextFactor()); profilePo.setNameFactor(profileXml.getNameFactor()); profilePo.setPathFactor(profileXml.getPathFactor()); profilePo.setThreshold(profileXml.getThreshold()); om.setProfile(profilePo); } OmCategory mappedCategoryXml = omXml.getMapped(); if (mappedCategoryXml != null) { fillObjectMappingCategory(mappedCategoryXml, om.getMappedCategory()); } OmCategory unmappedComponentCategory = omXml.getUnmappedComponent(); if (unmappedComponentCategory != null) { fillObjectMappingCategory(unmappedComponentCategory, om.getUnmappedLogicalCategory()); } OmCategory unmappedTechnicalCategory = omXml.getUnmappedTechnical(); if (unmappedTechnicalCategory != null) { fillObjectMappingCategory(unmappedTechnicalCategory, om.getUnmappedTechnicalCategory()); } return om; } /** * Write the information from the XML element to its corresponding Object. * * @param categoryXml * The XML element which contains the information * @param category * The persistent object Object */ @SuppressWarnings({ "rawtypes", "unchecked" }) private void fillObjectMappingCategory(OmCategory categoryXml, IObjectMappingCategoryPO category) { category.setName(categoryXml.getName()); for (OmCategory subcategoryXml : categoryXml.getCategoryList()) { IObjectMappingCategoryPO subcategory = PoMaker.createObjectMappingCategoryPO(subcategoryXml.getName()); category.addCategory(subcategory); fillObjectMappingCategory(subcategoryXml, subcategory); } for (OmEntry assocXml : categoryXml.getAssociationList()) { TechnicalName tecNameXml = assocXml.getTechnicalName(); List<String> logNames = assocXml.getLogicalNameList(); IComponentIdentifier tecName = null; if (tecNameXml != null && !tecNameXml.isNil()) { tecName = new ComponentIdentifier(); tecName.setComponentClassName(tecNameXml.getComponentClassName()); tecName.setSupportedClassName(tecNameXml.getSupportedClassName()); tecName.setAlternativeDisplayName(tecNameXml.getAlternativeDisplayName()); tecName.setNeighbours(new ArrayList(tecNameXml.getNeighbourList())); tecName.setHierarchyNames(new ArrayList(tecNameXml.getHierarchyNameList())); } // It is necessary to create a new (cloneable) list from the list // of component names because the list itself is not cloneable. // If the list is used directly, then IObjectMappingAssoziationPO assoc = PoMaker.createObjectMappingAssoziationPO(tecName, new ArrayList<String>(logNames)); assoc.setType(assocXml.getType()); category.addAssociation(assoc); } } /** * This method is called if the Action of a CAP is not compatible with the * current XML-Config-File.<br> * The existent TDManager of the CAP is filled with the TestData * @param owner The CAP. * @param xmlCap The abstraction of the XML CAP (see Apache XML Beans) * @return the filled TDManager of the given owner */ private ITDManager fillTDManager(IParamNodePO owner, Cap xmlCap) { final ITDManager tdman = owner.getDataManager(); List<ParamDescription> parDescList = xmlCap.getParameterDescriptionList(); final TestData testData = xmlCap.getTestdata(); int tdRow = 0; for (TestDataRow rowXml : testData.getRowList()) { if (rowXml.getDataList().isEmpty()) { // Bug 337215 may have caused Test Steps in exported Projects // to incorrectly contain multiple Data Sets. These erroneous // Data Sets seem to always be empty, so ignore empty Data Sets // for imported Test Steps. continue; } List<ITestDataPO> tdList = null; try { tdList = tdman.getDataSet(tdRow).getList(); } catch (IndexOutOfBoundsException ioobe) { // Component, Action, and/or Parameter could not be found in config xml // only log and continue -> import of projects with missing plugins //FIXME: NLS Look at "CompSystemI18n.getStri[...]" final StringBuilder msgSb = new StringBuilder(); msgSb.append(Messages.Component); msgSb.append(StringConstants.COLON + StringConstants.SPACE); msgSb.append(xmlCap.getComponentType()); msgSb.append(StringConstants.NEWLINE + Messages.Action); msgSb.append(StringConstants.COLON + StringConstants.SPACE); msgSb.append(CompSystemI18n.getString(xmlCap.getActionName(), true)); msgSb.append(StringConstants.NEWLINE + Messages.Parameter); msgSb.append(StringConstants.COLON + StringConstants.SPACE); msgSb.append(CompSystemI18n.getString(parDescList.get(tdRow).getName(), true)); final String msg = msgSb.toString(); log.error(msg, ioobe); continue; } int tdCell = 0; for (TestDataCell cellXml : rowXml.getDataList()) { String uniqueId = parDescList.get(tdCell).getUniqueId(); final int ownerIndex = owner.getDataManager().findColumnForParam(uniqueId); if (ownerIndex > -1) { // only relevant for old projects tdList.set(ownerIndex, PoMaker.createTestDataPO(readData(cellXml, owner))); } tdCell++; } // We need to clear the data manager first because a Test Step // can only have one Data Set, and we want to insert the Data Set // as a single unit (rather than updating each cell individually) tdman.clear(); tdman.insertDataSet(PoMaker.createListWrapperPO(tdList), tdRow); tdRow++; } return tdman; } /** * @param cellXml associated cell from import * @param owner The owner of the data. * @return the map read from the provided data. */ private Map<Locale, String> readData(TestDataCell cellXml, IParameterInterfacePO owner) { Map<Locale, String> localeToValue = new HashMap<Locale, String>(); for (I18NString i18nVal : cellXml.getDataList()) { if (i18nVal != null && !i18nVal.isNil() && i18nVal.getValue() != null && !(i18nVal.getValue().length() == 0)) { String i18nValString = i18nVal.getValue(); try { // Since we are not using the converter for anything other than // parsing, we can use null for paramDesc ModelParamValueConverter converter = new ModelParamValueConverter(i18nValString, owner, LocaleUtil.convertStrToLocale(i18nVal.getLanguage()), null); if (!converter.containsErrors()) { // Only try to replace reference GUIDs if the // string could be successfully parsed. // Otherwise, the model string will be overwritten with // the empty string because no tokens were created // during parsing. converter.replaceGuidsInReferences(m_oldToNewGuids); } else { m_unparseableParameters.add(i18nValString); } i18nValString = converter.getModelString(); } catch (IllegalArgumentException iae) { // Do nothing. // The i18nValue uses the old format and can therefore // not be parsed. This value will be converted in V1M42Converter. } localeToValue.put(LocaleUtil.convertStrToLocale(i18nVal.getLanguage()), i18nValString); } } return localeToValue; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans). * @param assignNewGuids <code>true</code> if the parameters were given * new unique IDs. Otherwise <code>false</code>. * @param mapper Mapper to resolve param names. * @return a persistent object generated from the information in the XML * element */ private ITestDataCategoryPO createTestDataCategory(TestDataCategory xml, boolean assignNewGuids, IParamNameMapper mapper) { ITestDataCategoryPO testDataCategory = PoMaker.createTestDataCategoryPO(xml.getName()); for (TestDataCategory subCategory : xml.getTestDataCategoryList()) { testDataCategory.addCategory(createTestDataCategory(subCategory, assignNewGuids, mapper)); } for (NamedTestData testData : xml.getNamedTestDataList()) { testDataCategory.addTestData(createTestDataCube(testData, assignNewGuids, mapper)); } return testDataCategory; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans). * @param assignNewGuids <code>true</code> if the parameters were given * new unique IDs. Otherwise <code>false</code>. * @param mapper Mapper to resolve param names. * @return a persistent object generated from the information in the XML * element */ private ITestDataCubePO createTestDataCube(NamedTestData xml, boolean assignNewGuids, IParamNameMapper mapper) { ITestDataCubePO testDataCube = PoMaker.createTestDataCubePO(xml.getName()); for (ParamDescription xmlParamDesc : xml.getParameterDescriptionList()) { if (assignNewGuids) { IParamDescriptionPO paramDesc = testDataCube.addParameter(xmlParamDesc.getType(), xmlParamDesc.getName(), mapper); m_oldToNewGuids.put(xmlParamDesc.getUniqueId(), paramDesc.getUniqueId()); } else { testDataCube.addParameter(xmlParamDesc.getType(), xmlParamDesc.getName(), xmlParamDesc.getUniqueId(), mapper); } } testDataCube.setDataManager(createTDManager(testDataCube, xml.getTestData(), assignNewGuids)); return testDataCube; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param owner The ParamNode which holds this TDManager * @param xml Abstraction of the XML element (see Apache XML Beans) * the test data, otherwise a new TDManager is created. * @return a persistent object generated from the information in the XML * element * @param assignNewGuids <code>true</code> if the parameters were given * new unique IDs. Otherwise <code>false</code>. */ private ITDManager createTDManager(IParameterInterfacePO owner, TestData xml, boolean assignNewGuids) { List<String> uniqueIds = new ArrayList<String>(xml.getUniqueIdsList()); final ITDManager tdman; if (assignNewGuids) { // Update list of unique IDs List<String> newUniqueIds = new ArrayList<String>(); for (String id : uniqueIds) { if (Pattern.matches("[0-9a-fA-F]{" + GUID_LENGTH + "}", id) //$NON-NLS-1$ //$NON-NLS-2$ && m_oldToNewGuids.containsKey(id)) { // Use new GUID newUniqueIds.add(m_oldToNewGuids.get(id)); } else { // Leave as-is newUniqueIds.add(id); } } uniqueIds = newUniqueIds; } if (uniqueIds.isEmpty()) { tdman = PoMaker.createTDManagerPO(owner); } else { tdman = PoMaker.createTDManagerPO(owner, uniqueIds); } for (TestDataRow rowXml : xml.getRowList()) { final List<ITestDataPO> td = new ArrayList<ITestDataPO>(rowXml.sizeOfDataArray()); for (TestDataCell cellXml : rowXml.getDataList()) { td.add(PoMaker.createTestDataPO(readData(cellXml, owner))); } tdman.insertDataSet(PoMaker.createListWrapperPO(td), tdman.getDataSetCount()); } return tdman; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the testcase * should be assigned a new GUID. Otherwise * <code>false</code>. * @param mapper mapper to resolve param names * @return a persistent object generated from the information in the XML * element */ private ISpecTestCasePO createTestCaseBase(IProjectPO proj, TestCase xml, boolean assignNewGuid, IParamNameMapper mapper) { ISpecTestCasePO tc; if (xml.getId() != null) { tc = NodeMaker.createSpecTestCasePO(xml.getName()); m_tcRef.put(xml.getId(), tc); } else if (assignNewGuid) { tc = NodeMaker.createSpecTestCasePO(xml.getName()); m_tcRef.put(tc.getGuid(), tc); m_oldToNewGuids.put(xml.getGUID(), tc.getGuid()); } else { tc = NodeMaker.createSpecTestCasePO(xml.getName(), xml.getGUID()); m_tcRef.put(xml.getGUID(), tc); } tc.setComment(xml.getComment()); tc.setGenerated(xml.getGenerated()); tc.setTaskId(xml.getTaskId()); tc.setInterfaceLocked(xml.getInterfaceLocked()); tc.setDataFile(xml.getDatafile()); if (xml.getReferencedTestData() != null) { String referencedDataName = xml.getReferencedTestData(); for (IParameterInterfacePO testDataCube : TestDataCubeBP.getAllTestDataCubesFor(proj)) { if (referencedDataName.equals(testDataCube.getName())) { tc.setReferencedDataCube(testDataCube); break; } } } for (ParamDescription pdXml : xml.getParameterDescriptionList()) { String uniqueId = pdXml.getUniqueId(); if (assignNewGuid) { IParamDescriptionPO paramDesc = tc.addParameter(pdXml.getType(), pdXml.getName(), mapper); m_oldToNewGuids.put(uniqueId, paramDesc.getUniqueId()); } else { if (uniqueId != null && Pattern.matches("[0-9a-fA-F]{" + GUID_LENGTH + "}", uniqueId)) { //$NON-NLS-1$ //$NON-NLS-2$ // use the existent guid for parameter tc.addParameter(pdXml.getType(), pdXml.getName(), uniqueId, mapper); } else { // creates a new GUID for parameter (only for conversion of // old projects) tc.addParameter(pdXml.getType(), pdXml.getName(), mapper); } } } tc.setDataManager(createTDManager(tc, xml.getTestdata(), assignNewGuid)); return tc; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the test suite * should be assigned a new GUID. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element */ private ITestSuitePO createTestSuite(IProjectPO proj, TestSuite xml, boolean assignNewGuid) { ITestSuitePO ts; if (xml.getGUID() != null && !assignNewGuid) { ts = NodeMaker.createTestSuitePO(xml.getName(), xml.getGUID()); } else { ts = NodeMaker.createTestSuitePO(xml.getName()); } if (assignNewGuid) { m_oldToNewGuids.put(xml.getGUID(), ts.getGuid()); } ts.setComment(xml.getComment()); ts.setTaskId(xml.getTaskId()); ts.setCmdLineParameter(xml.getCommandLineParameter()); if (xml.getSelectedAut() != null) { ts.setAut(findReferencedAut(xml.getSelectedAut())); } for (RefTestCase refXml : xml.getUsedTestcaseList()) { ts.addNode(createExecTestCase(proj, refXml, assignNewGuid)); } Map<String, Integer> defaultEventHandler = new HashMap<String, Integer>(); for (EventHandler evhXml : xml.getEventHandlerList()) { defaultEventHandler.put(evhXml.getEvent(), evhXml.getReentryProperty().intValue()); // Trac#1908 no place to store the max. number of retries } ts.setDefaultEventHandler(defaultEventHandler); ts.setStepDelay(xml.getStepDelay()); return ts; } /** * Creates the instance of the persistent object which is defined by the * XML element used as prameter. The method generates all dependend objects * as well. * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the test suite * should be assigned a new GUID. Otherwise * <code>false</code>. * @return a persistent object generated from the information in the XML * element * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. */ private ITestJobPO createTestJob(TestJobs xml, boolean assignNewGuid) throws InvalidDataException { ITestJobPO tj; if (xml.getGUID() != null && !assignNewGuid) { tj = NodeMaker.createTestJobPO(xml.getName(), xml.getGUID()); } else { tj = NodeMaker.createTestJobPO(xml.getName()); } tj.setComment(xml.getComment()); tj.setTaskId(xml.getTaskId()); for (RefTestSuite xmlRts : xml.getRefTestSuiteList()) { IRefTestSuitePO rts; if (assignNewGuid) { // Only Test Suites from the same project can be referenced, // and all Test Suites for this Project have already been // initialized (so they have already been entered into the // old to new GUID map). This is why we can simply directly use // the old to new GUID map. String testSuiteGuid = m_oldToNewGuids.get(xmlRts.getTsGuid()); if (testSuiteGuid == null) { throw new InvalidDataException( "Test Suite Reference: No new GUID found for Test Suite with old GUID: " //$NON-NLS-1$ + xmlRts.getTsGuid(), MessageIDs.E_IMPORT_PROJECT_XML_FAILED); } rts = NodeMaker.createRefTestSuitePO(xmlRts.getName(), testSuiteGuid, xmlRts.getAutId()); } else { rts = NodeMaker.createRefTestSuitePO(xmlRts.getName(), xmlRts.getGUID(), xmlRts.getTsGuid(), xmlRts.getAutId()); } rts.setComment(xmlRts.getComment()); tj.addNode(rts); } return tj; } /** * Shared method for setting values into ExecTCs and their subclasses. * * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param exec TC to be initialized * @param assignNewGuid <code>true</code> if nodes are being assigned * new GUIDs. Otherwise <code>false</code>. */ private void fillExecTestCase(IProjectPO proj, RefTestCase xml, IExecTestCasePO exec, boolean assignNewGuid) { exec.setName(xml.getName()); exec.setComment(xml.getComment()); exec.setGenerated(xml.getGenerated()); exec.setTaskId(xml.getTaskId()); if (xml.isSetActive()) { exec.setActive(xml.getActive()); } else { exec.setActive(true); } exec.setDataFile(xml.getDatafile()); if (xml.getReferencedTestData() != null) { String referencedDataName = xml.getReferencedTestData(); for (IParameterInterfacePO testDataCube : TestDataCubeBP.getAllTestDataCubesFor(proj)) { if (referencedDataName.equals(testDataCube.getName())) { exec.setReferencedDataCube(testDataCube); break; } } } if (xml.getHasOwnTestdata()) { // ExecTestCasePO doesn't have an own parameter list. // It uses generally the parameter from the associated // SpecTestCase. exec.setDataManager(createTDManager(exec, xml.getTestdata(), assignNewGuid)); } for (CompNames overriddenXml : xml.getOverriddenNamesList()) { final ICompNamesPairPO compName = PoMaker.createCompNamesPairPO(overriddenXml.getOriginalName(), overriddenXml.getNewName(), overriddenXml.getType()); compName.setPropagated(overriddenXml.getPropagated()); exec.addCompNamesPair(compName); } m_monitor.worked(1); } /** * Find a persistent object which has an XML id. * * @param selectedAut The XML id used to identify this instance * @return the object build while reading the XML element */ private IAUTMainPO findReferencedAut(String selectedAut) { return m_autRef.get(selectedAut); } /** * Find a persistent object which has an XML id. * * @param usedTestcase The XML id used to identify this instance * @return the object build while reading the XML element, or * <code>null</code> if the object cannot be found */ private ISpecTestCasePO findReferencedTC(String usedTestcase) { return m_tcRef.get(usedTestcase); } /** * Find a persistent object which has a GUID. * * @param usedTestcaseGuid The GUID used to identify this instance * @param projectGuid The GUID of the spec testcase's parent project * @param parentProject The parent project of the exec testcase * @param assignNewGuid <code>true</code> if elements are being assigned new * GUIDs. Otherwise <code>false</code>. * @return the object build while reading the XML element, or * <code>null</code> if the object cannot be found */ private ISpecTestCasePO findReferencedTCByGuid(String usedTestcaseGuid, String projectGuid, IProjectPO parentProject, boolean assignNewGuid) { String actualProjectGuid = assignNewGuid ? m_oldToNewGuids.get(projectGuid) : projectGuid; if (projectGuid == null || parentProject.getGuid().equals(actualProjectGuid)) { // Referenced TC is in same project if (assignNewGuid) { return m_tcRef.get(m_oldToNewGuids.get(usedTestcaseGuid)); } return m_tcRef.get(usedTestcaseGuid); } // Referenced TC is in different project return NodePM.getSpecTestCase(parentProject.getUsedProjects(), projectGuid, usedTestcaseGuid); } /** * This is the second run on categories. The first time the categories were * created and the contained TestCases were initialized. In this run all * TestCases will be completed. * @param proj The IProjectPO which is currently build. The instance is * needed by some objects to verify that their data confirms to project * specification (for instance languages). * @param xml Abstraction of the XML element (see Apache XML Beans) * @param assignNewGuid <code>true</code> if the category and all subnodes * should be assigned new GUIDs. Otherwise * <code>false</code>. * @param attrDescSession The session used for locating attribute * descriptions in the database. * @throws InvalidDataException if some data is invalid when constructing * an object. This should not happen for exported project, but may happen * when someone generates XML project description outside of GUIdancer. * @throws InterruptedException if the operation was canceled. */ private void rerunCategories(IProjectPO proj, Category xml, boolean assignNewGuid, EntityManager attrDescSession) throws InvalidDataException, InterruptedException { for (Category catXml : xml.getCategoryList()) { checkCancel(); rerunCategories(proj, catXml, assignNewGuid, attrDescSession); } for (TestCase tcXml : xml.getTestcaseList()) { checkCancel(); completeTestCase(proj, tcXml, assignNewGuid, attrDescSession); } } /** * * @param componentType * component type name * @return true if the component has a default mapping and therefore has no * component name */ private boolean componentHasDefaultMapping(String componentType) { Component component = ComponentBuilder.getInstance().getCompSystem().findComponent(componentType); if (component.isConcrete()) { return ((ConcreteComponent) component).hasDefaultMapping(); } return false; } }