blob: f4f504a1a00b994de93901104485472f3b448eba [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2015-2019 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.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.ModelManager;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Condition;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.base.query.Result;
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.Domain;
import org.eclipse.mdm.api.dflt.model.EntityFactory;
import org.eclipse.mdm.api.dflt.model.ProjectDomain;
import org.eclipse.mdm.api.dflt.model.Status;
import com.google.common.collect.Lists;
/**
* 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 Transaction transaction;
private EntityFactory entityFactoryDst;
private EntityManager entityManagerDst;
private ModelManager modelManagerDst;
private QueryService queryService;
private Map<String, ProjectDomain> projectDomainCache = new HashMap<>();
private Map<String, Classification> classificationCache = new HashMap<>();
/**
*
* @param transaction
* @param transferBase
* @param contextDst
* @param entityFactoryDst
* @param entityManagerDst
* @param modelManagerDst
*/
public ClassificationUtil(Transaction transaction, ApplicationContext contextDst) {
super();
this.transaction = transaction;
if (contextDst.getEntityFactory().isPresent()) {
this.entityFactoryDst = contextDst.getEntityFactory().get();
} else {
throw new ApiCopyException("EntityFactory not found!");
}
if (contextDst.getEntityManager().isPresent()) {
this.entityManagerDst = contextDst.getEntityManager().get();
} else {
throw new ApiCopyException("EntityManager not found!");
}
if (contextDst.getModelManager().isPresent()) {
this.modelManagerDst = contextDst.getModelManager().get();
} else {
throw new ApiCopyException("ModelManager not found!");
}
if (contextDst.getQueryService().isPresent()) {
this.queryService = contextDst.getQueryService().get();
} else {
throw new IllegalStateException("QueryService not found!");
}
}
public Classification getClassification(String rootProjectName) {
Domain domain = getDomain();
Status status = getStatus();
ProjectDomain projectDomain = getProjectDomain(rootProjectName);
return getClassification(domain, status, projectDomain);
}
public Classification getClassification(Domain domain, Status status, ProjectDomain projectDomain) {
String cacheKey = Arrays.asList(domain.getName(), status.getName(), projectDomain.getName()).stream()
.collect(Collectors.joining("_"));
Classification classification = classificationCache.get(cacheKey);
if (classification == null) {
EntityType entityType = modelManagerDst.getEntityType(Classification.class);
Condition condClass1 = ComparisonOperator.CASE_INSENSITIVE_EQUAL
.create(entityType.getAttribute("ProjectDomain"), projectDomain.getID());
Condition condClass2 = ComparisonOperator.CASE_INSENSITIVE_EQUAL.create(entityType.getAttribute("Domain"),
domain.getID());
Condition condClass3 = ComparisonOperator.CASE_INSENSITIVE_EQUAL.create(entityType.getAttribute("Status"),
status.getID());
java.util.List<Result> fetch = queryService.createQuery().selectID(entityType)
.fetch(Filter.and().addAll(condClass1, condClass2, condClass3));
List<String> classificationIds = fetch.stream().map(r -> r.getRecord(entityType)).map(Record::getID)
.collect(Collectors.toList());
if (classificationIds.isEmpty()) {
String classificationName = String.format("ProjDomainId_%s.DomainId_%s.StatusId_%s",
projectDomain.getID(), domain.getID(), status.getID());
classification = entityFactoryDst.createClassification(classificationName, status, projectDomain,
domain);
transaction.create(Lists.newArrayList(classification));
} else {
classification = entityManagerDst.load(Classification.class, classificationIds.get(0));
}
classificationCache.put(cacheKey, classification);
}
return classification;
}
public ProjectDomain getProjectDomain(String rootProjectName) {
ProjectDomain projectDomain = projectDomainCache.get(rootProjectName);
if (projectDomain == null) {
EntityType entityTypeProjectDomain = modelManagerDst.getEntityType(ProjectDomain.class);
Condition condProjectDomainName = ComparisonOperator.CASE_INSENSITIVE_EQUAL
.create(entityTypeProjectDomain.getAttribute("Name"), rootProjectName);
List<Result> fetchProjectDomain = queryService.createQuery().selectID(entityTypeProjectDomain)
.fetch(Filter.and().addAll(condProjectDomainName));
List<String> projectDomainIds = fetchProjectDomain.stream().map(r -> r.getRecord(entityTypeProjectDomain))
.map(Record::getID).collect(Collectors.toList());
if (projectDomainIds.size() > 1) {
throw new IllegalStateException(
String.format("More than one ProjectDomain instance with name \"%s\" found in destination!",
rootProjectName));
} else if (projectDomainIds.isEmpty()) {
projectDomain = entityFactoryDst.createProjectDomain(rootProjectName);
transaction.create(Lists.newArrayList(projectDomain));
} else {
projectDomain = entityManagerDst.load(ProjectDomain.class, projectDomainIds.get(0));
}
projectDomainCache.put(rootProjectName, projectDomain);
}
return projectDomain;
}
public Domain getDomain() {
List<Domain> domains = entityManagerDst.loadAll(Domain.class);
if (domains.size() != 1) {
throw new IllegalStateException("No or more than one Domain instance found in destination!");
}
Domain domain = domains.get(0);
return domain;
}
public Status getStatus() {
EntityType entityTypeStatus = modelManagerDst.getEntityType(Status.class);
Condition condStatusName = ComparisonOperator.CASE_INSENSITIVE_EQUAL
.create(entityTypeStatus.getAttribute("Name"), "Imported");
List<Result> fetchStatus = queryService.createQuery().selectID(entityTypeStatus)
.fetch(Filter.and().addAll(condStatusName));
List<String> statusIds = fetchStatus.stream().map(r -> r.getRecord(entityTypeStatus)).map(Record::getID)
.collect(Collectors.toList());
if (statusIds.size() != 1) {
throw new IllegalStateException(
"No or more than one Status instance with name \"Imported\" found in destination!");
}
return entityManagerDst.load(Status.class, statusIds.get(0));
}
public void clearCache() {
projectDomainCache.clear();
classificationCache.clear();
}
}