| /******************************************************************************** |
| * Copyright (c) 2015-2018 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; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.mdm.api.base.Transaction; |
| 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.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.dflt.ApplicationContext; |
| import org.eclipse.mdm.api.dflt.model.Pool; |
| import org.eclipse.mdm.api.dflt.model.Project; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.common.collect.ListMultimap; |
| |
| public class AtfxExportTask extends AtfxTransferBase implements ApiCopyTask { |
| private static final Logger LOG = LoggerFactory.getLogger(AtfxExportTask.class); |
| |
| public AtfxExportTask(ApplicationContext src, ApplicationContext dst) { |
| super(src, dst); |
| } |
| |
| @Override |
| public void copy(List<? extends Entity> entities) { |
| Transaction transaction = entityManagerDst.startTransaction(); |
| 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("Export entities: {}", entities); |
| entities.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); |
| } |
| } |
| |
| 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 { |
| 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) { |
| Project projectDst = entityFactoryDst.createProject(projectSrc.getName()); |
| |
| copyValues(projectSrc, projectDst, Arrays.asList("Id", "Name")); |
| |
| 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) { |
| 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")); |
| |
| 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(); |
| |
| Test testDst = entityFactoryDst.createTest(testSrc.getName(), poolParentDst); |
| |
| copyValues(testSrc, testDst, Arrays.asList("Id", "Name")); |
| |
| persist(transaction, testDst); |
| |
| 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 TestStep copyTestStep(TestStep testStepSrc, boolean recursive, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(testStepSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| 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")); |
| |
| persist(transaction, testStepDst); |
| |
| 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) { |
| TestStep testStepParentDst = (TestStep) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(measurementSrc, TestStep.class).get(), |
| entityManagerSrc)) |
| .getEntity(); |
| |
| Measurement measurementDst = entityFactoryDst.createMeasurement(measurementSrc.getName(), |
| testStepParentDst); |
| |
| copyValues(measurementSrc, measurementDst, Arrays.asList("Id", "Name")); |
| |
| persist(transaction, measurementDst); |
| |
| ehDst = new EntityHolder(measurementDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| |
| if (recursive) { |
| List<WriteRequest> listWriteRequests = new ArrayList<>(); |
| |
| Map<String, Channel> mapChannels = new HashMap<>(); |
| |
| for (Channel channel : entityManagerSrc.loadChildren(measurementSrc, Channel.class)) { |
| Channel channelDst = copyChannel(channel, transaction); |
| mapChannels.put(channel.getName(), channelDst); |
| } |
| |
| for (ChannelGroup channelGroup : entityManagerSrc.loadChildren(measurementSrc, ChannelGroup.class)) { |
| ChannelGroup channelGroupDst = copyChannelGroup(channelGroup, transaction); |
| |
| for (MeasuredValues measuredValues : entityManagerSrc.readMeasuredValues(ReadRequest |
| .create(channelGroup).valuesMode(ValuesMode.STORAGE).allChannels().allValues())) { |
| if (!mapChannels.containsKey(measuredValues.getName())) { |
| throw new ApiCopyException( |
| String.format("Cannot find Channel %s in destination!", measuredValues.getName())); |
| } |
| |
| Channel channelDst = mapChannels.get(measuredValues.getName()); |
| |
| listWriteRequests.add(createWriteRequest(channelGroupDst, channelDst, measuredValues)); |
| } |
| } |
| |
| transaction.writeMeasuredValues(listWriteRequests); |
| } |
| } |
| |
| return (Measurement) ehDst.getEntity(); |
| } |
| |
| private Channel copyChannel(Channel channelSrc, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(channelSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| Measurement measurementParentDst = (Measurement) mapSrcDstEntities |
| .get(new EntityHolder(entityManagerSrc.loadParent(channelSrc, Measurement.class).get(), |
| entityManagerSrc)) |
| .getEntity(); |
| |
| Quantity quantitySrc = channelSrc.getQuantity(); |
| Unit unitSrc = quantitySrc.getDefaultUnit(); |
| PhysicalDimension physicalDimensionSrc = unitSrc.getPhysicalDimension(); |
| |
| PhysicalDimension physicalDimensionDst = fetchOne(entityManagerDst, PhysicalDimension.class, |
| physicalDimensionSrc.getName()) |
| .orElseGet(() -> entityFactoryDst.createPhysicalDimension(physicalDimensionSrc.getName())); |
| |
| if (isNewEntity(physicalDimensionDst)) { |
| copyValues(physicalDimensionSrc, physicalDimensionDst, Arrays.asList("Id", "Name")); |
| persist(transaction, physicalDimensionDst); |
| } |
| |
| Unit unitDst = fetchOne(entityManagerDst, Unit.class, unitSrc.getName()) |
| .orElseGet(() -> entityFactoryDst.createUnit(unitSrc.getName(), physicalDimensionDst)); |
| |
| if (isNewEntity(unitDst)) { |
| copyValues(unitSrc, unitDst, Arrays.asList("Id", "Name")); |
| persist(transaction, unitDst); |
| } |
| |
| Quantity quantityDst = fetchOne(entityManagerDst, Quantity.class, quantitySrc.getName()) |
| .orElseGet(() -> entityFactoryDst.createQuantity(quantitySrc.getName(), unitDst)); |
| |
| if (isNewEntity(quantityDst)) { |
| copyValues(quantitySrc, quantityDst, Arrays.asList("Id", "Name")); |
| persist(transaction, quantityDst); |
| } |
| |
| Channel channelDst = entityFactoryDst.createChannel(measurementParentDst, quantityDst); |
| |
| copyValues(channelSrc, channelDst, Arrays.asList("Id", "Name")); |
| |
| persist(transaction, channelDst); |
| |
| ehDst = new EntityHolder(channelDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| } |
| |
| return (Channel) ehDst.getEntity(); |
| } |
| |
| private ChannelGroup copyChannelGroup(ChannelGroup channelGroupSrc, Transaction transaction) { |
| EntityHolder ehSrc = new EntityHolder(channelGroupSrc, entityManagerSrc); |
| |
| EntityHolder ehDst = mapSrcDstEntities.get(ehSrc); |
| |
| if (null == ehDst) { |
| 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")); |
| |
| persist(transaction, channelGroupDst); |
| |
| ehDst = new EntityHolder(channelGroupDst, entityManagerDst); |
| mapSrcDstEntities.put(ehSrc, ehDst); |
| } |
| |
| return (ChannelGroup) ehDst.getEntity(); |
| } |
| |
| } |