| /******************************************************************************** |
| * Copyright (c) 2015, 2023 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.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.stream.Stream; |
| |
| import org.eclipse.mdm.api.base.Transaction; |
| import org.eclipse.mdm.api.base.adapter.Core; |
| 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.BaseEntity; |
| import org.eclipse.mdm.api.base.model.BaseEntityFactory; |
| 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.ContextDescribable; |
| import org.eclipse.mdm.api.base.model.ContextRoot; |
| import org.eclipse.mdm.api.base.model.ContextSensor; |
| 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.PhysicalDimension; |
| 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.ValueType; |
| import org.eclipse.mdm.api.dflt.ApplicationContext; |
| import org.eclipse.mdm.api.dflt.model.CatalogAttribute; |
| import org.eclipse.mdm.api.dflt.model.CatalogComponent; |
| import org.eclipse.mdm.api.dflt.model.CatalogSensor; |
| import org.eclipse.mdm.api.dflt.model.EntityFactory; |
| import org.eclipse.mdm.api.dflt.model.Pool; |
| import org.eclipse.mdm.api.dflt.model.Project; |
| 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.apicopy.boundary.ExportType; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.common.collect.ListMultimap; |
| |
| public class ExportTask extends TransferBase implements ApiCopyTask { |
| private static final String TEMPLATE_ATTRIBUTE = "template"; |
| private static final Logger LOG = LoggerFactory.getLogger(ExportTask.class); |
| |
| public ExportTask(ApplicationContext src, ApplicationContext dst) { |
| super(src, dst); |
| } |
| |
| @Override |
| public void copy(List<? extends Entity> entities) { |
| Transaction transaction = entityManagerDst.startTransaction(); |
| try { |
| mapSrcDstEntities.clear(); |
| mapFileLinksExtComp.clear(); |
| |
| List<Entity> entitiesWithIndChannels = new ArrayList<>(); |
| entitiesWithIndChannels.addAll(entities); |
| |
| // if any Channel is exported, the corresponding Independent Channel should be |
| // exported too. |
| entities.stream().filter(e -> Channel.class.isInstance(e)).flatMap(e -> loadIndependent((Channel) e)) |
| .forEach(e -> entitiesWithIndChannels.add(e)); |
| |
| ListMultimap<Class<? extends Entity>, Entity> parents = loadParents(entitiesWithIndChannels); |
| LOG.trace("Resolved parents: {}", parents); |
| supportedRootEntities.forEach(ec -> parents.get(ec).forEach(e -> copyEntity(e, false, transaction))); |
| |
| LOG.trace("Exporting entities: {}", entitiesWithIndChannels); |
| entitiesWithIndChannels.forEach(e -> copyEntity(e, true, transaction)); |
| |
| transaction.commit(); |
| } catch (Exception exc) { |
| try { |
| transaction.abort(); |
| } catch (Exception exc2) { |
| LOG.error("Could not abort transaction!"); |
| } |
| |
| throw new ApiCopyException("Could not copy data.", exc); |
| } finally { |
| clearReplacedFileLinkCache(); |
| clearUploadedFileLinkCache(); |
| deleteLocalTempFiles(); |
| } |
| } |
| |
| private Stream<Entity> loadIndependent(Channel e) { |
| ChannelGroup channelGroup = entityManagerSrc.loadParent(e, ChannelGroup.class).get(); |
| return Stream.concat(Stream.of(e), loadIndependent(contextSrc, channelGroup).stream()); |
| } |
| |
| 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, recursive, transaction); |
| } else if (entity instanceof ChannelGroup) { |
| return copyChannelGroup((ChannelGroup) entity, recursive, transaction); |
| } else if (entity instanceof Channel) { |
| return copyChannel((Channel) entity, 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) { |
| LOG.trace("Exporting 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("Exporting Pool '{}'", poolSrc.getName()); |
| Project projectParentDst = (Project) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(poolSrc, Project.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| 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) { |
| LOG.trace("Exporting Test '{}'", testSrc.getName()); |
| Pool poolParentDst = (Pool) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(testSrc, Pool.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| Test testDst = entityFactoryDst.createTest(testSrc.getName(), poolParentDst); |
| |
| copyValues(testSrc, testDst, Arrays.asList("Id", "Name"), false); |
| |
| Optional<TemplateTest> templateTest = TemplateTest.of(testSrc); |
| if (templateTest.isPresent()) { |
| getCore(testDst, entityFactoryDst).ifPresent(c -> c.getValues().put(TEMPLATE_ATTRIBUTE, |
| ValueType.STRING.create(TEMPLATE_ATTRIBUTE, templateTest.get().getName()))); |
| } |
| |
| persist(transaction, testDst); |
| |
| copyFiles(testSrc, testDst, transaction); |
| |
| ehDst = new EntityHolder(testDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| entityManagerSrc.loadChildren(testSrc, TestStep.class) |
| .forEach(testStep -> copyTestStep(testStep, recursive, transaction)); |
| } |
| } |
| |
| return (Test) ehDst.getEntity(); |
| } |
| |
| private Optional<Core> getCore(BaseEntity entity, EntityFactory entityFactory) { |
| return Optional.ofNullable(BaseEntityFactory.getCore(entity)); |
| |
| // if (entityFactory instanceof ODSEntityFactory) { |
| // return Optional.ofNullable(ODSEntityFactory.extract(entity)); |
| // } else if (entityFactoryDst instanceof CSVEntityFactory) { |
| // return Optional.ofNullable(CSVEntityFactory.getCSVCore(entity)); |
| // } else { |
| // return Optional.empty(); |
| // } |
| } |
| |
| 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("Exporting TestStep '{}'", testStepSrc.getName()); |
| Test testParentDst = (Test) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(testStepSrc, Test.class).get(), entityManagerSrc)) |
| .getEntity(); |
| |
| TestStep testStepDst = entityFactoryDst.createTestStep(testStepSrc.getName(), testParentDst); |
| |
| copyValues(testStepSrc, testStepDst, Arrays.asList("Id", "Name"), false); |
| |
| Optional<TemplateTestStep> templateTest = TemplateTestStep.of(testStepSrc); |
| if (templateTest.isPresent()) { |
| getCore(testStepDst, entityFactoryDst).ifPresent(c -> c.getValues().put(TEMPLATE_ATTRIBUTE, |
| ValueType.STRING.create(TEMPLATE_ATTRIBUTE, templateTest.get().getName()))); |
| } |
| |
| persist(transaction, testStepDst); |
| |
| copyFiles(testStepSrc, testStepDst, transaction); |
| |
| TemplateTestStep tpl = entityManagerSrc.loadTemplate(testStepSrc).orElseThrow(() -> new ApiCopyException( |
| "Could not retrieve TemplateTestStep for TestStep " + testStepSrc.getID())); |
| |
| copyContext(testStepSrc, testStepDst, tpl, transaction); |
| |
| ehDst = new EntityHolder(testStepDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| entityManagerSrc.loadChildren(testStepSrc, Measurement.class) |
| .forEach(measurement -> copyMeasurement(measurement, recursive, transaction)); |
| } |
| } |
| return (TestStep) ehDst.getEntity(); |
| } |
| |
| private Measurement copyMeasurement(Measurement measurementSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(measurementSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Exporting Measurement '{}'", measurementSrc.getName()); |
| TestStep testStepParentSrc = entityManagerSrc.loadParent(measurementSrc, TestStep.class).get(); |
| |
| TestStep testStepParentDst = (TestStep) mapSrcDstEntities |
| .get(new EntityHolder(testStepParentSrc, entityManagerSrc)).getEntity(); |
| |
| Measurement measurementDst = entityFactoryDst.createMeasurement(measurementSrc.getName(), |
| testStepParentDst); |
| |
| copyValues(measurementSrc, measurementDst, Arrays.asList("Id", "Name"), false); |
| |
| persist(transaction, measurementDst); |
| |
| copyFiles(measurementSrc, measurementDst, transaction); |
| |
| TemplateTestStep tpl = entityManagerSrc.loadTemplate(testStepParentSrc) |
| .orElseThrow(() -> new ApiCopyException( |
| "Could not retrieve TemplateTestStep for Measurement + " + measurementSrc.getID())); |
| |
| copyContext(measurementSrc, measurementDst, tpl, transaction); |
| |
| ehDst = new EntityHolder(measurementDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| List<WriteRequest> listWriteRequests = new ArrayList<>(); |
| |
| Map<String, Channel> mapChannels = new HashMap<>(); |
| List<Channel> srcChannels = entityManagerSrc.loadChildren(measurementSrc, Channel.class); |
| |
| Map<String, Unit> unitMap = copyUnits(srcChannels, transaction); |
| Map<String, Optional<Quantity>> quantityMap = copyQuantities(srcChannels, unitMap, transaction); |
| |
| LOG.info("Measurement: id: " + measurementSrc.getID() + ", Name: '" + measurementSrc.getName() + "'"); |
| List<Channel> dstChannels = copyChannels(srcChannels, measurementDst, Collections.emptyList(), |
| quantityMap, unitMap, transaction); |
| for (Channel channelDst : dstChannels) { |
| mapChannels.put(channelDst.getName(), channelDst); |
| } |
| |
| for (ChannelGroup channelGroup : entityManagerSrc.loadChildren(measurementSrc, ChannelGroup.class)) { |
| ChannelGroup channelGroupDst = copyChannelGroup(channelGroup, transaction); |
| |
| ValuesMode valuesMode = contextDst.getParameters().containsKey(ExportType.ATFX.getKey()) |
| ? ValuesMode.STORAGE_PRESERVE_EXTCOMPS |
| : ValuesMode.CALCULATED; |
| for (MeasuredValues measuredValues : entityManagerSrc.readMeasuredValues( |
| ReadRequest.create(channelGroup).valuesMode(valuesMode).allChannels().allValues())) { |
| LOG.trace("Exporting MeasuredValues '{}'", measuredValues.getName()); |
| if (!mapChannels.containsKey(measuredValues.getName())) { |
| throw new ApiCopyException( |
| String.format("Cannot find Channel %s in destination!", measuredValues.getName())); |
| } |
| |
| Channel channelDst = mapChannels.get(measuredValues.getName()); |
| |
| if (channelDst.getUnit() != null |
| && !channelDst.getUnit().getName().equals(measuredValues.getUnit())) { |
| throw new ApiCopyException("Conversion of units is not supported (" |
| + measuredValues.getUnit() + " -> " + channelDst.getUnit().getName() + ")."); |
| } |
| |
| listWriteRequests |
| .add(createWriteRequest(entityManagerSrc, channelGroupDst, channelDst, measuredValues, |
| channelDst.getUnit(), mapChannels.get(channelDst.getName()), transaction)); |
| } |
| } |
| |
| transaction.writeMeasuredValues(listWriteRequests); |
| } |
| } |
| |
| return (Measurement) ehDst.getEntity(); |
| } |
| |
| private ChannelGroup copyChannelGroup(ChannelGroup channelGroupSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(channelGroupSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Exporting ChannelGroup '{}'", channelGroupSrc.getName()); |
| Measurement measurementParentSrc = entityManagerSrc.loadParent(channelGroupSrc, Measurement.class).get(); |
| |
| Measurement measurementParentDst = (Measurement) mapSrcDstEntities |
| .get(new EntityHolder(measurementParentSrc, entityManagerSrc)).getEntity(); |
| |
| ChannelGroup channelGroupDst = entityFactoryDst.createChannelGroup(channelGroupSrc.getName(), |
| channelGroupSrc.getNumberOfValues(), measurementParentDst); |
| |
| copyValues(channelGroupSrc, channelGroupDst, Arrays.asList("Id", "Name"), false); |
| |
| persist(transaction, channelGroupDst); |
| |
| ehDst = new EntityHolder(channelGroupDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| |
| List<WriteRequest> listWriteRequests = new ArrayList<>(); |
| Map<String, Channel> mapChannels = new HashMap<>(); |
| |
| List<Channel> srcChannels = entityManagerSrc.loadChildren(channelGroupSrc, Channel.class); |
| |
| Map<String, Unit> unitMap = copyUnits(srcChannels, transaction); |
| Map<String, Optional<Quantity>> quantityMap = copyQuantities(srcChannels, unitMap, transaction); |
| |
| LOG.info( |
| "ChannelGroup: id: " + channelGroupSrc.getID() + ", Name: '" + channelGroupSrc.getName() + "'"); |
| List<Channel> dstChannels = copyChannels(srcChannels, measurementParentDst, Collections.emptyList(), |
| quantityMap, unitMap, transaction); |
| for (Channel channelDst : dstChannels) { |
| mapChannels.put(channelDst.getName(), channelDst); |
| } |
| |
| ValuesMode valuesMode = contextDst.getParameters().containsKey(ExportType.ATFX.getKey()) |
| ? ValuesMode.STORAGE_PRESERVE_EXTCOMPS |
| : ValuesMode.CALCULATED; |
| for (MeasuredValues measuredValues : entityManagerSrc.readMeasuredValues( |
| ReadRequest.create(channelGroupSrc).valuesMode(valuesMode).allChannels().allValues())) { |
| LOG.trace("Exporting MeasuredValues '{}'", measuredValues.getName()); |
| if (!mapChannels.containsKey(measuredValues.getName())) { |
| throw new ApiCopyException( |
| String.format("Cannot find Channel %s in destination!", measuredValues.getName())); |
| } |
| |
| Channel channelDst = mapChannels.get(measuredValues.getName()); |
| |
| if (!channelDst.getUnit().getName().equals(measuredValues.getUnit())) { |
| throw new ApiCopyException("Conversion of units is not supported (" + measuredValues.getUnit() |
| + " -> " + channelDst.getUnit().getName() + ")."); |
| } |
| |
| listWriteRequests.add(createWriteRequest(entityManagerSrc, channelGroupDst, channelDst, |
| measuredValues, channelDst.getUnit(), mapChannels.get(channelDst.getName()), transaction)); |
| |
| } |
| |
| transaction.writeMeasuredValues(listWriteRequests); |
| } |
| } |
| |
| return (ChannelGroup) ehDst.getEntity(); |
| } |
| |
| private Channel copyChannel(Channel channelSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(channelSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Exporting Channel '{}'", channelSrc.getName()); |
| ChannelGroup channelGroupParentSrc = entityManagerSrc.loadParent(channelSrc, ChannelGroup.class).get(); |
| Measurement measurementParentSrc = entityManagerSrc.loadParent(channelGroupParentSrc, Measurement.class) |
| .get(); |
| |
| ChannelGroup channelGroupParentDst = (ChannelGroup) mapSrcDstEntities |
| .get(new EntityHolder(channelGroupParentSrc, entityManagerSrc)).getEntity(); |
| |
| Measurement measurementParentDst = (Measurement) mapSrcDstEntities |
| .get(new EntityHolder(measurementParentSrc, entityManagerSrc)).getEntity(); |
| |
| List<Channel> srcChannels = new ArrayList<>(); |
| srcChannels.add(channelSrc); |
| |
| if (recursive) { |
| List<WriteRequest> listWriteRequests = new ArrayList<>(); |
| |
| Map<String, Channel> mapChannels = new HashMap<>(); |
| |
| Map<String, Unit> unitMap = copyUnits(srcChannels, transaction); |
| Map<String, Optional<Quantity>> quantityMap = copyQuantities(srcChannels, unitMap, transaction); |
| |
| LOG.info("ChannelGroup: id: " + channelGroupParentSrc.getID() + ", Name: '" |
| + channelGroupParentSrc.getName() + "'"); |
| List<Channel> dstChannels = copyChannels(srcChannels, measurementParentDst, Collections.emptyList(), |
| quantityMap, unitMap, transaction); |
| for (Channel channelDst : dstChannels) { |
| mapChannels.put(channelDst.getName(), channelDst); |
| |
| ehDst = new EntityHolder(channelDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| } |
| |
| ValuesMode valuesMode = contextDst.getParameters().containsKey(ExportType.ATFX.getKey()) |
| ? ValuesMode.STORAGE_PRESERVE_EXTCOMPS |
| : ValuesMode.CALCULATED; |
| // only clone measured values for the source channel |
| for (MeasuredValues measuredValues : entityManagerSrc.readMeasuredValues(ReadRequest |
| .create(channelGroupParentSrc).valuesMode(valuesMode).channels(srcChannels).allValues())) { |
| LOG.trace("Exporting MeasuredValues '{}'", measuredValues.getName()); |
| if (!mapChannels.containsKey(measuredValues.getName())) { |
| throw new ApiCopyException( |
| String.format("Cannot find Channel %s in destination!", measuredValues.getName())); |
| } |
| |
| Channel channelDst = mapChannels.get(measuredValues.getName()); |
| |
| if (!channelDst.getUnit().getName().equals(measuredValues.getUnit())) { |
| throw new ApiCopyException("Conversion of units is not supported (" + measuredValues.getUnit() |
| + " -> " + channelDst.getUnit().getName() + ")."); |
| } |
| |
| listWriteRequests.add(createWriteRequest(entityManagerSrc, channelGroupParentDst, channelDst, |
| measuredValues, channelDst.getUnit(), mapChannels.get(channelDst.getName()), transaction)); |
| } |
| |
| transaction.writeMeasuredValues(listWriteRequests); |
| } else { |
| Channel channelDst = entityFactoryDst.createChannel(measurementParentDst, channelSrc.getQuantity()); |
| |
| copyValues(channelSrc, channelDst, Arrays.asList("Id", "Name"), false); |
| |
| persist(transaction, channelDst); |
| |
| ehDst = new EntityHolder(channelDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| } |
| } |
| |
| return (Channel) ehDst.getEntity(); |
| } |
| |
| private void copyContext(ContextDescribable entitySrc, ContextDescribable entityDst, TemplateTestStep tpl, |
| Transaction transaction) { |
| |
| for (ContextRoot root : entitySrc.loadContexts(entityManagerSrc).values()) { |
| LOG.trace("Exporting ContextRoot '{}'", root.getName()); |
| TemplateRoot tplRoot = tpl.getTemplateRoot(root.getContextType()) |
| .orElseThrow(() -> new ApiCopyException("Could not retrieve TemplateRoot " + root.getContextType() |
| + " for TestStep + " + entitySrc.getID())); |
| |
| ContextRoot rootDst; |
| if (entityDst instanceof TestStep) { |
| rootDst = entityFactoryDst.createContextRoot((TestStep) entityDst, tplRoot); |
| } else if (entityDst instanceof Measurement) { |
| rootDst = entityFactoryDst.createContextRoot((Measurement) entityDst, tplRoot); |
| } else { |
| throw new ApiCopyException("ContextDescribable must be of instance TestStep or Measurement!"); |
| } |
| |
| copyValues(root, rootDst, Arrays.asList("Id", "Name"), false); |
| persist(transaction, rootDst); |
| |
| for (ContextComponent comp : root.getContextComponents()) { |
| LOG.trace("Exporting ContextComponent '{}'", comp.getName()); |
| rootDst.getContextComponent(comp.getName()).ifPresent(c -> { |
| copyValues(comp, c, Arrays.asList("Id", "Name"), false); |
| persist(transaction, c); |
| copyFiles(comp, c, transaction); |
| }); |
| } |
| for (ContextSensor sensor : root.getContextSensors()) { |
| LOG.trace("Exporting ContextSensor '{}'", sensor.getName()); |
| // Parent should be already created above |
| ContextComponent parentDst = rootDst.getContextComponent(sensor.getContextComponent().getName()) |
| .orElseThrow(() -> new ApiCopyException( |
| "Parent ContextComponent of sensor " + sensor.getName() + " not found!")); |
| |
| ContextSensor sensorDst = parentDst.getContextSensor(sensor.getName()).orElseThrow( |
| () -> new ApiCopyException("ContextSensor '" + sensor.getName() + "' not found in target!")); |
| copyValues(sensor, sensorDst, Arrays.asList("Id", "Name"), false); |
| persist(transaction, sensorDst); |
| copyFiles(sensor, sensorDst, transaction); |
| } |
| } |
| |
| persist(transaction, entityDst); |
| } |
| |
| /** |
| * Preloads quantities from dst for the supplied Channels from src. |
| * |
| * @param srcChannels |
| * @return |
| */ |
| private Map<String, Optional<Quantity>> copyQuantities(List<Channel> srcChannels, Map<String, Unit> unitMapping, |
| Transaction transaction) { |
| |
| LOG.trace("Copying Quantities."); |
| |
| Map<String, Optional<Quantity>> map = new HashMap<>(); |
| // TODO copy all Quantities with one call. |
| for (Channel channel : srcChannels) { |
| Quantity quantitySrc = channel.getQuantity(); |
| |
| if (quantitySrc != null) { |
| Quantity quantity = copyQuantity(quantitySrc, unitMapping, transaction); |
| map.put(quantity.getName(), Optional.of(quantity)); |
| } |
| } |
| return map; |
| } |
| |
| private Quantity copyQuantity(Quantity quantity, Map<String, Unit> unitMapping, Transaction transaction) { |
| |
| Quantity quantityDst = fetchOne(entityManagerDst, Quantity.class, quantity.getName()) |
| .orElseGet(() -> createQuantity(quantity, unitMapping)); |
| |
| if (isNewEntity(quantityDst)) { |
| copyValues(quantity, quantityDst, Arrays.asList("Id", "Name"), false); |
| persist(transaction, quantityDst); |
| } |
| return quantityDst; |
| } |
| |
| private Quantity createQuantity(Quantity quantitySrc, Map<String, Unit> unitMapping) { |
| if (quantitySrc.getDefaultUnit() == null) { |
| return entityFactoryDst.createQuantity(quantitySrc.getName()); |
| } else { |
| Unit unitDst = unitMapping.get(quantitySrc.getDefaultUnit().getName()); |
| if (unitDst == null) { |
| LOG.warn("Default Unit {} for Quantity {} not found. Exporting Quantity without default Unit", |
| quantitySrc.getDefaultUnit().getName(), quantitySrc.getName()); |
| return entityFactoryDst.createQuantity(quantitySrc.getName()); |
| } else { |
| return entityFactoryDst.createQuantity(quantitySrc.getName(), unitDst); |
| } |
| } |
| } |
| |
| private Map<String, Unit> copyUnits(List<Channel> srcChannels, Transaction transaction) { |
| LOG.trace("Copying Units."); |
| |
| Map<String, Unit> map = new HashMap<>(); |
| // TODO copy all Units with one call. |
| for (Channel channel : srcChannels) { |
| Unit unitSrc = channel.getUnit(); |
| |
| if (unitSrc != null) { |
| Unit unit = copyUnit(unitSrc, transaction); |
| map.put(unit.getName(), unit); |
| } |
| |
| if (channel.getQuantity() != null) { |
| Unit defaultUnitSrc = channel.getQuantity().getDefaultUnit(); |
| if (defaultUnitSrc != null) { |
| Unit defaultUnit = copyUnit(defaultUnitSrc, transaction); |
| map.put(defaultUnit.getName(), defaultUnit); |
| } |
| } |
| |
| } |
| return map; |
| } |
| |
| private Unit copyUnit(Unit unitSrc, Transaction transaction) { |
| PhysicalDimension physicalDimensionSrc = unitSrc.getPhysicalDimension(); |
| |
| PhysicalDimension physicalDimensionDst = null; |
| if (physicalDimensionSrc != null) { |
| physicalDimensionDst = fetchOne(entityManagerDst, PhysicalDimension.class, physicalDimensionSrc.getName()) |
| .orElseGet(() -> entityFactoryDst.createPhysicalDimension(physicalDimensionSrc.getName())); |
| |
| if (isNewEntity(physicalDimensionDst)) { |
| copyValues(physicalDimensionSrc, physicalDimensionDst, Arrays.asList("Id", "Name"), false); |
| persist(transaction, physicalDimensionDst); |
| } |
| } |
| final PhysicalDimension d = physicalDimensionDst; |
| |
| Unit unitDst = fetchOne(entityManagerDst, Unit.class, unitSrc.getName()) |
| .orElseGet(() -> entityFactoryDst.createUnit(unitSrc.getName(), d)); |
| |
| if (isNewEntity(unitDst)) { |
| copyValues(unitSrc, unitDst, Arrays.asList("Id", "Name"), false); |
| persist(transaction, unitDst); |
| } |
| |
| return unitDst; |
| } |
| |
| private ChannelGroup copyChannelGroup(ChannelGroup channelGroupSrc, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(channelGroupSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| LOG.trace("Exporting ChannelGroup '{}'", channelGroupSrc.getName()); |
| Measurement measurementParentDst = (Measurement) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(channelGroupSrc, Measurement.class).get(), |
| entityManagerSrc)) |
| .getEntity(); |
| |
| ChannelGroup channelGroupDst = entityFactoryDst.createChannelGroup(channelGroupSrc.getName(), |
| channelGroupSrc.getNumberOfValues(), measurementParentDst); |
| |
| copyValues(channelGroupSrc, channelGroupDst, Arrays.asList("Id", "Name"), false); |
| |
| persist(transaction, channelGroupDst); |
| |
| ehDst = new EntityHolder(channelGroupDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| } |
| |
| return (ChannelGroup) ehDst.getEntity(); |
| } |
| |
| /** |
| * Copy the MDM catalog. |
| */ |
| public void copyCatalog() { |
| Transaction catTransaction = entityManagerDst.startTransaction(); |
| try { |
| mapSrcDstEntities.clear(); |
| |
| LOG.trace("Exporting Catalog"); |
| // Copy catalog |
| List<CatalogComponent> catComps = new ArrayList<>(); |
| for (ContextType contextType : ContextType.values()) { |
| for (CatalogComponent catComp : entityManagerSrc.loadAll(CatalogComponent.class, contextType)) { |
| LOG.trace("Exporting CatalogComponent '{}'", catComp.getName()); |
| CatalogComponent catCompDst = entityFactoryDst.createCatalogComponent(catComp.getContextType(), |
| catComp.getName()); |
| for (CatalogAttribute catAttr : catComp.getCatalogAttributes()) { |
| if (catAttr.getValueType().isEnumerationType()) { |
| entityFactoryDst.createCatalogAttribute(catAttr.getName(), catAttr.getValueType(), |
| catAttr.getEnumerationObject(), catCompDst, catAttr.getUnit().orElse(null)); |
| } else { |
| entityFactoryDst.createCatalogAttribute(catAttr.getName(), catAttr.getValueType(), |
| catCompDst, catAttr.getUnit().orElse(null)); |
| } |
| } |
| |
| for (CatalogSensor catSensor : catComp.getCatalogSensors()) { |
| LOG.trace("Exporting CatalogSensor '{}'", catComp.getName()); |
| CatalogSensor catSensorDst = entityFactoryDst.createCatalogSensor(catSensor.getName(), |
| catCompDst); |
| for (CatalogAttribute catAttr : catSensor.getCatalogAttributes()) { |
| entityFactoryDst.createCatalogSensorAttribute(catAttr.getName(), catAttr.getValueType(), |
| catSensorDst, catAttr.getUnit().orElse(null)); |
| } |
| } |
| |
| catComps.add(catCompDst); |
| } |
| } |
| |
| catTransaction.create(catComps); |
| catTransaction.commit(); |
| } catch (Exception exc) { |
| try { |
| catTransaction.abort(); |
| } catch (Exception exc2) { |
| LOG.error("Could not abort transaction!"); |
| } |
| |
| throw new ApiCopyException("Could not copy data.", exc); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.mdm.apicopy.control.ApiCopyTask#setUnitMapping(java.util.Map) |
| */ |
| @Override |
| public void setUnitMapping(Map<String, String> unitMapping) { |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.mdm.apicopy.control.ApiCopyTask#setQuantityMapping(java.util.Map) |
| */ |
| @Override |
| public void setQuantityMapping(Map<String, String> quantityMapping) { |
| } |
| |
| @Override |
| public void setProperties(Map<String, String> properties) { |
| } |
| |
| } |