| /******************************************************************************** |
| * 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.List; |
| |
| import org.asam.ods.AIDName; |
| import org.asam.ods.AIDNameValueSeqUnitId; |
| import org.asam.ods.AoException; |
| import org.asam.ods.AoSession; |
| import org.asam.ods.ApplicationElement; |
| import org.asam.ods.ApplicationStructure; |
| import org.asam.ods.DataType; |
| import org.asam.ods.ElemId; |
| import org.asam.ods.InstanceElementIterator; |
| import org.asam.ods.TS_Union; |
| import org.asam.ods.TS_UnionSeq; |
| import org.asam.ods.TS_Value; |
| import org.asam.ods.TS_ValueSeq; |
| import org.asam.ods.T_LONGLONG; |
| import org.eclipse.mdm.api.base.ServiceNotProvidedException; |
| import org.eclipse.mdm.api.base.model.Entity; |
| import org.eclipse.mdm.api.base.model.Test; |
| import org.eclipse.mdm.api.base.model.TestStep; |
| import org.eclipse.mdm.api.dflt.ApplicationContext; |
| import org.eclipse.mdm.api.dflt.EntityManager; |
| import org.eclipse.mdm.api.dflt.model.Pool; |
| import org.eclipse.mdm.api.dflt.model.Project; |
| import org.eclipse.mdm.api.odsadapter.ODSContext; |
| import org.eclipse.mdm.api.odsadapter.utils.ODSConverter; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Creates Classification instances, because openMDM4 clients checks them and |
| * does not show any data if classifications are absent. As soon as |
| * Classification can be created through standard MDM5 API this class becomes |
| * obsolete. |
| */ |
| public class ClassificationUtil { |
| private static final Logger LOG = LoggerFactory.getLogger(ClassificationUtil.class); |
| |
| private ApplicationContext contextDst; |
| private EntityManager entityManagerDst; |
| |
| public ClassificationUtil(ApplicationContext contextDst) { |
| this.contextDst = contextDst; |
| |
| entityManagerDst = contextDst.getEntityManager() |
| .orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class)); |
| } |
| |
| public void attachClassification(List<Entity> listEntities) { |
| if (!(contextDst instanceof ODSContext)) { |
| LOG.debug("Cannot attach classification as destination is not an ODS storage!"); |
| |
| return; |
| } |
| |
| AoSession aoSession = ((ODSContext) contextDst).getAoSession(); |
| |
| try { |
| aoSession.startTransaction(); |
| } catch (AoException exc) { |
| LOG.error(exc.getMessage(), exc); |
| |
| return; |
| } |
| |
| try { |
| ApplicationStructure applicationStructure = aoSession.getApplicationStructure(); |
| ApplicationElement aeDomain = applicationStructure.getElementByName("Domain"); |
| ApplicationElement aeProjectDomain = applicationStructure.getElementByName("ProjectDomain"); |
| ApplicationElement aeStatus = applicationStructure.getElementByName("Status"); |
| ApplicationElement aeClassification = applicationStructure.getElementByName("Classification"); |
| |
| if (null == aeDomain) { |
| throw new IllegalStateException("Cannot find application element Domain in destination!"); |
| } |
| |
| if (null == aeProjectDomain) { |
| throw new IllegalStateException("Cannot find application element ProjectDomain in destination!"); |
| } |
| |
| if (null == aeStatus) { |
| throw new IllegalStateException("Cannot find application element Status in destination!"); |
| } |
| |
| if (null == aeClassification) { |
| throw new IllegalStateException("Cannot find application element Classification in destination!"); |
| } |
| |
| InstanceElementIterator iter = aeDomain.getInstances("*"); |
| |
| if (iter.getCount() != 1) { |
| throw new IllegalStateException("No or more than one Domain instance found in destination!"); |
| } |
| |
| T_LONGLONG iidDomain = iter.nextN(1)[0].getId(); |
| |
| iter = aeStatus.getInstances("Imported"); |
| |
| if (iter.getCount() != 1) { |
| throw new IllegalStateException( |
| "No or more than one Status instance with name \"Imported\" found in destination!"); |
| } |
| |
| T_LONGLONG iidStatus = iter.nextN(1)[0].getId(); |
| |
| for (Entity entity : listEntities) { |
| Project rootProject = null; |
| |
| if (entity instanceof Test) { |
| rootProject = entityManagerDst |
| .loadParent(entityManagerDst.loadParent(entity, Pool.class).get(), Project.class).get(); |
| } else if (entity instanceof TestStep) { |
| rootProject = entityManagerDst.loadParent(entityManagerDst |
| .loadParent(entityManagerDst.loadParent(entity, Test.class).get(), Pool.class).get(), |
| Project.class).get(); |
| } else { |
| continue; |
| } |
| |
| String rootProjectName = rootProject.getName(); |
| |
| T_LONGLONG iidProjectDomain = null; |
| |
| iter = aeProjectDomain.getInstances(rootProject.getName()); |
| |
| switch (iter.getCount()) { |
| case 0: { |
| T_LONGLONG aidProjectDomain = aeProjectDomain.getId(); |
| List<AIDNameValueSeqUnitId> listProjectDomainAnvsuis = new ArrayList<>(); |
| listProjectDomainAnvsuis.add(createAnvsui(aidProjectDomain, "Name", rootProjectName)); |
| listProjectDomainAnvsuis |
| .add(createAnvsui(aidProjectDomain, "MimeType", "application/x-asam.aoany.projectdomain")); |
| |
| ElemId[] elemIds = aoSession.getApplElemAccess().insertInstances(listProjectDomainAnvsuis |
| .toArray(new AIDNameValueSeqUnitId[listProjectDomainAnvsuis.size()])); |
| |
| if (elemIds.length == 1) { |
| iidProjectDomain = elemIds[0].iid; |
| } else { |
| throw new IllegalStateException(String.format( |
| "Could not create ProjectDomain instance with name \"%s\" in destination!", |
| rootProjectName)); |
| } |
| } |
| break; |
| case 1: { |
| iidProjectDomain = iter.nextN(1)[0].getId(); |
| } |
| break; |
| default: |
| throw new IllegalStateException( |
| String.format("More than one ProjectDomain instance with name \"%s\" found in destination!", |
| rootProjectName)); |
| } |
| |
| T_LONGLONG iidClassification = null; |
| |
| String classificationName = String.format("ProjDomainId_%d.DomainId_%d.StatusId_%d", |
| ODSConverter.fromODSLong(iidProjectDomain), ODSConverter.fromODSLong(iidDomain), |
| ODSConverter.fromODSLong(iidStatus)); |
| |
| iter = aeClassification.getInstances(classificationName); |
| |
| if (iter.getCount() > 0) { |
| iidClassification = iter.nextN(1)[0].getId(); |
| } |
| |
| if (null == iidClassification) { |
| T_LONGLONG aidClassification = aeClassification.getId(); |
| AIDNameValueSeqUnitId[] arrAnvsuis = new AIDNameValueSeqUnitId[5]; |
| arrAnvsuis[0] = createAnvsui(aidClassification, "Name", classificationName); |
| arrAnvsuis[1] = createAnvsui(aidClassification, "MimeType", |
| "application/x-asam.aoany.classification"); |
| arrAnvsuis[2] = createAnvsui(aidClassification, "Domain", iidDomain); |
| arrAnvsuis[3] = createAnvsui(aidClassification, "Status", iidStatus); |
| arrAnvsuis[4] = createAnvsui(aidClassification, "ProjectDomain", iidProjectDomain); |
| |
| ElemId[] elemIds = aoSession.getApplElemAccess().insertInstances(arrAnvsuis); |
| |
| if (elemIds.length == 1) { |
| iidClassification = elemIds[0].iid; |
| } else { |
| throw new IllegalStateException(String.format( |
| "Could not create Classification instance with name \"%s\" in destination!", |
| classificationName)); |
| } |
| } |
| |
| if (null != iidClassification) { |
| ApplicationElement aeEntity = applicationStructure.getElementByName(entity.getTypeName()); |
| |
| if (null == aeEntity) { |
| throw new IllegalStateException(String.format( |
| "Could not find application element \"%s\" in destination!", entity.getTypeName())); |
| } |
| |
| T_LONGLONG aidEntity = aeEntity.getId(); |
| AIDNameValueSeqUnitId[] arrEntityAnvsuis = new AIDNameValueSeqUnitId[2]; |
| arrEntityAnvsuis[0] = createAnvsui(aidEntity, "Id", |
| ODSConverter.toODSLong(Long.valueOf(entity.getID()))); |
| arrEntityAnvsuis[1] = createAnvsui(aidEntity, "Classification", iidClassification); |
| |
| aoSession.getApplElemAccess().updateInstances(arrEntityAnvsuis); |
| } else { |
| throw new IllegalStateException( |
| String.format("No Classification instance with name \"%s\" available in destination!", |
| classificationName)); |
| } |
| } |
| |
| aoSession.commitTransaction(); |
| } catch (AoException exc) { |
| try { |
| LOG.error(exc.getMessage(), exc); |
| |
| aoSession.abortTransaction(); |
| } catch (AoException exc2) { |
| LOG.error(exc2.getMessage(), exc2); |
| } |
| } |
| } |
| |
| private AIDNameValueSeqUnitId createAnvsui(T_LONGLONG aid, String attrName, String value) throws AoException { |
| AIDNameValueSeqUnitId anvsui = new AIDNameValueSeqUnitId(); |
| anvsui.attr = new AIDName(aid, attrName); |
| anvsui.unitId = new T_LONGLONG(0, 0); |
| anvsui.values = tsValue2tsValueSeq(getTSValue(value)); |
| |
| return anvsui; |
| } |
| |
| private AIDNameValueSeqUnitId createAnvsui(T_LONGLONG aid, String attrName, T_LONGLONG value) throws AoException { |
| AIDNameValueSeqUnitId anvsui = new AIDNameValueSeqUnitId(); |
| anvsui.attr = new AIDName(aid, attrName); |
| anvsui.unitId = new T_LONGLONG(0, 0); |
| anvsui.values = tsValue2tsValueSeq(getTSValue(value)); |
| |
| return anvsui; |
| } |
| |
| public static TS_ValueSeq tsValue2tsValueSeq(TS_Value value) throws AoException { |
| TS_ValueSeq vSeq = new TS_ValueSeq(); |
| vSeq.flag = new short[] { value.flag }; |
| vSeq.u = new TS_UnionSeq(); |
| DataType dt = value.u.discriminator(); |
| if (dt == DataType.DT_STRING) { |
| vSeq.u.stringVal(new String[] { value.u.stringVal() }); |
| } else if (dt == DataType.DT_LONGLONG) { |
| vSeq.u.longlongVal(new T_LONGLONG[] { value.u.longlongVal() }); |
| } |
| return vSeq; |
| } |
| |
| private TS_Value getTSValue(T_LONGLONG value) { |
| TS_Value v = new TS_Value(); |
| v.flag = 15; |
| v.u = new TS_Union(); |
| v.u.longlongVal(value); |
| return v; |
| } |
| |
| private TS_Value getTSValue(String value) { |
| TS_Value v = new TS_Value(); |
| v.u = new TS_Union(); |
| if (value == null || value.length() < 1) { |
| v.flag = 0; |
| v.u.stringVal(""); |
| } else { |
| v.flag = 15; |
| v.u.stringVal(value); |
| } |
| return v; |
| } |
| } |