/*******************************************************************************
* 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.ConvertUtilsBean;
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.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.ObjectMappingAssoziationConverter;
import org.eclipse.jubula.client.archive.converter.RefTSNameConverter;
import org.eclipse.jubula.client.archive.converter.TreeDirectionConverter;
import org.eclipse.jubula.client.archive.converter.V4C001;
import org.eclipse.jubula.client.archive.i18n.Messages;
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.Comment;
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.Node;
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.ReportingRule;
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.TestJobs.Testjobelement;
import org.eclipse.jubula.client.archive.schema.TestSuite;
import org.eclipse.jubula.client.archive.schema.TestSuite.Testsuiteelement;
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.Activator;
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.IALMReportingRulePO;
import org.eclipse.jubula.client.core.model.IAUTConfigPO;
import org.eclipse.jubula.client.core.model.IAUTMainPO;
import org.eclipse.jubula.client.core.model.IArchivableTestResultSummary;
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.ICommentPO;
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.ITestJobPO;
import org.eclipse.jubula.client.core.model.ITestResultSummaryPO;
import org.eclipse.jubula.client.core.model.ITestResultSummaryPO.AlmReportStatus;
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.ProjectVersion;
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.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.LocaleUtil;
import org.eclipse.jubula.client.core.utils.ModelParamValueConverter;
import org.eclipse.jubula.client.core.utils.ReportRuleType;
import org.eclipse.jubula.client.core.utils.TrackingUnit;
import org.eclipse.jubula.toolkit.common.businessprocess.ToolkitSupportBP;
import org.eclipse.jubula.toolkit.common.exception.ToolkitPluginException;
import org.eclipse.jubula.toolkit.common.xml.businessprocess.ComponentBuilder;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.constants.ToolkitConstants;
import org.eclipse.jubula.tools.internal.exception.Assert;
import org.eclipse.jubula.tools.internal.exception.InvalidDataException;
import org.eclipse.jubula.tools.internal.exception.JBVersionException;
import org.eclipse.jubula.tools.internal.i18n.CompSystemI18n;
import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs;
import org.eclipse.jubula.tools.internal.objects.ComponentIdentifier;
import org.eclipse.jubula.tools.internal.objects.IComponentIdentifier;
import org.eclipse.jubula.tools.internal.objects.IMonitoringValue;
import org.eclipse.jubula.tools.internal.objects.MonitoringValue;
import org.eclipse.jubula.tools.internal.version.IVersion;
import org.eclipse.jubula.tools.internal.xml.businessmodell.Component;
import org.eclipse.jubula.tools.internal.xml.businessmodell.ConcreteComponent;
import org.eclipse.jubula.tools.internal.xml.businessmodell.Profile;
import org.eclipse.jubula.tools.internal.xml.businessmodell.ToolkitDescriptor;
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);
}
}
if (arg0.isAssignableFrom(AlmReportStatus.class)) {
try {
return AlmReportStatus.valueOf(String.valueOf(arg1));
} catch (Throwable e) {
throw new ConversionException(e);
}
}
throw new ConversionException("Type " + arg0.getCanonicalName() //$NON-NLS-1$
+ " not supported for conversion."); //$NON-NLS-1$
}
};
ConvertUtilsBean convertUtils = BEAN_UTILS.getConvertUtils();
convertUtils.register(stringConverter, String.class);
convertUtils.register(converter, Date.class);
}
/** 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>();
/** whether to skip the import of tracked data */
private boolean m_skipTrackingInformation = false;
/** the old default language */
private Locale m_oldDefaultLanguage = null;
/**
* Constructor
*
* @param monitor
* The progress monitor for this import operation.
* @param io
* the import output device during import progress
* @param skipTrackingInformation
* whether to skip the import of tracked data
*/
public XmlImporter(IProgressMonitor monitor, IProgressConsole io,
boolean skipTrackingInformation) {
m_monitor = monitor;
m_io = io;
m_skipTrackingInformation = skipTrackingInformation;
}
/**
* Creates the instance of the persistent object which is defined by the XML
* element used as parameter. The method generates all dependent 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.
* @throws ToolkitPluginException
*/
public IProjectPO createProject(Project xml,
IParamNameMapper paramNameMapper,
IWritableComponentNameCache compNameCache)
throws InvalidDataException, JBVersionException,
InterruptedException, ToolkitPluginException {
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 dependent 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 microVersion
* Micro version number for the created object.
* @param versionQualifier
* Version qualifier 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.
* @throws ToolkitPluginException
* in case of the toolkit of the project is not supported
*/
public IProjectPO createProject(Project xml,
Integer majorVersion, Integer minorVersion,
Integer microVersion, String versionQualifier,
IParamNameMapper paramNameMapper,
IWritableComponentNameCache compNameCache)
throws InvalidDataException, JBVersionException,
InterruptedException, ToolkitPluginException {
if (majorVersion != null) {
xml.setMajorProjectVersion(majorVersion);
} else {
xml.setNilMajorProjectVersion();
}
if (minorVersion != null) {
xml.setMinorProjectVersion(minorVersion);
} else {
xml.setNilMinorProjectVersion();
}
if (microVersion != null) {
xml.setMicroProjectVersion(microVersion);
} else {
xml.setNilMicroProjectVersion();
}
xml.setProjectVersionQualifier(versionQualifier);
return createProject(xml, 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
* @throws ToolkitPluginException
* in case of the toolkit of the project is not supported
*/
public IProjectPO createProject(Project xml, boolean assignNewGuid,
IParamNameMapper paramNameMapper,
IWritableComponentNameCache compNameCache)
throws InvalidDataException,
InterruptedException, JBVersionException, ToolkitPluginException {
checkMinimumRequiredXMLVersion(xml);
documentRequiredProjects(xml);
checkUsedToolkits(xml);
checkSupportedToolkits(xml.getUsedToolkitList());
List<AbstractXmlConverter> listOfConverter =
new LinkedList<AbstractXmlConverter>();
// ======= register converter here =======
listOfConverter.add(new AutIdGenerationConverter());
listOfConverter.add(new V4C001());
listOfConverter.add(new HTMLTechnicalComponentIndexConverter());
listOfConverter.add(new TreeDirectionConverter());
listOfConverter.add(new RefTSNameConverter());
listOfConverter.add(new ObjectMappingAssoziationConverter());
// =======================================
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;
}
/**
* Check, whether the supported toolkits are supported.
* @param usedToolkits collection of the used toolkits
* @throws ToolkitPluginException if an unsupported toolkit is referenced
*/
private void checkSupportedToolkits(
List<UsedToolkit> usedToolkits) throws ToolkitPluginException {
List<String> toolkitIds = ComponentBuilder.getInstance()
.getLevelToolkitIds();
StringBuilder errorMsg = new StringBuilder();
for (UsedToolkit usedToolkit : usedToolkits) {
if (!ComponentBuilder.getInstance().getLevelToolkitIds()
.contains(usedToolkit.getName())) {
try {
ToolkitConstants.LEVEL_TOOLKIT.equals(ToolkitSupportBP
.getToolkitLevel(usedToolkit.getName()));
} catch (ToolkitPluginException e) {
errorMsg.append(StringConstants.NEWLINE);
errorMsg.append(StringConstants.TAB);
errorMsg.append(usedToolkit.getName());
}
}
}
if (StringUtils.isNotBlank(errorMsg.toString())) {
throw new ToolkitPluginException(NLS
.bind(Messages.UnsupportedToolkits, errorMsg.toString()));
}
}
/**
* @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(),
getProjectVersion(
xml.isNilMajorProjectVersion()
|| !xml.isSetMajorProjectVersion() ? null
: xml.getMajorProjectVersion(),
xml.isNilMinorProjectVersion()
|| !xml.isSetMinorProjectVersion() ? null
: xml.getMinorProjectVersion(),
xml.isNilMicroProjectVersion()
|| !xml.isSetMicroProjectVersion() ? null
: xml.getMicroProjectVersion(),
xml.getProjectVersionQualifier())}));
for (ReusedProject rp : xml.getReusedProjectsList()) {
ProjectVersion version = getProjectVersion(
rp.isNilMajorProjectVersion()
|| !rp.isSetMajorProjectVersion() ? null
: rp.getMajorProjectVersion(),
rp.isNilMinorProjectVersion()
|| !rp.isSetMinorProjectVersion() ? null
: rp.getMinorProjectVersion(),
rp.isNilMicroProjectVersion()
|| !rp.isSetMicroProjectVersion() ? null
: rp.getMicroProjectVersion(),
rp.getProjectVersionQualifier());
String requiredProjectString = rp.getProjectName() != null
? NLS.bind(Messages.XmlImporterRequiredProject,
new Object[] { rp.getProjectName(), version})
: NLS.bind(Messages.XmlImporterRequiredProjectWithoutName,
new Object[] { rp.getProjectGUID(), version});
m_io.writeLine(requiredProjectString);
}
}
}
/**
* Gets the {@link ProjectVersion} for the specified version numbers
* @param major number
* @param minor number
* @param micro number
* @param versionQualifier string version
* @return the projectVersion
*/
private ProjectVersion getProjectVersion(Integer major, Integer minor,
Integer micro, String versionQualifier) {
return new ProjectVersion(major, minor, micro, versionQualifier);
}
/**
* Creates the instance of the persistent object which is defined by the
* XML element used as parameter. The method generates all dependent 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.generateUUID();
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.addCompNamePO(
componentNamePO);
}
}
if (assignNewGuid) {
for (IComponentNamePO createdName : createdCompNames) {
String newGuid = oldToNewGUID.get(
createdName.getReferencedGuid());
if (newGuid != null) {
createdName.setReferencedGuid(newGuid);
}
}
ImportExportUtil.switchCompNamesGuids(proj, oldToNewGUID);
}
}
/**
* @param usedTK toolkits used from project to import
* @param projName name of project to import
* @param errorMsgs list with strings of detailed 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();
ToolkitDescriptor desc =
ComponentBuilder.getInstance().getCompSystem()
.getToolkitDescriptor(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()) {
ImportExportUtil.checkCancel(m_monitor);
proj.addUsedProject(createReusedProject(reusedProj));
}
if (xml.isSetDefaultLanguage()) {
m_oldDefaultLanguage = LocaleUtil.convertStrToLocale(
xml.getDefaultLanguage());
m_io.writeStatus(new Status(IStatus.WARNING, Activator.PLUGIN_ID,
NLS.bind(Messages.ImportOfDefaultLanguage,
m_oldDefaultLanguage)));
}
for (Aut autXml : xml.getAutList()) {
ImportExportUtil.checkCancel(m_monitor);
proj.addAUTMain(createAUTMain(autXml, assignNewGuid));
}
for (TestDataCategory testDataCategory
: xml.getTestDataCategoryList()) {
ImportExportUtil.checkCancel(m_monitor);
proj.getTestDataCubeCont().addCategory(createTestDataCategory(
testDataCategory, assignNewGuid, mapper));
}
for (NamedTestData testDataCube : xml.getNamedTestDataList()) {
ImportExportUtil.checkCancel(m_monitor);
proj.getTestDataCubeCont().addTestData(createTestDataCube(
testDataCube, assignNewGuid, mapper));
}
for (Category catXml : xml.getCategoryList()) {
ImportExportUtil.checkCancel(m_monitor);
proj.getSpecObjCont().addSpecObject(
createCategory(proj, catXml, assignNewGuid, mapper));
}
for (TestCase tcXml : xml.getTestcaseList()) {
ImportExportUtil.checkCancel(m_monitor);
initTestCase(assignNewGuid, mapper, proj, tcXml);
}
for (Category catXml : xml.getCategoryList()) {
ImportExportUtil.checkCancel(m_monitor);
rerunCategories(proj, catXml, assignNewGuid, attrDescSession);
}
for (TestCase tcXml : xml.getTestcaseList()) {
ImportExportUtil.checkCancel(m_monitor);
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()) {
ImportExportUtil.checkCancel(m_monitor);
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.setMarkupLanguage(xml.getMarkupLanguage());
proj.setToolkit(xml.getAutToolKit());
proj.setIsReusable(xml.getIsReusable());
proj.setIsProtected(xml.getIsProtected());
IProjectPropertiesPO projProperties = proj.getProjectProperties();
projProperties.setALMRepositoryName(xml.getAlmRepositoryName());
projProperties.setIsReportOnSuccess(xml.getIsReportOnSuccess());
projProperties.setIsReportOnFailure(xml.getIsReportOnFailure());
projProperties.setDashboardURL(xml.getDashboardURL());
projProperties.getCheckConfCont().setEnabled(
xml.getTeststyleEnabled());
projProperties.setIsTrackingActivated(xml.getTrackingEnabled());
projProperties.setTrackChangesSignature(xml.getTrackingAttribute());
if (xml.isSetTrackingUnit()) {
projProperties.setTrackChangesUnit(
TrackingUnit.valueOf(xml.getTrackingUnit()));
}
projProperties.setTrackChangesSpan(xml.getTrackingSpan());
List<IALMReportingRulePO> reportingRules =
new ArrayList<IALMReportingRulePO>();
for (ReportingRule rule : xml.getReportingRulesList()) {
IALMReportingRulePO newReportingRule = createReportingRule(rule);
reportingRules.add(newReportingRule);
}
projProperties.setALMReportingRules(reportingRules);
return projProperties;
}
/**
* converts alm reporting rule from xml to po
* @param xml rule from xml file
* @return the converted rule
*/
private IALMReportingRulePO createReportingRule(ReportingRule xml) {
String name = xml.getName();
String fieldID = xml.getFieldID();
String value = xml.getValue();
String xmlType = xml.getType();
ReportRuleType type = null;
if (xmlType.equals(ReportRuleType.ONSUCCESS.toString())) {
type = ReportRuleType.ONSUCCESS;
} else if (xmlType.equals(ReportRuleType.ONFAILURE.toString())) {
type = ReportRuleType.ONFAILURE;
}
IALMReportingRulePO rule = PoMaker.createALMReportingRulePO(
name, fieldID, value, type);
return rule;
}
/**
* @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()) {
ImportExportUtil.checkCancel(m_monitor);
List<IExecPersistable> tsAndCats =
createListOfCategoriesAndTestsuites(
proj, catXml, assignNewGuid);
for (IExecPersistable exec : tsAndCats) {
proj.getExecObjCont().addExecObject(exec);
}
}
for (ExecCategory catXml : xml.getExecCategoriesList()) {
ImportExportUtil.checkCancel(m_monitor);
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"); //$NON-NLS-1$
for (TestSuite tsXml : xml.getTestsuiteList()) {
ImportExportUtil.checkCancel(m_monitor);
ITestSuitePO tsPO = createTestSuite(proj, tsXml, assignNewGuid);
catTS.addNode(tsPO);
}
proj.getExecObjCont().addExecObject(catTS);
}
if (!xml.getTestsuiteList().isEmpty()) {
ICategoryPO catTJ = NodeMaker.createCategoryPO("Test Jobs"); //$NON-NLS-1$
for (TestJobs tjXml : xml.getTestJobsList()) {
ImportExportUtil.checkCancel(m_monitor);
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) {
Integer majorProjVersion = null;
if (!xml.isNilMajorProjectVersion()
&& xml.isSetMajorProjectVersion()
|| xml.isSetMajorNumber()) {
majorProjVersion = xml.isSetMajorNumber()
? xml.getMajorNumber() : xml.getMajorProjectVersion();
}
Integer minorProjVersion = null;
if (!xml.isNilMinorProjectVersion()
&& xml.isSetMinorProjectVersion()
|| xml.isSetMinorNumber()) {
minorProjVersion = xml.isSetMinorNumber()
? xml.getMinorNumber() : xml.getMinorProjectVersion();
}
Integer microProjVersion = !xml.isSetMicroProjectVersion()
|| xml.isNilMicroProjectVersion() ? null : xml
.getMicroProjectVersion();
String postFixProjVersion = !xml.isSetProjectVersionQualifier()
|| xml.isNilProjectVersionQualifier() ? null : xml
.getProjectVersionQualifier();
if (!assignNewGuid) {
proj = NodeMaker.createProjectPO(
IVersion.JB_CLIENT_METADATA_VERSION, majorProjVersion,
minorProjVersion, microProjVersion, postFixProjVersion,
xml.getGUID());
} else {
proj = NodeMaker.createProjectPO(
IVersion.JB_CLIENT_METADATA_VERSION, majorProjVersion,
minorProjVersion, microProjVersion, postFixProjVersion);
m_oldToNewGuids.put(xml.getGUID(), proj.getGuid());
}
ProjectNameBP.getInstance().setName(proj.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(
IArchivableTestResultSummary.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);
}
/**
* 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 if (stepXml.getUsedTestcase() != null) {
tc.addNode(createExecTestCase(
proj, stepXml.getUsedTestcase(), assignNewGuid));
} else if (stepXml.getComment() != null) {
tc.addNode(createComment(stepXml.getComment(), 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 parameter. The method generates all dependent 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);
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 parameter. The method generates all dependent 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 (AutConfig confXml : xml.getConfigList()) {
aut.addAutConfigToSet(createAUTConfig(confXml, assignNewGuid));
}
for (String autId : xml.getAutIdList()) {
aut.getAutIds().add(autId);
}
final List<MapEntry> props = xml.getPropertiesList();
for (MapEntry prop : props) {
aut.getPropertyMap().put(prop.getKey(), prop.getValue());
}
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 = null;
if (xml.isSetMajorProjectVersion()) {
majorProjVersion = xml.isNilMajorProjectVersion() ? null : xml
.getMajorProjectVersion();
} else if (xml.isSetMajorNumber()) {
majorProjVersion = xml.isNilMajorNumber() ? null : xml
.getMajorNumber();
}
Integer minorProjVersion = null;
if (xml.isSetMinorProjectVersion()) {
minorProjVersion = xml.isNilMinorProjectVersion() ? null : xml
.getMinorProjectVersion();
} else if (xml.isSetMinorNumber()) {
minorProjVersion = xml.isNilMinorNumber() ? null : xml
.getMinorNumber();
}
Integer microProjVersion = !xml.isSetMicroProjectVersion()
|| xml.isNilMicroProjectVersion() ? null : xml
.getMicroProjectVersion();
String versionQualifier = !xml.isSetProjectVersionQualifier()
|| xml.isNilProjectVersionQualifier() ? null : xml
.getProjectVersionQualifier();
IReusedProjectPO reusedProject = PoMaker.createReusedProjectPO(
xml.getProjectGUID(), majorProjVersion, minorProjVersion,
microProjVersion, versionQualifier);
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 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 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 ICommentPO createComment(Comment xml, boolean assignNewGuid) {
ICommentPO cat;
if (!assignNewGuid && xml.getGUID() != null) {
cat = NodeMaker.createCommentPO(xml.getName(), xml.getGUID());
} else {
cat = NodeMaker.createCommentPO(xml.getName());
}
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.setDescription(xml.getDescription());
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 = ImportExportUtil.findReferencedTCByGuid(
xml.getTestcaseGuid(), xml.getProjectGuid(),
proj, assignNewGuid, m_oldToNewGuids, m_tcRef);
}
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 = ImportExportUtil.findReferencedTCByGuid(
xml.getTestcaseGuid(), xml.getProjectGuid(),
proj, assignNewGuid, m_oldToNewGuids, m_tcRef);
}
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()));
ObjectMappingProfile omp = tecNameXml.getProfile();
if (omp != null) {
Profile p = new Profile(omp.getName(), omp.getNameFactor(),
omp.getPathFactor(), omp.getContextFactor(),
omp.getThreshold());
tecName.setProfile(p);
}
}
// 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 HashSet<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 http://eclip.se/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<String> tdList = null;
try {
tdList = tdman.getDataSet(tdRow).getColumnStringValues();
} 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, 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 list of test data
*/
private String readData(TestDataCell cellXml,
IParameterInterfacePO owner) {
String valueString;
if (m_oldDefaultLanguage != null) {
valueString = readOldI18nMainData(cellXml, owner);
} else {
valueString = cellXml.getValue();
if (valueString != null) {
try {
// Since we are not using the converter for anything other than
// parsing, we can use null for paramDesc
ModelParamValueConverter converter =
new ModelParamValueConverter(
valueString, owner,
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.replaceUuidsInReferences(m_oldToNewGuids);
} else {
m_unparseableParameters.add(valueString);
}
valueString = 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.
}
}
}
return valueString;
}
/**
* @param cellXml associated cell from import
* @param owner The owner of the data.
* @return the map read from the provided data.
*/
private String readOldI18nMainData(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,
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.replaceUuidsInReferences(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.get(m_oldDefaultLanguage);
}
/**
* Creates the instance of the persistent object which is defined by the
* XML element used as parameter. The method generates all dependent 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 parameter. The method generates all dependent 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 parameter. The method generates all dependent 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]{" + ImportExportUtil.UUID_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<String> td = new ArrayList<String>(rowXml
.sizeOfDataArray());
for (TestDataCell cellXml : rowXml.getDataList()) {
td.add(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 parameter. The method generates all dependent 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.setDescription(xml.getDescription());
tc.setGenerated(xml.getGenerated());
tc.setTaskId(xml.getTaskId());
tc.setInterfaceLocked(xml.getInterfaceLocked());
tc.setDataFile(xml.getDatafile());
fillTrackedChangesInformation(tc, xml);
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]{" + ImportExportUtil.UUID_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 parameter. The method generates all dependent 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.setDescription(xml.getDescription());
ts.setTaskId(xml.getTaskId());
fillTrackedChangesInformation(ts, xml);
if (xml.getSelectedAut() != null) {
ts.setAut(findReferencedAut(xml.getSelectedAut()));
}
List<RefTestCase> usedTestcaseList = xml.getUsedTestcaseList();
if (!usedTestcaseList.isEmpty()) {
// Deprecated way
for (RefTestCase refXml : usedTestcaseList) {
ts.addNode(createExecTestCase(proj, refXml, assignNewGuid));
}
} else {
// New way
for (Testsuiteelement element : xml.getTestsuiteelementList()) {
RefTestCase refXml = element.getUsedTestcase();
if (refXml != null) {
ts.addNode(createExecTestCase(proj, refXml, assignNewGuid));
} else {
Comment comXml = element.getComment();
if (comXml != null) {
ts.addNode(createComment(comXml, 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());
if (!xml.isSetRelevant()) {
ts.setRelevant(true);
} else {
ts.setRelevant(xml.getRelevant());
}
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.setDescription(xml.getDescription());
tj.setTaskId(xml.getTaskId());
fillTrackedChangesInformation(tj, xml);
List<RefTestSuite> refTestSuiteList = xml.getRefTestSuiteList();
if (!refTestSuiteList.isEmpty()) {
// Deprecated way
for (RefTestSuite xmlRts : refTestSuiteList) {
processRefTestSuite(assignNewGuid, tj, xmlRts);
}
} else {
// New way
for (Testjobelement element : xml.getTestjobelementList()) {
RefTestSuite xmlRts = element.getRefTestSuite();
if (xmlRts != null) {
processRefTestSuite(assignNewGuid, tj, xmlRts);
} else {
Comment xmlComment = element.getComment();
tj.addNode(createComment(xmlComment, false));
}
}
}
return tj;
}
/**
* Adds ref test suite to test job
* @param assignNewGuid <code>true</code> if the test suite
* should be assigned a new GUID. Otherwise
* <code>false</code>.
* @param tj test job
* @param xmlRts ref test suite from xml
* @throws InvalidDataException
*/
private void processRefTestSuite(boolean assignNewGuid, ITestJobPO tj,
RefTestSuite xmlRts) throws InvalidDataException {
if (xmlRts != null) {
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: " + xmlRts.getTsGuid(), //$NON-NLS-1$
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());
rts.setDescription(xmlRts.getDescription());
tj.addNode(rts);
}
}
/**
* @param poNode
* the persistent object to fill
* @param xmlNode
* the xml node to read from
*/
private void fillTrackedChangesInformation(INodePO poNode, Node xmlNode) {
List<MapEntry> trackedModificationList =
xmlNode.getTrackedModificationList();
if (!trackedModificationList.isEmpty() && !m_skipTrackingInformation) {
Map<Long, String> trackedChanges = new HashMap<Long, String>();
for (MapEntry me : trackedModificationList) {
trackedChanges.put(Long.valueOf(me.getKey()), me.getValue());
}
poNode.setTrackedChangesMap(trackedChanges);
}
}
/**
* 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.setDescription(xml.getDescription());
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(), null);
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);
}
/**
* 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()) {
ImportExportUtil.checkCancel(m_monitor);
rerunCategories(proj, catXml, assignNewGuid, attrDescSession);
}
for (TestCase tcXml : xml.getTestcaseList()) {
ImportExportUtil.checkCancel(m_monitor);
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;
}
}