| /******************************************************************************** |
| * Copyright (c) 2015-2021 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| package org.eclipse.mdm.apicopy.control; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| |
| import org.eclipse.mdm.api.base.Transaction; |
| import org.eclipse.mdm.api.base.adapter.EntityType; |
| import org.eclipse.mdm.api.base.adapter.Relation; |
| import org.eclipse.mdm.api.base.massdata.ReadRequest; |
| import org.eclipse.mdm.api.base.massdata.ReadRequest.ValuesMode; |
| import org.eclipse.mdm.api.base.massdata.WriteRequest; |
| import org.eclipse.mdm.api.base.model.Channel; |
| import org.eclipse.mdm.api.base.model.ChannelGroup; |
| import org.eclipse.mdm.api.base.model.ContextComponent; |
| import org.eclipse.mdm.api.base.model.ContextRoot; |
| import org.eclipse.mdm.api.base.model.ContextType; |
| import org.eclipse.mdm.api.base.model.Entity; |
| import org.eclipse.mdm.api.base.model.MeasuredValues; |
| import org.eclipse.mdm.api.base.model.Measurement; |
| import org.eclipse.mdm.api.base.model.Quantity; |
| import org.eclipse.mdm.api.base.model.Test; |
| import org.eclipse.mdm.api.base.model.TestStep; |
| import org.eclipse.mdm.api.base.model.Unit; |
| import org.eclipse.mdm.api.base.model.User; |
| import org.eclipse.mdm.api.base.model.Value; |
| import org.eclipse.mdm.api.base.model.VersionState; |
| import org.eclipse.mdm.api.dflt.ApplicationContext; |
| import org.eclipse.mdm.api.dflt.EntityManager; |
| import org.eclipse.mdm.api.dflt.model.Classification; |
| import org.eclipse.mdm.api.dflt.model.Pool; |
| import org.eclipse.mdm.api.dflt.model.Project; |
| import org.eclipse.mdm.api.dflt.model.TemplateComponent; |
| import org.eclipse.mdm.api.dflt.model.TemplateRoot; |
| import org.eclipse.mdm.api.dflt.model.TemplateTest; |
| import org.eclipse.mdm.api.dflt.model.TemplateTestStep; |
| import org.eclipse.mdm.api.dflt.model.TemplateTestStepUsage; |
| import org.eclipse.mdm.api.dflt.model.Versionable; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.common.base.Strings; |
| import com.google.common.collect.ListMultimap; |
| |
| public class ImportTask extends TransferBase implements ApiCopyTask { |
| |
| /** |
| * Property to configure to overwrite the existing test step |
| * |
| * Default: false |
| * |
| * If true and the matching target test step exists, context data will be |
| * overwritten and the measurements will be imported as children of the existing |
| * teststep. |
| * |
| * Otherwise a new test step will be created |
| */ |
| private static final String PROPERTY_OVERWRITE_EXISTING_ELEMENTS = "overwriteExistingElements"; |
| private static final String DEFAULT_OVERWRITE_EXISTING_ELEMENTS = "false"; |
| |
| /** |
| * Property to configure that existing measured values will be appended |
| * |
| * Default: false |
| * |
| * If true the measured value of the import data set will be appended to the |
| * existing. That means, if the target measurement already exists the importer |
| * will add the measured values of the source column to the target column. If at |
| * the the target measurement the column not exists, the importer create a new |
| * one, add first invalid values with the count of the target submatrix size, |
| * and add there the source values. |
| * |
| * If false and the target measurement already exists, the import task will be |
| * canceled |
| */ |
| private static final String PROPERTY_APPEND = "append"; |
| private static final String DEFAULT_APPEND = "false"; |
| |
| /** |
| * Property to configure that existing file links will be replaced |
| * |
| * Default: false |
| * |
| * If true, file links of the target entities will be replaced, if in the source |
| * the file link exists |
| * |
| * Otherwise new file links will be added to the existing sequence. |
| */ |
| private static final String PROPERTY_REPLACE_FILELINKS = "replaceFileLinks"; |
| private static final String DEFAULT_REPLACE_FILES = "false"; |
| |
| /** |
| * Property to configure that a valid template is required in the target |
| * datasources |
| * |
| * Default: true |
| * |
| * If true, a valid template is required in the target datasource. If none is |
| * found the import will fail. If false and no valid template is found, the |
| * test/teststep will be imported with no template (not recommended). |
| * |
| */ |
| private static final String PROPERTY_REQUIRE_TEMPLATE = "requireTemplate"; |
| private static final String DEFAULT_REQUIRE_TEMPLATE = "true"; |
| |
| /** |
| * Property to configure that the TemplateTest will be updated to the latest |
| * valid version. |
| * |
| * Default: false |
| * |
| * If true, the TemplateTest at the Test will be updated to the latest valid |
| * version. The TemplateTest will only be updated if it is consistent with the |
| * existing TestSteps and their TemplateTestSteps. This means all used |
| * TemplateTestSteps must be configured in the TemplateTestStepUsages of the new |
| * TemplateTest. |
| * |
| */ |
| private static final String PROPERTY_UPDATE_TEST_TEMPLATE = "updateTemplateTest"; |
| private static final String DEFAULT_UPDATE_TEST_TEMPLATE = "false"; |
| |
| private static final Logger LOG = LoggerFactory.getLogger(ImportTask.class); |
| |
| private ClassificationUtil classificationUtil; |
| private TemplateManager templateManager; |
| |
| private Map<String, String> quantityMapping = new HashMap<>(); |
| |
| private Map<String, String> unitMapping = new HashMap<>(); |
| |
| private Map<String, String> properties = new HashMap<>(); |
| |
| private boolean replaceFileLinks = false; |
| |
| public ImportTask(ApplicationContext src, ApplicationContext dst, TemplateManager templateManager) { |
| super(src, dst); |
| |
| if (templateManager == null) { |
| this.templateManager = new DefaultTemplateManager(); |
| } else { |
| this.templateManager = templateManager; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.mdm.apicopy.control.ApiCopyTask#setUnitMapping(java.util.Map) |
| */ |
| @Override |
| public void setUnitMapping(Map<String, String> unitMapping) { |
| this.unitMapping = unitMapping; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.mdm.apicopy.control.ApiCopyTask#setQuantityMapping(java.util.Map) |
| */ |
| @Override |
| public void setQuantityMapping(Map<String, String> quantityMapping) { |
| this.quantityMapping = quantityMapping; |
| } |
| |
| @Override |
| public void copy(List<? extends Entity> entities) { |
| Transaction transaction = entityManagerDst.startTransaction(); |
| classificationUtil = new ClassificationUtil(transaction, contextDst); |
| try { |
| mapSrcDstEntities.clear(); |
| |
| ListMultimap<Class<? extends Entity>, Entity> parents = loadParents(entities); |
| LOG.trace("Resolved parents: {}", parents); |
| supportedRootEntities.forEach(ec -> parents.get(ec).forEach(e -> copyEntity(e, false, transaction))); |
| |
| LOG.trace("Import entities: {}", entities); |
| entities.forEach(e -> copyEntity(e, true, transaction)); |
| transaction.commit(); |
| deleteFilesOfReplacedFileLinks(transaction); |
| } catch (Exception exc) { |
| try { |
| transaction.abort(); |
| } catch (Exception exc2) { |
| LOG.error("Could not abort transaction!"); |
| } |
| deleteFilesOfUploadedFileLinks(transaction); |
| |
| throw new ApiCopyException("Could not copy data: " + exc.getMessage(), exc); |
| } finally { |
| classificationUtil.clearCache(); |
| clearReplacedFileLinkCache(); |
| clearUploadedFileLinkCache(); |
| deleteLocalTempFiles(); |
| } |
| } |
| |
| @Override |
| public boolean isReplaceFileLinks() { |
| return replaceFileLinks; |
| } |
| |
| private Entity copyEntity(Entity entity, boolean recursive, Transaction transaction) { |
| if (entity instanceof Project) { |
| return copyProject((Project) entity, recursive, transaction); |
| } else if (entity instanceof Pool) { |
| return copyPool((Pool) entity, recursive, transaction); |
| } else if (entity instanceof Test) { |
| return copyTest((Test) entity, recursive, transaction); |
| } else if (entity instanceof TestStep) { |
| return copyTestStep((TestStep) entity, recursive, transaction); |
| } else if (entity instanceof Measurement) { |
| return copyMeasurement((Measurement) entity, new ArrayList<ContextRoot>(), recursive, transaction); |
| } else { |
| throw new ApiCopyException("Unsupported entity: '" + entity.getClass().getName() + "'"); |
| } |
| } |
| |
| private Project copyProject(Project projectSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(projectSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| |
| Optional<Project> projectOpt = fetchOne(entityManagerDst, Project.class, projectSrc.getName()); |
| |
| if (projectOpt.isPresent()) { |
| LOG.trace("Project '{}' already exists.", projectSrc.getName()); |
| ehDst = new EntityHolder(projectOpt.get(), entityManagerDst); |
| } else { |
| LOG.trace("Importing Project '{}'.", projectSrc.getName()); |
| |
| Project projectDst = entityFactoryDst.createProject(projectSrc.getName()); |
| copyValues(projectSrc, projectDst, Arrays.asList("Id", "Name"), false); |
| |
| persist(transaction, projectDst); |
| ehDst = new EntityHolder(projectDst, entityManagerDst); |
| } |
| |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| entityManagerSrc.loadChildren(projectSrc, Pool.class) |
| .forEach(pool -> copyPool(pool, recursive, transaction)); |
| } |
| } |
| |
| return (Project) ehDst.getEntity(); |
| } |
| |
| private Pool copyPool(Pool poolSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(poolSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Importing Pool '{}'", poolSrc.getName()); |
| |
| Project projectParentDst = (Project) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(poolSrc, Project.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| Optional<Pool> poolOpt = fetchChild(entityManagerDst, projectParentDst, Pool.class, poolSrc.getName()); |
| |
| if (poolOpt.isPresent()) { |
| LOG.trace("Pool '{}' already exists.", poolSrc.getName()); |
| ehDst = new EntityHolder(poolOpt.get(), entityManagerDst); |
| } else { |
| LOG.trace("Importing Pool '{}'.", poolSrc.getName()); |
| |
| Pool poolDst = entityFactoryDst.createPool(poolSrc.getName(), projectParentDst); |
| copyValues(poolSrc, poolDst, Arrays.asList("Id", "Name"), false); |
| |
| persist(transaction, poolDst); |
| ehDst = new EntityHolder(poolDst, entityManagerDst); |
| } |
| |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| entityManagerSrc.loadChildren(poolSrc, Test.class) |
| .forEach(test -> copyTest(test, recursive, transaction)); |
| } |
| } |
| |
| return (Pool) ehDst.getEntity(); |
| } |
| |
| private Test copyTest(Test testSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(testSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| |
| Pool poolParentDst = (Pool) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(testSrc, Pool.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| Optional<TemplateTest> templateTestDst = loadTemplateTest(testSrc); |
| |
| String rootProjectName = getProjectName(testSrc, entityManagerSrc); |
| |
| Optional<Test> testOpt = fetchChild(entityManagerDst, poolParentDst, Test.class, testSrc.getName()); |
| |
| if (testOpt.isPresent()) { |
| LOG.trace("Test '{}' already exists.", testSrc.getName()); |
| if (Boolean.valueOf( |
| properties.getOrDefault(PROPERTY_UPDATE_TEST_TEMPLATE, DEFAULT_UPDATE_TEST_TEMPLATE))) { |
| LOG.debug("Trying to update TemplateTest of existing Test '{}'.", testSrc.getName()); |
| |
| Test testDst = updateTemplateTest(testOpt.get(), transaction); |
| ehDst = new EntityHolder(testDst, entityManagerDst); |
| } else { |
| checkIfTemplateIsApplicableForTest(templateTestDst, testOpt); |
| |
| ehDst = new EntityHolder(testOpt.get(), entityManagerDst); |
| } |
| } else { |
| Test testDst; |
| if (templateTestDst.isPresent()) { |
| LOG.trace("Importing Test '{}' using TestTemplate '{}'", testSrc.getName(), |
| templateTestDst.get().getName()); |
| testDst = entityFactoryDst.createTest(testSrc.getName(), poolParentDst, templateTestDst.get(), |
| classificationUtil.getClassification(rootProjectName), false); |
| } else { |
| LOG.trace("Importing Test '{}' using no TestTemplate", testSrc.getName()); |
| testDst = entityFactoryDst.createTest(testSrc.getName(), poolParentDst, null, |
| classificationUtil.getClassification(rootProjectName), false); |
| } |
| |
| copyValues(testSrc, testDst, Arrays.asList("Id", "Name", "MDMLinks"), true); |
| |
| // copy responsible person: |
| Optional<User> userSrc = testSrc.getResponsiblePerson(); |
| if (userSrc.isPresent()) { |
| User userDst = entityManagerDst.loadAll(User.class, escapeWildcards(userSrc.get().getName())) |
| .stream().findFirst().orElseThrow(() -> new ApiCopyException(String.format( |
| "No User instance with name %s found in destination!", userSrc.get().getName()))); |
| |
| testDst.setResponsiblePerson(userDst); |
| } |
| |
| persist(transaction, testDst); |
| |
| copyFiles(testSrc, testDst, transaction); |
| |
| ehDst = new EntityHolder(testDst, entityManagerDst); |
| } |
| |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| EntityType etTestStep = modelManagerDst.getEntityType(TestStep.class); |
| EntityType etTest = modelManagerDst.getEntityType(Test.class); |
| |
| Relation relTest = etTestStep.getRelation(etTest); |
| |
| if (null == relTest) { |
| throw new ApiCopyException("No relation to Test found at TestStep!"); |
| } |
| |
| copyTestSteps(testSrc, recursive, templateTestDst, (Test) ehDst.getEntity(), transaction); |
| entityManagerSrc.loadChildren(testSrc, TestStep.class) |
| .forEach(testStep -> copyTestStep(testStep, recursive, transaction)); |
| } |
| } |
| |
| return (Test) ehDst.getEntity(); |
| } |
| |
| /** |
| * Check if the TemplateTest that should be used by the importer is compatible |
| * with the Template Test at the existing Test. |
| * |
| * @param templateTest |
| * @param test |
| * @throws ApiCopyException if property requireTemplate is true and test does |
| * not have a template or templateTest is empty or the |
| * names of the tests template and the given |
| * templateTest do not match. |
| */ |
| private void checkIfTemplateIsApplicableForTest(Optional<TemplateTest> templateTest, Optional<Test> test) { |
| if (Boolean.valueOf(properties.getOrDefault(PROPERTY_REQUIRE_TEMPLATE, DEFAULT_REQUIRE_TEMPLATE))) { |
| |
| TemplateTest existingTemplateTest = TemplateTest.of(test.get()) |
| .orElseThrow(() -> new ApiCopyException("Property '" + PROPERTY_REQUIRE_TEMPLATE |
| + "' is true, but the existing target test with id='" + test.get().getID() |
| + "' has no template specified.")); |
| |
| TemplateTest importingTemplateTest = templateTest.orElseThrow(() -> new ApiCopyException("Property '" |
| + PROPERTY_REQUIRE_TEMPLATE + "' is true, but template test the existing target test with id='" |
| + test.get().getID() + "' has no template specified.")); |
| |
| if (!importingTemplateTest.nameEquals(existingTemplateTest.getName())) { |
| throw new ApiCopyException( |
| "Existing test template with name " + existingTemplateTest.getName() + " does not match name '" |
| + importingTemplateTest.getName() + "' of test template returned by template manager."); |
| } |
| } |
| |
| } |
| |
| private Test updateTemplateTest(Test test, Transaction transaction) { |
| Optional<TemplateTest> tplTest = TemplateTest.of(test); |
| |
| if (tplTest.isPresent()) { |
| String name = tplTest.map(TemplateTest::getName).map(this::escapeWildcards) |
| .orElseThrow(() -> new ApiCopyException("Could not load TemplateTest name")); |
| |
| Set<String> requiredTemplates = entityManagerDst.loadChildren(test, TestStep.class).stream() |
| .map(ts -> TemplateTestStep.of(ts)).filter(Optional::isPresent).map(Optional::get) |
| .map(TemplateTestStep::getID).collect(Collectors.toSet()); |
| |
| List<TemplateTest> list = entityManagerDst.loadAll(TemplateTest.class, name); |
| |
| Optional<TemplateTest> newerTplTest = list.stream() |
| .sorted(Comparator.comparing(tts -> tts.getVersion(), Comparator.reverseOrder())) |
| .filter(tt -> tt.isValid()).filter(tt -> tt.getVersion() > tplTest.get().getVersion()) |
| .filter(tt -> testContainsTemplate(tt, requiredTemplates)).findFirst(); |
| |
| if (newerTplTest.isPresent()) { |
| LOG.debug("Updating Test '{}' setting new TemplateTest '{}' with version {} (old version {}).", |
| test.getName(), newerTplTest.get().getName(), newerTplTest.get().getVersion(), |
| tplTest.get().getVersion()); |
| |
| newerTplTest.get().assign(test); |
| persist(transaction, test); |
| } |
| } |
| return test; |
| } |
| |
| private boolean testContainsTemplate(TemplateTest tt, Collection<String> templateTestStepIDs) { |
| |
| Set<String> configuredValidTemplates = tt.getTemplateTestStepUsages().stream() |
| .map(TemplateTestStepUsage::getTemplateTestStep).filter(TemplateTestStep::isValid) |
| .map(TemplateTestStep::getID).collect(Collectors.toSet()); |
| |
| return configuredValidTemplates.containsAll(templateTestStepIDs); |
| } |
| |
| private Boolean isRequireTemplate() { |
| return Boolean.valueOf(properties.getOrDefault(PROPERTY_REQUIRE_TEMPLATE, DEFAULT_REQUIRE_TEMPLATE)); |
| } |
| |
| private TestStep copyTestStep(TestStep testStepSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(testStepSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Importing TestStep '{}'", testStepSrc.getName()); |
| |
| Test testDst = (Test) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(testStepSrc, Test.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| Optional<TemplateTestStep> templateTestStep = loadTemplateTestStep(testDst, testStepSrc); |
| |
| String rootProjectName = getProjectName(testStepSrc, entityManagerSrc); |
| |
| TestStep testStepDst = fetchChild(entityManagerDst, testDst, TestStep.class, testStepSrc.getName()) |
| .orElseGet(() -> { |
| if (templateTestStep.isPresent() && hasContextData(testStepSrc)) { |
| LOG.trace("Importing TestStep '{}' using TestStepTemplate '{}' and create context roots", |
| testStepSrc.getName(), templateTestStep.get().getName()); |
| return entityFactoryDst.createTestStep(testDst, templateTestStep.get(), |
| classificationUtil.getClassification(rootProjectName)); |
| } else if (templateTestStep.isPresent()) { |
| LOG.trace("Importing TestStep '{}' using TestStepTemplate '{}'", testStepSrc.getName(), |
| templateTestStep.get().getName()); |
| return entityFactoryDst.createTestStep(testDst, templateTestStep.get(), |
| classificationUtil.getClassification(rootProjectName), false); |
| } else { |
| LOG.trace("Importing TestStep '{}' using no TestStepTemplate", testStepSrc.getName()); |
| TestStep createdTestStep = entityFactoryDst.createTestStep(testStepSrc.getName(), testDst, |
| classificationUtil.getClassification(rootProjectName)); |
| return createdTestStep; |
| } |
| }); |
| |
| copyValues(testStepSrc, testStepDst, Arrays.asList("Id"), true); |
| |
| persist(transaction, testStepDst); |
| |
| copyFiles(testStepSrc, testStepDst, transaction); |
| |
| ehDst = new EntityHolder(testStepDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| Map<ContextType, ContextRoot> mapContextRootsSrc = testStepSrc.loadContexts(entityManagerSrc, |
| ContextType.values()); |
| Map<ContextType, ContextRoot> mapContextRootsDst = testStepDst.loadContexts(entityManagerDst, |
| ContextType.values()); |
| |
| copyContext(mapContextRootsSrc, mapContextRootsDst, templateTestStep, transaction); |
| |
| if (recursive) { |
| List<ContextRoot> listContextRoots = new ArrayList<>(); |
| entityManagerSrc.loadChildren(testStepSrc, Measurement.class) |
| .forEach(measurement -> copyMeasurement(measurement, listContextRoots, recursive, transaction)); |
| } |
| } |
| return (TestStep) ehDst.getEntity(); |
| } |
| |
| private String getProjectName(TestStep testStep, EntityManager entityManager) { |
| Optional<Test> parentTest = entityManager.loadParent(testStep, Test.class); |
| |
| if (!parentTest.isPresent()) { |
| throw new ApiCopyException("Parent of source teststep not found!"); |
| } |
| |
| return getProjectName(parentTest.get(), entityManager); |
| } |
| |
| private String getProjectName(Test test, EntityManager entityManager) { |
| |
| Optional<Pool> parentPool = entityManager.loadParent(test, Pool.class); |
| |
| if (!parentPool.isPresent()) { |
| throw new ApiCopyException("Parent of source test not found!"); |
| } |
| |
| Optional<Project> parentProject = entityManager.loadParent(parentPool.get(), Project.class); |
| |
| if (!parentProject.isPresent()) { |
| throw new ApiCopyException("Parent of source pool not found!"); |
| } |
| |
| return parentProject.get().getName(); |
| } |
| |
| /** |
| * Check if the teststep has context data |
| * |
| * @param testStepSrc |
| * @return true if the teststep has conteyt data |
| */ |
| private boolean hasContextData(TestStep testStepSrc) { |
| boolean hasContextData = false; |
| |
| Optional<EntityManager> entityManager = contextSrc.getEntityManager(); |
| if (entityManager.isPresent()) { |
| Map<ContextType, ContextRoot> loadContexts = entityManager.get().loadContexts(testStepSrc, |
| ContextType.UNITUNDERTEST, ContextType.TESTEQUIPMENT, ContextType.TESTSEQUENCE); |
| if (!loadContexts.isEmpty()) { |
| hasContextData = true; |
| } |
| } |
| |
| return hasContextData; |
| |
| } |
| |
| private List<TestStep> copyTestSteps(Test testSrc, boolean recursive, Optional<TemplateTest> templateTestDst, |
| Test testDst, Transaction transaction) { |
| |
| List<TestStep> listTestStepsSrc = entityManagerSrc.loadChildren(testSrc, TestStep.class); |
| |
| List<TestStep> listTestStepsDst = new ArrayList<>(); |
| for (int i = 0, len = listTestStepsSrc.size(); i < len; ++i) { |
| TestStep testStepSrc = listTestStepsSrc.get(i); |
| Optional<TemplateTestStep> templateTestStep = loadTemplateTestStep(testDst, testStepSrc); |
| |
| String rootProjectName = getProjectName(testStepSrc, entityManagerSrc); |
| |
| Optional<TestStep> oTestStepDst = fetchChild(entityManagerDst, testDst, TestStep.class, |
| testStepSrc.getName()); |
| |
| TestStep testStepDst; |
| |
| boolean overwriteExistingElements = Boolean.valueOf( |
| properties.getOrDefault(PROPERTY_OVERWRITE_EXISTING_ELEMENTS, DEFAULT_OVERWRITE_EXISTING_ELEMENTS)); |
| |
| if (!overwriteExistingElements || (overwriteExistingElements && !oTestStepDst.isPresent())) { |
| if (templateTestStep.isPresent() && hasContextData(testStepSrc)) { |
| LOG.trace("Importing TestStep '{}' using TestStepTemplate '{}' and create context roots", |
| testStepSrc.getName(), templateTestStep.get().getName()); |
| testStepDst = entityFactoryDst.createTestStep(testDst, templateTestStep.get(), |
| classificationUtil.getClassification(rootProjectName)); |
| testStepDst.setName(testStepSrc.getName()); |
| } else if (templateTestStep.isPresent()) { |
| LOG.trace("Importing TestStep '{}' using TestStepTemplate '{}' and create context roots", |
| testStepSrc.getName(), templateTestStep.get().getName()); |
| testStepDst = entityFactoryDst.createTestStep(testDst, templateTestStep.get(), |
| classificationUtil.getClassification(rootProjectName), false); |
| } else { |
| LOG.trace("Importing TestStep '{}' using no TestStepTemplate", testStepSrc.getName()); |
| testStepDst = entityFactoryDst.createTestStep(testStepSrc.getName(), testDst, |
| classificationUtil.getClassification(rootProjectName)); |
| } |
| } else { |
| testStepDst = oTestStepDst.get(); |
| } |
| |
| copyValues(testStepSrc, testStepDst, Arrays.asList("Id"), true); |
| |
| listTestStepsDst.add(testStepDst); |
| |
| mapSrcDstEntities.put(new EntityHolder(testStepSrc, entityManagerSrc), |
| new EntityHolder(testStepDst, entityManagerDst)); |
| } |
| |
| for (TestStep testStepSrc : listTestStepsSrc) { |
| Optional<TestStep> testStepDst = listTestStepsDst.stream() |
| .filter(n -> n.getName().equals(testStepSrc.getName())).findFirst(); |
| |
| if (testStepDst.isPresent()) { |
| Map<ContextType, ContextRoot> mapContextRootsSrc = testStepSrc.loadContexts(entityManagerSrc, |
| ContextType.values()); |
| Map<ContextType, ContextRoot> mapContextRootsDst = testStepDst.get().loadContexts(entityManagerDst, |
| ContextType.values()); |
| copyContext(mapContextRootsSrc, mapContextRootsDst, loadTemplateTestStep(testDst, testStepSrc), |
| transaction); |
| } |
| } |
| |
| persist(transaction, listTestStepsDst); |
| |
| for (TestStep testStepSrc : listTestStepsSrc) { |
| copyFiles(testStepSrc, |
| (TestStep) mapSrcDstEntities.get(new EntityHolder(testStepSrc, entityManagerSrc)).getEntity(), |
| transaction); |
| } |
| |
| if (recursive) { |
| for (TestStep testStep : listTestStepsSrc) { |
| List<ContextRoot> listContextRoots = new ArrayList<>(); |
| entityManagerSrc.loadChildren(testStep, Measurement.class) |
| .forEach(measurement -> copyMeasurement(measurement, listContextRoots, recursive, transaction)); |
| } |
| } |
| |
| return listTestStepsDst; |
| } |
| |
| private void copyContext(Map<ContextType, ContextRoot> mapContextRootsSrc, |
| Map<ContextType, ContextRoot> mapContextRootsDst, Optional<TemplateTestStep> optTemplateTestStep, |
| Transaction transaction) { |
| |
| for (Map.Entry<ContextType, ContextRoot> me : mapContextRootsSrc.entrySet()) { |
| LOG.trace("Importing ContextRoot '{}'", me.getKey()); |
| ContextRoot contextRootDst = mapContextRootsDst.get(me.getKey()); |
| if (null != contextRootDst && contextRootDst.getName().equals(me.getValue().getName())) { |
| ContextRoot contextRootSrc = me.getValue(); |
| copyValues(contextRootSrc, contextRootDst, Arrays.asList("Id", "Name"), false); |
| |
| TemplateRoot templateRootDst = null; |
| |
| if (optTemplateTestStep.isPresent()) { |
| Optional<TemplateRoot> optTemplateRoot = optTemplateTestStep.get() |
| .getTemplateRoot(contextRootDst.getContextType()); |
| |
| templateRootDst = optTemplateRoot.orElse(null); |
| } |
| |
| for (ContextComponent contextComponentSrc : me.getValue().getContextComponents()) { |
| LOG.trace("Importing ContextComponent '{}'", contextComponentSrc.getName()); |
| Optional<ContextComponent> o = contextRootDst.getContextComponent(contextComponentSrc.getName()); |
| |
| if (o.isPresent()) { |
| ContextComponent contextComponentDst = o.get(); |
| |
| copyValues(contextComponentSrc, contextComponentDst, Arrays.asList("Id", "Name"), true); |
| |
| copyFiles(contextComponentSrc, contextComponentDst, transaction); |
| |
| } else if (null != templateRootDst) { |
| Optional<TemplateComponent> optTemplateComponent = templateRootDst |
| .getTemplateComponent(contextComponentSrc.getName()); |
| |
| if (optTemplateComponent.isPresent()) { |
| TemplateComponent templateComponent = optTemplateComponent.get(); |
| if (templateComponent.isOptional() && !templateComponent.isDefaultActive()) { |
| ContextComponent contextComponentDst = entityFactoryDst |
| .createContextComponent(contextComponentSrc.getName(), contextRootDst); |
| |
| copyValues(contextComponentSrc, contextComponentDst, Arrays.asList("Id", "Name"), true); |
| |
| persist(transaction, contextComponentDst); |
| |
| copyFiles(contextComponentSrc, contextComponentDst, transaction); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| private Measurement copyMeasurement(Measurement measurementSrc, List<ContextRoot> listContextRootsDst, |
| boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(measurementSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| boolean append = Boolean.valueOf(properties.getOrDefault(PROPERTY_APPEND, DEFAULT_APPEND)); |
| |
| if (null == ehDst) { |
| LOG.trace("Importing Measurement '{}'", measurementSrc.getName()); |
| TestStep testStepSrc = entityManagerSrc.loadParent(measurementSrc, TestStep.class).get(); |
| TestStep testStepParentDst = (TestStep) mapSrcDstEntities |
| .get(new EntityHolder(testStepSrc, entityManagerSrc)).getEntity(); |
| |
| // EntityType etMeasurement = modelManagerDst.getEntityType(Measurement.class); |
| // EntityType etTestStep = modelManagerDst.getEntityType(TestStep.class); |
| // |
| // Relation relTestStep = etMeasurement.getRelation(etTestStep); |
| // |
| // if (null == relTestStep) { |
| // throw new ApiCopyException("No relation to TestStep found at MeaResult!"); |
| // } |
| // |
| // Filter filter = Filter.nameOnly(etMeasurement, measurementSrc.getName()).id(relTestStep, |
| // testStepParentDst.getID()); |
| // |
| // Optional<Measurement> optMeasurement = fetchOne(searchServiceDst, Measurement.class, filter); |
| Optional<Measurement> optMeasurement = fetchChild(entityManagerDst, testStepParentDst, Measurement.class, |
| measurementSrc.getName()); |
| |
| Measurement measurementDst = null; |
| |
| if (optMeasurement.isPresent() && !append) { |
| throw new ApiCopyException(String.format("TestStep '%s' has already a measurement with name '%s'!", |
| testStepParentDst.getName(), measurementSrc.getName())); |
| } else if (optMeasurement.isPresent()) { |
| measurementDst = optMeasurement.get(); |
| } else { |
| append = false; |
| } |
| |
| Test testDst = (Test) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(testStepSrc, Test.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| Optional<TemplateTestStep> optTemplateTestStep = loadTemplateTestStep(testDst, testStepSrc); |
| |
| // If no ContextRoots to use with the newly created Measurement are passed into |
| // this method, use ContextRoots |
| // of any already existing Measurement under the parent test step. |
| // First look in destination... |
| if (listContextRootsDst.isEmpty()) { |
| for (Measurement existingMeasurementDst : entityManagerDst.loadChildren(testStepParentDst, |
| Measurement.class)) { |
| listContextRootsDst.addAll( |
| existingMeasurementDst.loadContexts(entityManagerDst, ContextType.values()).values()); |
| |
| if (!listContextRootsDst.isEmpty()) { |
| break; |
| } |
| } |
| } |
| |
| // ...then, if nothing has been found, in source and try to find destination |
| // counterpart in cache map: |
| if (listContextRootsDst.isEmpty()) { |
| for (Measurement existingMeasurementSrc : entityManagerSrc.loadChildren(testStepSrc, |
| Measurement.class)) { |
| EntityHolder eh = mapSrcDstEntities.get(new EntityHolder(existingMeasurementSrc, entityManagerSrc)); |
| if (null != eh) { |
| listContextRootsDst.addAll(((Measurement) eh.getEntity()) |
| .loadContexts(entityManagerDst, ContextType.values()).values()); |
| } |
| |
| if (!listContextRootsDst.isEmpty()) { |
| break; |
| } |
| } |
| } |
| |
| // Still no ContextRoots found? Create them from the test step template: |
| if (listContextRootsDst.isEmpty() && optTemplateTestStep.isPresent()) { |
| optTemplateTestStep.get().getTemplateRoots() |
| .forEach(tr -> listContextRootsDst.add(entityFactoryDst.createContextRoot(tr))); |
| } |
| |
| if (measurementDst == null) { |
| measurementDst = entityFactoryDst.createMeasurement(measurementSrc.getName(), testStepParentDst, |
| listContextRootsDst.toArray(new ContextRoot[listContextRootsDst.size()])); |
| } |
| |
| copyValues(measurementSrc, measurementDst, Arrays.asList("Id", "Name"), true); |
| |
| ehDst = new EntityHolder(measurementDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| Map<ContextType, ContextRoot> mapContextRootsSrc = testStepParentDst.loadContexts(entityManagerDst, |
| ContextType.values()); |
| Map<ContextType, ContextRoot> mapContextRootsDst = measurementDst.loadContexts(entityManagerDst, |
| ContextType.values()); |
| |
| copyContext(mapContextRootsSrc, mapContextRootsDst, optTemplateTestStep, transaction); |
| |
| mapContextRootsSrc = measurementSrc.loadContexts(entityManagerSrc, ContextType.values()); |
| mapContextRootsDst = measurementDst.loadContexts(entityManagerDst, ContextType.values()); |
| copyContext(mapContextRootsSrc, mapContextRootsDst, optTemplateTestStep, transaction); |
| |
| persist(transaction, measurementDst); |
| |
| copyFiles(measurementSrc, measurementDst, transaction); |
| |
| String projectName = getProjectName(entityManagerSrc.loadParent(measurementSrc, TestStep.class).get(), |
| entityManagerSrc); |
| Classification classification = classificationUtil.getClassification(projectName); |
| classification.assign(testStepParentDst); |
| persist(transaction, testStepParentDst); |
| |
| Iterator<ContextRoot> contextRootIter = mapContextRootsDst.values().iterator(); |
| |
| while (contextRootIter.hasNext()) { |
| ContextRoot contextRootForUpdate = contextRootIter.next(); |
| persist(transaction, contextRootForUpdate); |
| } |
| |
| if (recursive) { |
| |
| Collection<ChannelGroup> channelGroupsToDelete = new ArrayList<>(); |
| Collection<Channel> channelsToDelete = new ArrayList<>(); |
| |
| List<Channel> sourceChannels = entityManagerSrc.loadChildren(measurementSrc, Channel.class); |
| List<WriteRequest> listWriteRequests = new ArrayList<>(); |
| |
| Map<String, Channel> mapChannelsDst = new HashMap<>(); |
| Map<String, Channel> mapChannelsSrc = new HashMap<>(); |
| |
| List<Channel> existingChannels = entityManagerDst.loadChildren(measurementDst, Channel.class); |
| if (append && !isSrcChannelsValid(sourceChannels, existingChannels)) { |
| throw new ApiCopyException( |
| "Appending not possible. All channels of existing measurement have to be in the source measurement"); |
| } |
| |
| Map<String, Optional<Quantity>> quantitiesByName = preloadQuantities(sourceChannels); |
| Map<String, Unit> unitsByName = preloadUnits(sourceChannels); |
| for (Channel channel : sourceChannels) { |
| Channel channelDst = copyChannel(channel, measurementDst, existingChannels, quantitiesByName, |
| unitsByName, transaction); |
| mapChannelsDst.put(channel.getName(), channelDst); |
| mapChannelsSrc.put(channel.getName(), channel); |
| } |
| |
| for (ChannelGroup channelGroupSrc : entityManagerSrc.loadChildren(measurementSrc, ChannelGroup.class)) { |
| Map<String, MeasuredValues> existingMeasValuesToAppend = new HashMap<>(); |
| |
| Integer numberOfValues = 0; |
| if (append) { |
| Optional<ChannelGroup> optChannelGroup = fetchOneChannelGroup(entityManagerSrc, |
| channelGroupSrc); |
| |
| if (optChannelGroup.isPresent()) { |
| numberOfValues = optChannelGroup.get().getNumberOfValues(); |
| existingMeasValuesToAppend = getMeasurementValuesMap(entityManagerDst, |
| optChannelGroup.get()); |
| } |
| |
| } |
| |
| ChannelGroup channelGroupDst = copyChannelGroup(channelGroupSrc, transaction, append, |
| channelGroupsToDelete); |
| |
| for (MeasuredValues measuredValues : entityManagerSrc.readMeasuredValues(ReadRequest |
| .create(channelGroupSrc).valuesMode(ValuesMode.STORAGE).allChannels().allValues())) { |
| LOG.trace("Importing MeasuredValues '{}'", measuredValues.getName()); |
| if (!mapChannelsDst.containsKey(measuredValues.getName())) { |
| throw new ApiCopyException( |
| String.format("Cannot find Channel %s in destination!", measuredValues.getName())); |
| } |
| |
| Channel channelDst = mapChannelsDst.get(measuredValues.getName()); |
| |
| String sourceUnitName = unitMapping.getOrDefault(measuredValues.getUnit(), |
| measuredValues.getUnit()); |
| |
| List<Unit> sourceUnits = entityManagerDst.loadAll(Unit.class, escapeWildcards(sourceUnitName)); |
| |
| if (!sourceUnitName.isEmpty() && (sourceUnits == null || sourceUnits.isEmpty())) { |
| throw new ApiCopyException( |
| String.format("Unit with name '%s' not found in target!", sourceUnitName)); |
| } |
| |
| Unit sourceUnit = null; |
| |
| if (sourceUnits != null && !sourceUnits.isEmpty()) { |
| sourceUnit = sourceUnits.get(0); |
| } |
| if (append) { |
| |
| Channel channelSrc = mapChannelsSrc.get(channelDst.getName()); |
| |
| channelsToDelete.add(channelDst); |
| channelDst = replaceChannelDst(channelSrc, channelDst, measurementDst, ehSrc, transaction); |
| |
| MeasuredValues measuredValuesOld = existingMeasValuesToAppend.get(channelDst.getName()); |
| |
| if (measuredValuesOld == null) { |
| measuredValuesOld = MeasuredValuesHelper.createEmptyValues(measuredValues.getName(), |
| measuredValues.getScalarType(), measuredValues.getUnit(), |
| measuredValues.getSequenceRepresentation(), |
| measuredValues.getGenerationParameters(), measuredValues.isIndependent(), |
| measuredValues.getAxisType(), numberOfValues); |
| } |
| |
| measuredValues = MeasuredValuesHelper.appenMeasuredValues(measuredValuesOld, |
| measuredValues); |
| |
| } |
| |
| listWriteRequests.add(createWriteRequest(channelGroupDst, channelDst, measuredValues, |
| sourceUnit, mapChannelsSrc.get(channelDst.getName()))); |
| } |
| |
| } |
| |
| transaction.writeMeasuredValues(listWriteRequests); |
| transaction.delete(channelsToDelete); |
| transaction.delete(channelGroupsToDelete); |
| |
| } |
| } |
| |
| return (Measurement) ehDst.getEntity(); |
| } |
| |
| private boolean isSrcChannelsValid(List<Channel> channelsSrc, List<Channel> channelsDst) { |
| boolean isSrcChannelsValid = true; |
| |
| Map<String, Channel> sourceMap = new HashMap<>(); |
| channelsSrc.forEach(srcChannel -> sourceMap.put(srcChannel.getName(), srcChannel)); |
| |
| for (Channel channelDst : channelsDst) { |
| if (sourceMap.get(channelDst.getName()) == null) { |
| isSrcChannelsValid = false; |
| break; |
| } |
| } |
| |
| return isSrcChannelsValid; |
| } |
| |
| private Channel replaceChannelDst(Channel channelSrc, Channel channelDst, Measurement measurementDst, |
| EntityHolder ehSrc, Transaction transaction) { |
| Channel channelNew = entityFactoryDst.createChannel(channelDst.getName(), measurementDst, |
| channelDst.getQuantity()); |
| |
| copyValues(channelDst, channelNew, Arrays.asList("Id"), false); |
| persist(transaction, channelNew); |
| |
| mapSrcDstEntities.put(new EntityHolder(channelSrc, entityManagerSrc), |
| new EntityHolder(channelNew, entityManagerDst)); |
| |
| return channelNew; |
| } |
| |
| private Map<String, MeasuredValues> getMeasurementValuesMap(EntityManager entityManager, |
| ChannelGroup channelGroup) { |
| |
| Map<String, MeasuredValues> returnVal = new HashMap<>(); |
| |
| for (MeasuredValues measuredValues : entityManager.readMeasuredValues( |
| ReadRequest.create(channelGroup).valuesMode(ValuesMode.STORAGE).allChannels().allValues())) { |
| returnVal.put(measuredValues.getName(), measuredValues); |
| } |
| return returnVal; |
| } |
| |
| /** |
| * Preloads quantities from dst for the supplied Channels from src. |
| * |
| * @param srcChannels |
| * @return |
| */ |
| private Map<String, Optional<Quantity>> preloadQuantities(List<Channel> srcChannels) { |
| |
| LOG.trace("Preloading Quantities."); |
| |
| // Load quantity names in dst by name |
| Set<String> quantityNames = srcChannels.stream().map(c -> c.getQuantity().getName()) |
| .map(n -> quantityMapping.getOrDefault(n, n)).collect(Collectors.toSet()); |
| |
| List<Quantity> results = entityManagerDst.loadAll(Quantity.class, quantityNames); |
| |
| // Find a valid quantity with the highest version |
| /* |
| * TODO Quantity should actually implement Versionable, then we could just use |
| * org.eclipse.mdm.api.dflt.EntityManager.loadLatestValid(Class<T>, String) Bug: |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=553368 |
| */ |
| |
| Comparator<Quantity> compareByVersion = Comparator |
| .comparing(q -> Integer.valueOf(q.getValue(Versionable.ATTR_VERSION).extract())); |
| |
| return results.stream().filter(q -> q.getValue(Versionable.ATTR_VERSION_STATE).extract() == VersionState.VALID) |
| .collect(Collectors.groupingBy(Quantity::getName, Collectors.maxBy(compareByVersion))); |
| } |
| |
| /** |
| * Preloads quantities from dst for the supplied Channels from src. |
| * |
| * @param srcChannels |
| * @return |
| */ |
| private Map<String, Unit> preloadUnits(List<Channel> srcChannels) { |
| |
| LOG.trace("Preloading Units."); |
| |
| // Load unit names in dst by name |
| Set<String> unitNames = srcChannels.stream().filter(c -> c.getUnit() != null).map(c -> c.getUnit().getName()) |
| .map(n -> unitMapping.getOrDefault(n, n)).collect(Collectors.toSet()); |
| |
| List<Unit> results = entityManagerDst.loadAll(Unit.class, unitNames); |
| |
| Map<String, Unit> mapping = new HashMap<>(); |
| for (Unit u : results) { |
| mapping.put(u.getName(), u); |
| } |
| |
| // Add units for aliased unit names |
| for (Map.Entry<String, String> entry : unitMapping.entrySet()) { |
| Unit mappedUnit = mapping.get(entry.getValue()); |
| mapping.put(entry.getKey(), mappedUnit); |
| LOG.debug("Mapping {} to {}", entry.getKey(), mappedUnit); |
| } |
| |
| return mapping; |
| } |
| |
| private Optional<ChannelGroup> fetchOneChannelGroup(EntityManager entityManager, ChannelGroup channelGroupSrc) { |
| Measurement measurementParentDst = (Measurement) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(channelGroupSrc, Measurement.class).get(), |
| entityManagerSrc)) |
| .getEntity(); |
| |
| return fetchChild(entityManager, measurementParentDst, ChannelGroup.class, channelGroupSrc.getName()); |
| |
| } |
| |
| private ChannelGroup copyChannelGroup(ChannelGroup channelGroupSrc, Transaction transaction, boolean append, |
| Collection<ChannelGroup> entitiesToDelete) { |
| EntityHolder ehSrc = new EntityHolder(channelGroupSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Importing ChannelGroup '{}'", channelGroupSrc.getName()); |
| Measurement measurementParentDst = (Measurement) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(channelGroupSrc, Measurement.class).get(), |
| entityManagerSrc)) |
| .getEntity(); |
| |
| EntityType etChannelGroup = modelManagerDst.getEntityType(ChannelGroup.class); |
| EntityType etMeasurement = modelManagerDst.getEntityType(Measurement.class); |
| |
| Relation relMeasurement = etChannelGroup.getRelation(etMeasurement); |
| |
| if (null == relMeasurement) { |
| throw new ApiCopyException("No relation to MeaResult found at SubMatrix!"); |
| } |
| |
| Optional<ChannelGroup> channelGroupOptional = fetchOneChannelGroup(entityManagerDst, channelGroupSrc); |
| |
| ChannelGroup channelGroupDst = null; |
| |
| if (append && channelGroupOptional.isPresent()) { |
| entitiesToDelete.add(channelGroupOptional.get()); |
| channelGroupDst = entityFactoryDst.createChannelGroup(channelGroupSrc.getName(), |
| channelGroupSrc.getNumberOfValues(), measurementParentDst); |
| } else { |
| channelGroupDst = channelGroupOptional |
| .orElseGet(() -> entityFactoryDst.createChannelGroup(channelGroupSrc.getName(), |
| channelGroupSrc.getNumberOfValues(), measurementParentDst)); |
| } |
| |
| copyValues(channelGroupSrc, channelGroupDst, Arrays.asList("Id"), false); |
| |
| persist(transaction, channelGroupDst); |
| |
| ehDst = new EntityHolder(channelGroupDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| } |
| |
| return (ChannelGroup) ehDst.getEntity(); |
| } |
| |
| private Optional<TemplateTest> loadTemplateTest(Test testSrc) { |
| Optional<TemplateTest> returnVal = Optional.empty(); |
| |
| String templateTestName = templateManager.getTemplateTestName(testSrc); |
| |
| if (Strings.isNullOrEmpty(templateTestName) && isRequireTemplate()) { |
| throw new ApiCopyException( |
| "TemplateManager returned no template test name, but " + PROPERTY_REQUIRE_TEMPLATE + " is true."); |
| } |
| |
| if (!Strings.isNullOrEmpty(templateTestName)) { |
| returnVal = getCurrentValidTestTemplate( |
| entityManagerDst.loadAll(TemplateTest.class, escapeWildcards(templateTestName))); |
| if (isRequireTemplate() && !returnVal.isPresent()) { |
| throw new ApiCopyException("No valid TemplateTest with name '" + templateTestName |
| + "' found in target datasource! " |
| + "Either specify an existing valid template name or create a new valid TemplateTest with given name."); |
| } |
| } |
| |
| return returnVal; |
| } |
| |
| private Optional<TemplateTest> getCurrentValidTestTemplate(List<TemplateTest> listTemplateTests) { |
| Optional<TemplateTest> returnVal = Optional.empty(); |
| |
| if (listTemplateTests != null && !listTemplateTests.isEmpty()) { |
| int highestVersion = -1; |
| TemplateTest highestValidTemplate = null; |
| |
| for (TemplateTest templateTest : listTemplateTests) { |
| Value value = templateTest.getValue(TemplateTest.ATTR_VERSION_STATE); |
| |
| if (VersionState.VALID.equals(value.extract())) { |
| int version = Integer.parseInt(templateTest.getValue(TemplateTest.ATTR_VERSION).extract()); |
| |
| if (version > highestVersion) { |
| highestValidTemplate = templateTest; |
| highestVersion = version; |
| } |
| } |
| |
| } |
| |
| if (highestValidTemplate != null) { |
| returnVal = Optional.of(highestValidTemplate); |
| } |
| |
| } |
| return returnVal; |
| } |
| |
| /** |
| * Load the {@link TemplateTestStep} to use for import. |
| * |
| * @param testDst parent {@link Test} in the target datasource |
| * @param testStepSrc {@link TestStep} to import |
| * @return {@link TemplateTestStep} to use for importing the given |
| * {@link TestStep} |
| */ |
| private Optional<TemplateTestStep> loadTemplateTestStep(Test testDst, TestStep testStepSrc) { |
| Optional<TemplateTestStep> returnVal = Optional.empty(); |
| |
| String templateTestStepName = templateManager.getTemplateTestStepName(testStepSrc); |
| |
| if (Strings.isNullOrEmpty(templateTestStepName) && isRequireTemplate()) { |
| throw new ApiCopyException("TemplateManager returned no template teststep name, but " |
| + PROPERTY_REQUIRE_TEMPLATE + " is true."); |
| } |
| |
| if (!Strings.isNullOrEmpty(templateTestStepName)) { |
| returnVal = TemplateTest.of(testDst) |
| .flatMap(tt -> getTemplateTestStepHighestValidVersion(tt, templateTestStepName)); |
| |
| if (isRequireTemplate() && !returnVal.isPresent()) { |
| throw new ApiCopyException("No valid TemplateTestStep with name '" + templateTestStepName |
| + "' found in target datasource! " |
| + "Either specify an existing valid template name or create a valid TemplateTestStep with given name."); |
| } |
| } |
| return returnVal; |
| } |
| |
| /** |
| * Get the highest valid {@link TemplateTestStep} of the given |
| * {@link TemplateTest} with the specified name. |
| * |
| * @param tplTest {@link TemplateTest} |
| * @param name Name of the requested {@link TemplateTestStep} |
| * @return the {@link TemplateTestStep} |
| */ |
| private Optional<TemplateTestStep> getTemplateTestStepHighestValidVersion(TemplateTest tplTest, String name) { |
| return tplTest.getTemplateTestStepUsages().stream().map(TemplateTestStepUsage::getTemplateTestStep) |
| .filter(tts -> tts.nameEquals(name)).filter(TemplateTestStep::isValid) |
| .sorted(Comparator.comparing(tts -> tts.getVersion(), Comparator.reverseOrder())).findFirst(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.mdm.apicopy.control.ApiCopyTask#setProperties(java.util.Map) |
| */ |
| @Override |
| public void setProperties(Map<String, String> properties) { |
| this.properties = properties; |
| this.replaceFileLinks = Boolean |
| .valueOf(this.properties.getOrDefault(PROPERTY_REPLACE_FILELINKS, DEFAULT_REPLACE_FILES)); |
| } |
| |
| } |