
org.integratedmodelling.engine.modelling.resolver.BaseResolver Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (C) 2007, 2015:
*
* - Ferdinando Villa
* - integratedmodelling.org
* - any other authors listed in @author annotations
*
* All rights reserved. This file is part of the k.LAB software suite,
* meant to enable modular, collaborative, integrated
* development of interoperable data and model components. For
* details, see http://integratedmodelling.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Affero General Public License
* Version 3 or any later version.
*
* This program is distributed in the hope that it will be useful,
* but without any warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose. See the
* Affero General Public License for more details.
*
* You should have received a copy of the Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* The license is also available at: https://www.gnu.org/licenses/agpl.html
*******************************************************************************/
package org.integratedmodelling.engine.modelling.resolver;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.integratedmodelling.api.knowledge.IConcept;
import org.integratedmodelling.api.knowledge.ISemantic;
import org.integratedmodelling.api.modelling.IActiveDirectObservation;
import org.integratedmodelling.api.modelling.IDataSource;
import org.integratedmodelling.api.modelling.IDependency;
import org.integratedmodelling.api.modelling.IModel;
import org.integratedmodelling.api.modelling.IObservable;
import org.integratedmodelling.api.modelling.IObservingObject;
import org.integratedmodelling.api.modelling.ISubject;
import org.integratedmodelling.api.modelling.resolution.IResolutionScope;
import org.integratedmodelling.api.modelling.resolution.ISubjectResolver;
import org.integratedmodelling.api.monitoring.IMonitor;
import org.integratedmodelling.api.monitoring.Messages;
import org.integratedmodelling.common.configuration.KLAB;
import org.integratedmodelling.common.kim.KIMObservingObject;
import org.integratedmodelling.common.vocabulary.NS;
import org.integratedmodelling.common.vocabulary.ObservationMetadata;
import org.integratedmodelling.engine.modelling.kbox.ObservationKbox;
import org.integratedmodelling.engine.modelling.runtime.DirectObservation;
import org.integratedmodelling.engine.modelling.runtime.Subject;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabInternalErrorException;
/**
* Provides all basic resolver functionalities except the actual resolve()
* methods. Separated only to keep Resolver clean and readable and still have
* the full resolver logics in it (without separating in artificial subclasses
* as it was earlier).
*
* @author ferdinando.villa
*
*/
public abstract class BaseResolver implements ISubjectResolver {
Map dsCache = new HashMap<>();
/**
* Group together the dependencies of the passed object (model or observer)
* into groups to be resolved in sequence. This will collect all consecutive
* data dependencies in one group and leave process and agent dependencies
* by themselves.
*
* TODO inject dependencies from semantics and resolve abstract dependencies
* to concrete ones using models.
*
* @throws KlabException
*/
public List> groupDependencies(ISemantic observer, IResolutionScope context)
throws KlabException {
List> ret = new ArrayList>();
List deps = null;
if (observer instanceof IObservingObject) {
deps = new ArrayList(((KIMObservingObject) observer)
.getAllDependencies(((ResolutionScope) context).getMonitor(), context));
}
if (deps == null) {
return new ArrayList<>();
}
// Set existing = new HashSet<>();
// for (IDependency d : deps) {
// existing.add(d.getObservable().getType());
// }
// /**
// * give the contextualizer a chance.
// */
// if (((ResolutionContext) context).actuator instanceof
// IContextualActuator) {
// deps = ((IContextualActuator) (((ResolutionContext)
// context).actuator))
// .contextualizeDependencies(deps);
// }
if (deps.size() == 0) {
return ret;
}
ArrayList last = null;
for (IDependency d : deps) {
IObservable obs = d.getObservable();
if (NS.isProcess(obs)) {
if (last != null) {
ret.add(last);
}
ret.add(Collections.singletonList(d));
last = null;
} else if (NS.isQuality(obs) || NS.isTrait(obs)) {
if (last == null) {
last = new ArrayList();
}
last.add(d);
} else if (NS.isObject(obs)) {
if (last != null) {
ret.add(last);
}
ret.add(Collections.singletonList(d));
last = null;
} else {
/*
* shouldn't happen unless the ontologies are fubar
*/
throw new KlabInternalErrorException(
obs + " cannot be recognized as a quality, trait, subject or process");
}
}
if (last != null) {
ret.add(last);
}
return ret;
}
/**
* Create a model by merging all the passed ones into a conditional model
* that uses the call order for selection. If any model is a merged model,
* unwrap it and merge the result again in a flat list. TODO implement
*
* @param models
* @return merged model
* @throws KlabException
*/
public static IModel mergeModels(IModel... models) throws KlabException {
ArrayList mods = new ArrayList();
for (IModel m : models) {
// if (((Model) m).isMerged()) {
//
// }
}
// IModel model = new
// Model(SemanticObject.newInstance(concept.getType()),
// CamelCase.toLowerCase(
// concept.getLocalName(), '-'),
// subjectObserver.getSubject().getNamespace(), models);
// ProvenanceNode obs = ctx.modelGraph.add(model.getObserver());
//
// int cidx = 0;
// for (ProvenanceNode node : conditions) {
// DependencyEdge de = new
// DependencyEdge(DependencyEdge.CONDITIONAL_DEPENDENCY, "", concept);
// de.conditionIndex = cidx++;
// ctx.modelGraph.addEdge(node, obs, de);
// }
//
// ProvenanceNode ret = ctx.modelGraph.add(model);
// ret.coverage = coverage;
//
// ctx.modelGraph.addEdge(
// obs,
// ret,
// new DependencyEdge(DependencyEdge.DEFINE_STATE, "",
// subjectObserver.getObservable(model
// .getObserver())));
return null;
}
/**
* TODO this should produce an instantiator so the objects are "produced" later using the regular
* dataflow mechanism. It should NOT initialize the subjects.
*
* @param subjectType
* @param scope
* @return
* @throws KlabException
*/
protected List lookupSubjects(IConcept subjectType, IResolutionScope scope) throws KlabException {
List ret = new ArrayList<>();
int objs = 0;
for (ObservationMetadata sg : ObservationKbox.get().query(Collections.singleton(subjectType), scope.getScale(),
scope.getScenarios(), false)) {
ISubject subj = (ISubject) KLAB.MFACTORY.createSubject(
sg.getSubjectObserver(((ResolutionScope) scope).getMonitor()),
(IActiveDirectObservation) scope.getSubject(), ((ResolutionScope) scope).monitor);
if (subj != null) {
ret.add(subj);
}
// ((DirectObservation) subj).setContextSubject(scope.getSubject());
// ((Subject)scope.getSubject()).addSubject(subj, KLAB.p(NS.PART_OF));
//
// if (((Subject) subj).initialize(scope, /* FIXME! */ null, ((ResolutionScope) scope).monitor).isEmpty()) {
// ((ResolutionScope) scope).monitor.warn("cannot resolve dependent subject " + subj.getName());
// }
objs++;
}
if (objs > 0) {
((ResolutionScope) scope).monitor
.info(objs + " objects of type " + subjectType + " retrieved from network search", Messages.INFOCLASS_DOWNLOAD);
}
return ret;
}
/**
* Get the datasource for a model, if any, ensuring only one is created and
* if the model does not have it we don't keep trying.
*
* @param model
* @param monitor
* @return
* @throws KlabException
*/
protected IDataSource getDatasource(IModel model, IMonitor monitor) throws KlabException {
if (dsCache.containsKey(model)) {
// may be null
return dsCache.get(model);
}
IDataSource ret = model.getDatasource(monitor);
dsCache.put(model, ret);
return ret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy