All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.integratedmodelling.engine.modelling.resolver.BaseResolver Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *  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.IObservableSemantics;
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.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 KIMObservingObject) {
			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) {

			IObservableSemantics 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) /* FIXME should not have traits */|| NS.isTrait(obs)) {
				if (last == null) {
					last = new ArrayList<>();
				}
				last.add(d);
			} else if (NS.isObject(obs) || NS.isRelationship(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, process or relationship");
			}
		}

		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()), scope.getSubject().getContext(),
					(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 " + NS.getDisplayName(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 - 2024 Weber Informatics LLC | Privacy Policy