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

org.molgenis.model.MolgenisModel Maven / Gradle / Ivy

package org.molgenis.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

import org.molgenis.MolgenisOptions;
import org.molgenis.fieldtypes.MrefField;
import org.molgenis.fieldtypes.XrefField;
import org.molgenis.model.elements.Entity;
import org.molgenis.model.elements.Field;
import org.molgenis.model.elements.Model;
import org.molgenis.model.elements.Module;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MolgenisModel
{
	private static final Logger LOG = LoggerFactory.getLogger(MolgenisModel.class);

	public static Model parse(MolgenisOptions options) throws Exception
	{
		Model model = null;

		try
		{
			LOG.info("parsing db-schema from " + options.model_database);

			model = MolgenisModelParser.parseDbSchema(options.model_database);

			// determine imported entities (entities that already exist)
			Model importedModel = MolgenisModelParser.parseDbSchema(options.import_model_database);
			MolgenisModelValidator.validate(importedModel, options);
			for (Entity importedEntity : importedModel.getEntities())
			{
				importedEntity.setImported(true);
				importedEntity.setModel(model);
			}

			// dark magic that does way more then setting a name, location is
			// important here
			importedModel.getDatabase().setName("imported");

			// remove imported entities from model
			for (Module importedModule : importedModel.getModules())
			{
				model.getModules().add(importedModule);

				for (Entity importedEntity : importedModule.getEntities())
				{
					// Prevent duplicate elements (elements of parent are also
					// in the tree)
					model.getDatabase().getTreeElements().remove(importedEntity.getName());
					importedEntity.setParent(model.getDatabase());
				}
			}

			// Get the strings of the property 'authorizable' and add the entity
			// name
			// 'Authorizable' to the list of Implements. Solves datamodel
			// duplication
			// in molgenis_apps suite. Possible future work: put auth
			// dependencies into
			// molgenis itself so it becomes generic across projects.
			for (String eName : options.authorizable)
			{
				eName = eName.trim(); // allow e.g. 'Observation, Investigation'
				Vector implNames = model.getEntity(eName).getImplementsNames();
				if (!implNames.contains("Authorizable"))
				{
					implNames.add("Authorizable");
					model.getEntity(eName).setImplements(implNames);
				}
			}

			LOG.info("read model");
			if (LOG.isTraceEnabled()) LOG.trace(model.toString());

			LOG.debug("validating model ...");
			MolgenisModelValidator.validate(model, options);
			LOG.info("validated model");

			if (LOG.isTraceEnabled()) LOG.trace(model.toString());
		}
		catch (MolgenisModelException e)
		{
			LOG.error("Parsing failed: " + e.getMessage());
			e.printStackTrace();
			throw e;
		}
		return model;
	}

	public static Model parse(Properties p) throws Exception
	{
		MolgenisOptions options = new MolgenisOptions(p);
		return parse(options);
	}

	public static List sortEntitiesByDependency(List entityList, final Model model)
			throws MolgenisModelException
	{
		List result = new ArrayList();

		boolean found = true;
		List toBeMoved = new ArrayList();
		while (entityList.size() > 0 && found)
		{
			found = false;
			for (Entity entity : entityList)
			{
				List deps = getDependencies(entity, model);

				// check if all deps are there
				boolean missing = false;
				for (String dep : deps)
				{
					if (indexOf(result, dep) < 0)
					{
						missing = true;
						break;
					}
				}

				if (!missing)
				{
					toBeMoved.add(entity);
					result.add(entity);
					found = true;
					break;
				}
			}

			for (Entity e : toBeMoved)
				entityList.remove(e);
			toBeMoved.clear();
		}

		// list not empty, cyclic?
		for (Entity e : entityList)
		{
			LOG.error("cyclic relations to '" + e.getName() + "' depends on " + getDependencies(e, model));
			result.add(e);
		}

		// result
		for (Entity e : result)
		{
			LOG.info(e.getName());
		}

		return result;
	}

	private static int indexOf(List entityList, String entityName)
	{
		for (int i = 0; i < entityList.size(); i++)
		{
			if (entityList.get(i).getName().equals(entityName)) return i;
		}
		return -1;
	}

	private static List getDependencies(Entity currentEntity, Model model) throws MolgenisModelException
	{
		Set dependencies = new HashSet();

		for (Field field : currentEntity.getAllFields())
		{
			if (field.getType() instanceof XrefField)
			{
				dependencies.add(model.getEntity(field.getXrefEntityName()).getName());

				Entity xrefEntity = field.getXrefEntity();

				// also all subclasses have this xref!!!!
				for (Entity e : xrefEntity.getAllDescendants())
				{
					if (!dependencies.contains(e.getName())) dependencies.add(e.getName());
				}
			}
			if (field.getType() instanceof MrefField)
			{
				dependencies.add(field.getXrefEntity().getName()); // mref
				// fields
				// including super classes
				for (String name : model.getEntity(field.getXrefEntity().getName()).getParents())
				{
					dependencies.add(name);
				}
			}
		}

		dependencies.remove(currentEntity.getName());
		return new ArrayList(dependencies);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy