From a4fe92c12fc19018f7d2899f250d7ab42ceea665 Mon Sep 17 00:00:00 2001
From: David Hoksza <david.hoksza@uni.lu>
Date: Wed, 17 Jan 2018 16:18:29 +0100
Subject: [PATCH] Added associated annotator class to miriam data including
 hibernate mapping + createMiriamData in element annotator. without unit tests

---
 .../services/annotators/ElementAnnotator.java |   30 +
 .../services/annotators/TairAnnotator.java    |    4 +-
 .../annotators/ElementAnnotatorTest.java      |   33 +
 .../lcsb/mapviewer/model/map/MiriamData.java  |   61 +-
 .../lcsb/mapviewer/model/map/MiriamType.java  | 1288 ++++++++---------
 persist/src/db/12.0.0/fix_db_20180117.sql     |    2 +
 6 files changed, 764 insertions(+), 654 deletions(-)
 create mode 100644 persist/src/db/12.0.0/fix_db_20180117.sql

diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotator.java
index 84761857a5..e71c85ce6a 100644
--- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotator.java
+++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotator.java
@@ -12,6 +12,7 @@ import lcsb.mapviewer.common.exception.InvalidArgumentException;
 import lcsb.mapviewer.converter.model.celldesigner.structure.CellDesignerChemical;
 import lcsb.mapviewer.model.map.BioEntity;
 import lcsb.mapviewer.model.map.MiriamData;
+import lcsb.mapviewer.model.map.MiriamRelationType;
 import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.species.Chemical;
@@ -473,5 +474,34 @@ public abstract class ElementAnnotator extends CachableInterface {
 			logger.warn(prefix + "MCS in db different: \"" + element.getMechanicalConfidenceScore() + "\", \"" + value + "\"");
 		}
 	}
+	
+	private void setAnnotator(MiriamData md){
+		md.setAnnotator(this.getClass());		
+	}
+	
+	protected MiriamData createMiriamData(){
+		MiriamData md = new MiriamData();
+		setAnnotator(md);
+		return md;		
+	}
+	
+	protected MiriamData createMiriamData(MiriamData _md){
+		MiriamData md = new MiriamData(_md);
+		setAnnotator(md);
+		return md;		
+	}
+	
+	protected MiriamData createMiriamData(MiriamType mt, String resource){
+		MiriamData md = new MiriamData(mt, resource);
+		setAnnotator(md);
+		return md;		
+	}
+	
+	protected MiriamData createMiriamData(MiriamRelationType relationType, MiriamType mt, String resource){
+		MiriamData md = new MiriamData(relationType, mt, resource);
+		setAnnotator(md);
+		return md;		
+	}	
+	
 
 }
diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java
index 0388293b12..9dcac43bcd 100644
--- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java
+++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java
@@ -58,7 +58,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService
 		this.setCache(null);
 
 		try {
-			MiriamData md = tairToUniprot(new MiriamData(MiriamType.TAIR_LOCUS, "AT1G01030"));
+			MiriamData md = tairToUniprot(createMiriamData(MiriamType.TAIR_LOCUS, "AT1G01030"));
 
 			status.setStatus(ExternalServiceStatusType.OK);
 			if (md == null || !md.getResource().equalsIgnoreCase("Q9MAN1")) {
@@ -122,7 +122,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService
 		Collection<MiriamData> result = new HashSet<MiriamData>();
 		Matcher m = tairToUniprot.matcher(pageContent);
 		if (m.find()) {
-			result.add(new MiriamData(MiriamType.UNIPROT, m.group(1)));
+			result.add(createMiriamData(MiriamType.UNIPROT, m.group(1)));
 		}		
 		return result;
 	}
diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotatorTest.java
index 1dac8112d6..f4c613ca90 100644
--- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotatorTest.java
+++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/ElementAnnotatorTest.java
@@ -2,6 +2,7 @@ package lcsb.mapviewer.annotation.services.annotators;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
 
 import org.junit.After;
 import org.junit.AfterClass;
@@ -12,6 +13,9 @@ import lcsb.mapviewer.annotation.AnnotationTestFunctions;
 import lcsb.mapviewer.annotation.cache.CachableInterface;
 import lcsb.mapviewer.annotation.cache.SourceNotAvailable;
 import lcsb.mapviewer.model.map.BioEntity;
+import lcsb.mapviewer.model.map.MiriamData;
+import lcsb.mapviewer.model.map.MiriamRelationType;
+import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.species.GenericProtein;
 import lcsb.mapviewer.model.map.species.Ion;
@@ -193,5 +197,34 @@ public class ElementAnnotatorTest extends AnnotationTestFunctions {
 
 		assertEquals(1, getWarnings().size());
 	}
+	
+	@Test
+	public void createMiriamData1() {
+		MiriamData md = annotator.createMiriamData();
+		assertEquals(md.getAnnotator(), annotator.getClass()); 
+	}
+	
+	@Test
+	public void createMiriamData2() {
+		MiriamData md = annotator.createMiriamData(MiriamType.UNIPROT, "XXX");
+		assertEquals(md.getAnnotator(), annotator.getClass()); 
+	}
+	
+	@Test
+	public void createMiriamData3() {
+		MiriamData md = annotator.createMiriamData(MiriamRelationType.BQ_BIOL_ENCODES, MiriamType.UNIPROT, "XXX");
+		assertEquals(md.getAnnotator(), annotator.getClass()); 
+	}
+	
+	@Test
+	public void createMiriamData4() {
+		MiriamData md1 = new MiriamData(MiriamType.UNIPROT, "XXX");
+		assertNull(md1.getAnnotator());
+		
+		MiriamData md2 = annotator.createMiriamData(md1);
+		assertEquals(md2.getAnnotator(), annotator.getClass());
+	}
+	
+	
 
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/MiriamData.java b/model/src/main/java/lcsb/mapviewer/model/map/MiriamData.java
index 5e5dffd5a5..491d0f840a 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/MiriamData.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/MiriamData.java
@@ -64,6 +64,13 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
 	 */
 	@Column(name = "resource")
 	private String						 resource					= "";
+	
+	/**
+	 * The annotator which created the miriam data or which 
+	 * should be associated with it.
+	 */
+	@Column(name = "annotator")
+	private Class<?> 					annotator 					= null;
 
 	/**
 	 * Default constructor.
@@ -82,8 +89,9 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
 		setRelationType(md.relationType);
 		setDataType(md.dataType);
 		setResource(md.resource);
+		setAnnotator(md.annotator);
 	}
-
+	
 	/**
 	 * Constructor that initialize the data by information from params.
 	 * 
@@ -93,8 +101,11 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
 	 *          type of the miriam data (see: {@link MiriamType})
 	 * @param resource
 	 *          {@link #resource}
+	 * @param annotator
+	 *          {@link #annotator}
+	 *          
 	 */
-	public MiriamData(MiriamRelationType relationType, MiriamType mt, String resource) {
+	public MiriamData(MiriamRelationType relationType, MiriamType mt, String resource, Class<?> annotator) {
 		if (mt == null) {
 			throw new InvalidArgumentException("MiriamType cannot be null");
 		}
@@ -104,8 +115,36 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
 		setRelationType(relationType);
 		setDataType(mt);
 		setResource(resource);
+		setAnnotator(annotator);
+	}
+
+	/**
+	 * Constructor that initialize the data by information from params.
+	 * 
+	 * @param relationType
+	 *          {@link #relationType}
+	 * @param mt
+	 *          type of the miriam data (see: {@link MiriamType})
+	 * @param resource
+	 *          {@link #resource}
+	 */
+	public MiriamData(MiriamRelationType relationType, MiriamType mt, String resource) {
+		this(relationType, mt, resource, null);
+	}
+	
+	/**
+	 * Constructor that initialize the data by information from params.
+	 * 
+	 * @param mt
+	 *          type of the miriam data (see: {@link MiriamType})
+	 * @param resource
+	 *          {@link #resource}
+	 */
+	public MiriamData(MiriamType mt, String resource, Class<?> annotator) {
+		this(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, mt, resource, annotator);
 	}
 
+	
 	/**
 	 * Constructor that initialize the data by information from params.
 	 * 
@@ -115,7 +154,7 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
 	 *          {@link #resource}
 	 */
 	public MiriamData(MiriamType mt, String resource) {
-		this(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, mt, resource);
+		this(mt, resource, null);
 	}
 
 	/**
@@ -250,4 +289,20 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
 
 		}
 	}
+	
+	/**
+	 * 	
+	 * @return {@link #annotator}
+	 */
+	public Class<?> getAnnotator() {
+		return annotator;
+	}
+
+	/**
+	 * 
+	 * @param {@link #annotator}
+	 */
+	public void setAnnotator(Class<?> annotator) {
+		this.annotator = annotator;
+	}
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java b/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java
index f633cde675..338903c600 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java
@@ -39,7 +39,6 @@ public enum MiriamType {
 			new Class<?>[] {}, "MIR:00000237"), //
 	
 	/**
-
 	 * The Carbohydrate-Active Enzyme (CAZy) database: http://www.cazy.org/.
 	 */
 	CAZY("CAZy", //
@@ -47,326 +46,318 @@ public enum MiriamType {
 			new String[] { "urn:miriam:cazy" }, //
 			new Class<?>[] {}, "MIR:00000195"), //
 
-  /**
-   * Consensus CDS: http://identifiers.org/ccds/.
-   */
-  CCDS("Consensus CDS", //
-      "http://www.ncbi.nlm.nih.gov/CCDS/", //
-      new String[] { "urn:miriam:ccds" }, //
-      new Class<?>[] {}, "MIR:00000375"), //
-
-  /**
-   * Chebi database:
-   * <a href = "http://www.ebi.ac.uk/chebi/">http://www.ebi.ac.uk/chebi/</a>.
-   */
-  CHEBI("Chebi", //
-      "http://www.ebi.ac.uk/chebi/", //
-      new String[] { "urn:miriam:obo.chebi", "urn:miriam:chebi" }, //
-      new Class<?>[] { Chemical.class, Drug.class, }, "MIR:00000002", //
-      new Class<?>[] { Chemical.class }), //
-
-  /**
-   * ChemSpider database:
-   * <a href = "http://www.chemspider.com/">http://www.chemspider.com/</a>.
-   */
-  CHEMSPIDER("ChemSpider", //
-      "http://www.chemspider.com//", //
-      new String[] { "urn:miriam:chemspider" }, //
-      new Class<?>[] {}, "MIR:00000138"), //
-
-  /**
-   * Chembl database: https://www.ebi.ac.uk/chembldb/.
-   */
-  CHEMBL_COMPOUND("ChEMBL", //
-      "https://www.ebi.ac.uk/chembldb/", //
-      new String[] { "urn:miriam:chembl.compound" }, //
-      new Class<?>[] { Drug.class }, "MIR:00000084"), //
-
-  /**
-   * Target in chembl database: https://www.ebi.ac.uk/chembldb/.
-   */
-  CHEMBL_TARGET("ChEMBL target", //
-      "https://www.ebi.ac.uk/chembldb/", //
-      new String[] { "urn:miriam:chembl.target" }, //
-      new Class<?>[] { Protein.class, Complex.class }, "MIR:00000085"), //
-
-  /**
-   * Clusters of Orthologous Groups: https://www.ncbi.nlm.nih.gov/COG/.
-   */
-  COG("Clusters of Orthologous Groups", //
-      "https://www.ncbi.nlm.nih.gov/COG/", //
-      new String[] { "urn:miriam:cogs" }, //
-      new Class<?>[] { Reaction.class }, "MIR:00000296"), //
-
-  /**
-   * Digital Object Identifier: http://www.doi.org/.
-   */
-  DOI("Digital Object Identifier", //
-      "http://www.doi.org/", //
-      new String[] { "urn:miriam:doi" }, //
-      new Class<?>[] { Reaction.class }, "MIR:00000019"), //
-
-  /**
-   * Drugbank database: http://www.drugbank.ca/.
-   */
-  DRUGBANK("DrugBank", //
-      "http://www.drugbank.ca/", //
-      new String[] { "urn:miriam:drugbank" }, //
-      new Class<?>[] { Drug.class }, "MIR:00000102"), //
-  /**
-   * Drugbank targets: http://www.drugbank.ca/targets.
-   */
-  DRUGBANK_TARGET_V4("DrugBank Target v4", //
-      "http://www.drugbank.ca/targets", //
-      new String[] { "urn:miriam:drugbankv4.target" }, //
-      new Class<?>[] {}, "MIR:00000528"), //
-
-  /**
-   * Enzyme Nomenclature: http://www.enzyme-database.org/.
-   */
-  EC("Enzyme Nomenclature", //
-      "http://www.enzyme-database.org/", //
-      new String[] { "urn:miriam:ec-code" }, //
-      new Class<?>[] { Protein.class, Complex.class }, "MIR:00000004"), //
-
-  /**
-   * Ensembl: www.ensembl.org.
-   */
-  ENSEMBL("Ensembl", //
-      "www.ensembl.org", //
-      new String[] { "urn:miriam:ensembl" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000003"), //
-
-  /**
-   * Ensembl Plants: http://plants.ensembl.org/.
-   */
-  ENSEMBL_PLANTS("Ensembl Plants", //
-      "http://plants.ensembl.org/", //
-      new String[] { "urn:miriam:ensembl.plant" }, //
-      new Class<?>[] {}, "MIR:00000205"), //
-
-  /**
-   * Entrez Gene: http://www.ncbi.nlm.nih.gov/gene.
-   */
-  ENTREZ("Entrez Gene", //
-      "http://www.ncbi.nlm.nih.gov/gene", //
-      new String[] { "urn:miriam:ncbigene", "urn:miriam:entrez.gene" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000069"), //
-
-  /**
-   * Gene Ontology: http://amigo.geneontology.org/amigo.
-   */
-  GO("Gene Ontology", //
-      "http://amigo.geneontology.org/amigo", //
-      new String[] { "urn:miriam:obo.go", "urn:miriam:go" }, //
-      new Class<?>[] { Phenotype.class, Compartment.class, Complex.class }, "MIR:00000022"), //
-
-  /**
-   * HGNC: http://www.genenames.org.
-   */
-  HGNC("HGNC", //
-      "http://www.genenames.org", //
-      new String[] { "urn:miriam:hgnc" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000080", //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }), //
-
-  /**
-   * HGNC symbol: http://www.genenames.org.
-   */
-  HGNC_SYMBOL("HGNC Symbol", //
-      "http://www.genenames.org", //
-      new String[] { "urn:miriam:hgnc.symbol" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000362", //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }), //
-
-  /**
-   * HMDB: http://www.hmdb.ca/.
-   */
-  HMDB("HMDB", //
-      "http://www.hmdb.ca/", //
-      "urn:miriam:hmdb", //
-      new Class<?>[] { Chemical.class, Drug.class, }, "MIR:00000051"), //
-
-  /**
-   * InterPro: http://www.ebi.ac.uk/interpro/.
-   */
-  INTERPRO("InterPro", //
-      "http://www.ebi.ac.uk/interpro/", //
-      new String[] { "urn:miriam:interpro" }, //
-      new Class<?>[] { Protein.class, Complex.class }, "MIR:00000011"), //
-
-  /**
-   * KEGG Compound: http://www.genome.jp/kegg/ligand.html.
-   */
-  KEGG_COMPOUND("Kegg Compound", //
-      "http://www.genome.jp/kegg/ligand.html", //
-      "urn:miriam:kegg.compound", //
-      new Class<?>[] { Chemical.class }, "MIR:00000013"), //
-
-  /**
-   * KEGG Genes: http://www.genome.jp/kegg/genes.html.
-   */
-  KEGG_GENES("Kegg Genes", //
-      "http://www.genome.jp/kegg/genes.html", //
-      new String[] { "urn:miriam:kegg.genes", "urn:miriam:kegg.genes:hsa" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000070"), //
-
-  /**
-   * KEGG Orthology: http://www.genome.jp/kegg/ko.html.
-   */
-  KEGG_ORTHOLOGY("KEGG Orthology", //
-      "http://www.genome.jp/kegg/ko.html", //
-      new String[] { "urn:miriam:kegg.orthology" }, //
-      new Class<?>[] {}, "MIR:00000116"), //
-
-  /**
-   * KEGG Pathway: http://www.genome.jp/kegg/pathway.html.
-   */
-  KEGG_PATHWAY("Kegg Pathway", //
-      "http://www.genome.jp/kegg/pathway.html", //
-      "urn:miriam:kegg.pathway", //
-      new Class<?>[] { Reaction.class }, "MIR:00000012"), //
-
-  /**
-   * KEGG Reaction: http://www.genome.jp/kegg/reaction/.
-   */
-  KEGG_REACTION("Kegg Reaction", //
-      "http://www.genome.jp/kegg/reaction/", //
-      "urn:miriam:kegg.reaction", //
-      new Class<?>[] { Reaction.class }, "MIR:00000014"), //
-
-  /**
-   * MeSH 2012: http://www.nlm.nih.gov/mesh/.
-   */
-  MESH_2012("MeSH 2012", //
-      "http://www.nlm.nih.gov/mesh/", //
-      new String[] { "urn:miriam:mesh.2012", "urn:miriam:mesh" }, //
-      new Class<?>[] { Phenotype.class, Compartment.class, Complex.class }, "MIR:00000270"), //
-
-  /**
-   * miRBase Sequence: http://www.mirbase.org/.
-   */
-  MI_R_BASE_SEQUENCE("miRBase Sequence Database", //
-      "http://www.mirbase.org/", //
-      new String[] { "urn:miriam:mirbase" }, //
-      new Class<?>[] {}, "MIR:00000078"), //
-
-  /**
-   * miRBase Mature Sequence: http://www.mirbase.org/.
-   */
-  MI_R_BASE_MATURE_SEQUENCE("miRBase Mature Sequence Database", //
-      "http://www.mirbase.org/", //
-      new String[] { "urn:miriam:mirbase.mature" }, //
-      new Class<?>[] {}, "MIR:00000235"), //
-
-  /**
-   * miRTaRBase Mature Sequence: http://mirtarbase.mbc.nctu.edu.tw/.
-   */
-  MIR_TAR_BASE_MATURE_SEQUENCE("miRTarBase Mature Sequence Database", //
-      "http://mirtarbase.mbc.nctu.edu.tw/", //
-      new String[] { "urn:miriam:mirtarbase" }, //
-      new Class<?>[] {}, "MIR:00100739"), //
-
-  /**
-   * Mouse Genome Database: http://www.informatics.jax.org/.
-   */
-  MGD("Mouse Genome Database", //
-      "http://www.informatics.jax.org/", //
-      new String[] { "urn:miriam:mgd" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000037"), //
-
-  /**
-   * Online Mendelian Inheritance in Man: http://omim.org/.
-   */
-  OMIM("Online Mendelian Inheritance in Man", //
-      "http://omim.org/", //
-      new String[] { "urn:miriam:omim" }, //
-      new Class<?>[] { Phenotype.class }, "MIR:00000016"), //
-
-  /**
-   * PANTHER Family: http://www.pantherdb.org/.
-   */
-  PANTHER("PANTHER Family", //
-      "http://www.pantherdb.org/", //
-      new String[] { "urn:miriam:panther.family", "urn:miriam:panther" }, //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000060"), //
-
-  /**
-   * PDB: http://www.pdbe.org/.
-   */
-  PDB("Protein Data Bank", //
-      "http://www.pdbe.org/", //
-      "urn:miriam:pdb", //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000020"),
-
-  /**
-   * Protein Family Database: http://pfam.xfam.org/.
-   */
-  PFAM("Protein Family Database", //
-      "http://pfam.xfam.org//", //
-      "urn:miriam:pfam", //
-      new Class<?>[] {}, "MIR:00000028"), //
-
-  /**
-   * PharmGKB Pathways: http://www.pharmgkb.org/.
-   */
-  PHARM("PharmGKB Pathways", //
-      "http://www.pharmgkb.org/", //
-      "urn:miriam:pharmgkb.pathways", //
-      new Class<?>[] {}, "MIR:00000089"), //
-
-  /**
-   * PubChem-compound: http://pubchem.ncbi.nlm.nih.gov/.
-   */
-  PUBCHEM("PubChem-compound", //
-      "http://pubchem.ncbi.nlm.nih.gov/", //
-      new String[] { "urn:miriam:pubchem.compound" }, //
-      new Class<?>[] { Chemical.class }, "MIR:00000034", //
-      new Class<?>[] { Chemical.class }), //
-
-  /**
-   * PubChem-substance: http://pubchem.ncbi.nlm.nih.gov/.
-   */
-  PUBCHEM_SUBSTANCE("PubChem-substance", //
-      "http://pubchem.ncbi.nlm.nih.gov/", //
-      new String[] { "urn:miriam:pubchem.substance" }, //
-      new Class<?>[] { Chemical.class }, "MIR:00000033", //
-      new Class<?>[] { Chemical.class }), //
-
-  /**
-   * PubMed: http://www.ncbi.nlm.nih.gov/PubMed/.
-   */
-  PUBMED("PubMed", //
-      "http://www.ncbi.nlm.nih.gov/PubMed/", //
-      new String[] { "urn:miriam:pubmed" }, //
-      new Class<?>[] { BioEntity.class }, "MIR:00000015", //
-      new Class<?>[] { Reaction.class }), //
-
-  /**
-   * Reactome: http://www.reactome.org/.
-   */
-  REACTOME("Reactome", //
-      "http://www.reactome.org/", //
-      "urn:miriam:reactome", //
-      new Class<?>[] { Reaction.class }, "MIR:00000018"), //
-
-  /**
-   * RefSeq: http://www.ncbi.nlm.nih.gov/projects/RefSeq/.
-   */
-  REFSEQ("RefSeq", //
-      "http://www.ncbi.nlm.nih.gov/projects/RefSeq/", //
-      "urn:miriam:refseq", //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000039"),
-
-  /**
-   * SGD: http://www.yeastgenome.org/.
-   */
-  SGD("Saccharomyces Genome Database", //
-      "http://www.yeastgenome.org/", //
-      "urn:miriam:sgd", //
-      new Class<?>[] {}, "MIR:00000023"),
-      
-  /**
+	/**
+	 * Consensus CDS: http://identifiers.org/ccds/.
+	 */
+	CCDS("Consensus CDS", //
+			"http://www.ncbi.nlm.nih.gov/CCDS/", //
+			new String[] { "urn:miriam:ccds" }, //
+			new Class<?>[] {}, "MIR:00000375"), //
+
+	/**
+	 * Chebi database:
+	 * <a href = "http://www.ebi.ac.uk/chebi/">http://www.ebi.ac.uk/chebi/</a>.
+	 */
+	CHEBI("Chebi", //
+			"http://www.ebi.ac.uk/chebi/", //
+			new String[] { "urn:miriam:obo.chebi", "urn:miriam:chebi" }, //
+			new Class<?>[] { Chemical.class, Drug.class, }, "MIR:00000002", //
+			new Class<?>[] { Chemical.class }), //
+
+	/**
+	 * ChemSpider database:
+	 * <a href = "http://www.chemspider.com/">http://www.chemspider.com/</a>.
+	 */
+	CHEMSPIDER("ChemSpider", //
+			"http://www.chemspider.com//", //
+			new String[] { "urn:miriam:chemspider" }, //
+			new Class<?>[] {}, "MIR:00000138"), //
+
+	/**
+	 * Chembl database: https://www.ebi.ac.uk/chembldb/.
+	 */
+	CHEMBL_COMPOUND("ChEMBL", //
+			"https://www.ebi.ac.uk/chembldb/", //
+			new String[] { "urn:miriam:chembl.compound" }, //
+			new Class<?>[] { Drug.class }, "MIR:00000084"), //
+
+	/**
+	 * Target in chembl database: https://www.ebi.ac.uk/chembldb/.
+	 */
+	CHEMBL_TARGET("ChEMBL target", //
+			"https://www.ebi.ac.uk/chembldb/", //
+			new String[] { "urn:miriam:chembl.target" }, //
+			new Class<?>[] { Protein.class, Complex.class }, "MIR:00000085"), //
+
+	/**
+	 * Clusters of Orthologous Groups: https://www.ncbi.nlm.nih.gov/COG/. 
+	 */
+	COG("Clusters of Orthologous Groups", //
+			"https://www.ncbi.nlm.nih.gov/COG/", //
+			new String[] { "urn:miriam:cogs" }, //
+			new Class<?>[] { Reaction.class }, "MIR:00000296"), //
+
+	/**
+	 * Drugbank database: http://www.drugbank.ca/.
+	 */
+	DRUGBANK("DrugBank", //
+			"http://www.drugbank.ca/", //
+			new String[] { "urn:miriam:drugbank" }, //
+			new Class<?>[] { Drug.class }, "MIR:00000102"), //
+	/**
+	 * Drugbank tagrets: http://www.drugbank.ca/targets.
+	 */
+	DRUGBANK_TARGET_V4("DrugBank Target v4", //
+			"http://www.drugbank.ca/targets", //
+			new String[] { "urn:miriam:drugbankv4.target" }, //
+			new Class<?>[] {}, "MIR:00000528"), //
+
+	/**
+	 * Enzyme Nomenclature: http://www.enzyme-database.org/.
+	 */
+	EC("Enzyme Nomenclature", //
+			"http://www.enzyme-database.org/", //
+			new String[] { "urn:miriam:ec-code" }, //
+			new Class<?>[] { Protein.class, Complex.class }, "MIR:00000004"), //
+
+	/**
+	 * Ensembl: www.ensembl.org.
+	 */
+	ENSEMBL("Ensembl", //
+			"www.ensembl.org", //
+			new String[] { "urn:miriam:ensembl" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000003"), //
+
+	/**
+	 * Ensembl Plants: http://plants.ensembl.org/.
+	 */
+	ENSEMBL_PLANTS("Ensembl Plants", //
+			"http://plants.ensembl.org/", //
+			new String[] { "urn:miriam:ensembl.plant" }, //
+			new Class<?>[] {}, "MIR:00000205"), //
+
+	/**
+	 * Entrez Gene: http://www.ncbi.nlm.nih.gov/gene.
+	 */
+	ENTREZ("Entrez Gene", //
+			"http://www.ncbi.nlm.nih.gov/gene", //
+			new String[] { "urn:miriam:ncbigene", "urn:miriam:entrez.gene" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000069"), //
+
+	/**
+	 * Gene Ontology: http://amigo.geneontology.org/amigo.
+	 */
+	GO("Gene Ontology", //
+			"http://amigo.geneontology.org/amigo", //
+			new String[] { "urn:miriam:obo.go", "urn:miriam:go" }, //
+			new Class<?>[] { Phenotype.class, Compartment.class, Complex.class }, "MIR:00000022"), //
+
+	/**
+	 * HGNC: http://www.genenames.org.
+	 */
+	HGNC("HGNC", //
+			"http://www.genenames.org", //
+			new String[] { "urn:miriam:hgnc" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000080", //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }), //
+
+	/**
+	 * HGNC symbol: http://www.genenames.org.
+	 */
+	HGNC_SYMBOL("HGNC Symbol", //
+			"http://www.genenames.org", //
+			new String[] { "urn:miriam:hgnc.symbol" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000362", //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }), //
+
+	/**
+	 * HMDB: http://www.hmdb.ca/.
+	 */
+	HMDB("HMDB", //
+			"http://www.hmdb.ca/", //
+			"urn:miriam:hmdb", //
+			new Class<?>[] { Chemical.class, Drug.class, }, "MIR:00000051"), //
+
+	/**
+	 * InterPro: http://www.ebi.ac.uk/interpro/.
+	 */
+	INTERPRO("InterPro", //
+			"http://www.ebi.ac.uk/interpro/", //
+			new String[] { "urn:miriam:interpro" }, //
+			new Class<?>[] { Protein.class, Complex.class }, "MIR:00000011"), //
+
+	/**
+	 * KEGG Compound: http://www.genome.jp/kegg/ligand.html.
+	 */
+	KEGG_COMPOUND("Kegg Compound", //
+			"http://www.genome.jp/kegg/ligand.html", //
+			"urn:miriam:kegg.compound", //
+			new Class<?>[] { Chemical.class }, "MIR:00000013"), //
+
+	/**
+	 * KEGG Genes: http://www.genome.jp/kegg/genes.html.
+	 */
+	KEGG_GENES("Kegg Genes", //
+			"http://www.genome.jp/kegg/genes.html", //
+			new String[] { "urn:miriam:kegg.genes", "urn:miriam:kegg.genes:hsa" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000070"), //
+
+	/**
+	 * KEGG Orthology: http://www.genome.jp/kegg/ko.html.
+	 */
+	KEGG_ORTHOLOGY("KEGG Orthology", //
+			"http://www.genome.jp/kegg/ko.html", //
+			new String[] { "urn:miriam:kegg.orthology" }, //
+			new Class<?>[] {}, "MIR:00000116"), //
+
+	/**
+	 * KEGG Pathway: http://www.genome.jp/kegg/pathway.html.
+	 */
+	KEGG_PATHWAY("Kegg Pathway", //
+			"http://www.genome.jp/kegg/pathway.html", //
+			"urn:miriam:kegg.pathway", //
+			new Class<?>[] { Reaction.class }, "MIR:00000012"), //
+
+	/**
+	 * KEGG Reaction: http://www.genome.jp/kegg/reaction/.
+	 */
+	KEGG_REACTION("Kegg Reaction", //
+			"http://www.genome.jp/kegg/reaction/", //
+			"urn:miriam:kegg.reaction", //
+			new Class<?>[] { Reaction.class }, "MIR:00000014"), //
+
+	/**
+	 * MeSH 2012: http://www.nlm.nih.gov/mesh/.
+	 */
+	MESH_2012("MeSH 2012", //
+			"http://www.nlm.nih.gov/mesh/", //
+			new String[] { "urn:miriam:mesh.2012", "urn:miriam:mesh" }, //
+			new Class<?>[] { Phenotype.class, Compartment.class, Complex.class }, "MIR:00000270"), //
+
+	/**
+	 * miRBase Sequence: http://www.mirbase.org/.
+	 */
+	MI_R_BASE_SEQUENCE("miRBase Sequence Database", //
+			"http://www.mirbase.org/", //
+			new String[] { "urn:miriam:mirbase" }, //
+			new Class<?>[] {}, "MIR:00000078"), //
+
+	/**
+	 * miRBase Mature Sequence: http://www.mirbase.org/.
+	 */
+	MI_R_BASE_MATURE_SEQUENCE("miRBase Mature Sequence Database", //
+			"http://www.mirbase.org/", //
+			new String[] { "urn:miriam:mirbase.mature" }, //
+			new Class<?>[] {}, "MIR:00000235"), //
+
+	/**
+	 * miRTaRBase Mature Sequence: http://mirtarbase.mbc.nctu.edu.tw/.
+	 */
+	MIR_TAR_BASE_MATURE_SEQUENCE("miRTarBase Mature Sequence Database", //
+			"http://mirtarbase.mbc.nctu.edu.tw/", //
+			new String[] { "urn:miriam:mirtarbase" }, //
+			new Class<?>[] {}, "MIR:00100739"), //
+
+	/**
+	 * Mouse Genome Database: http://www.informatics.jax.org/.
+	 */
+	MGD("Mouse Genome Database", //
+			"http://www.informatics.jax.org/", //
+			new String[] { "urn:miriam:mgd" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000037"), //
+
+	/**
+	 * Online Mendelian Inheritance in Man: http://omim.org/.
+	 */
+	OMIM("Online Mendelian Inheritance in Man", //
+			"http://omim.org/", //
+			new String[] { "urn:miriam:omim" }, //
+			new Class<?>[] { Phenotype.class }, "MIR:00000016"), //
+
+	/**
+	 * PANTHER Family: http://www.pantherdb.org/.
+	 */
+	PANTHER("PANTHER Family", //
+			"http://www.pantherdb.org/", //
+			new String[] { "urn:miriam:panther.family", "urn:miriam:panther" }, //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000060"), //
+	
+	/**
+	 * PDB: http://www.pdbe.org/.
+	 */
+	PDB("Protein Data Bank", //
+			"http://www.pdbe.org/", //
+			"urn:miriam:pdb", //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000020"),
+
+	/**
+	 * Protein Family Database: http://pfam.xfam.org/.
+	 */
+	PFAM("Protein Family Database", //
+			"http://pfam.xfam.org//", //
+			"urn:miriam:pfam", //
+			new Class<?>[] {}, "MIR:00000028"), //
+
+	/**
+	 * PharmGKB Pathways: http://www.pharmgkb.org/.
+	 */
+	PHARM("PharmGKB Pathways", //
+			"http://www.pharmgkb.org/", //
+			"urn:miriam:pharmgkb.pathways", //
+			new Class<?>[] {}, "MIR:00000089"), //
+
+	/**
+	 * PubChem-compound: http://pubchem.ncbi.nlm.nih.gov/.
+	 */
+	PUBCHEM("PubChem-compound", //
+			"http://pubchem.ncbi.nlm.nih.gov/", //
+			new String[] { "urn:miriam:pubchem.compound" }, //
+			new Class<?>[] { Chemical.class }, "MIR:00000034", //
+			new Class<?>[] { Chemical.class }), //
+
+	/**
+	 * PubChem-substance: http://pubchem.ncbi.nlm.nih.gov/.
+	 */
+	PUBCHEM_SUBSTANCE("PubChem-substance", //
+			"http://pubchem.ncbi.nlm.nih.gov/", //
+			new String[] { "urn:miriam:pubchem.substance" }, //
+			new Class<?>[] { Chemical.class }, "MIR:00000033", //
+			new Class<?>[] { Chemical.class }), //
+
+	/**
+	 * PubMed: http://www.ncbi.nlm.nih.gov/PubMed/.
+	 */
+	PUBMED("PubMed", //
+			"http://www.ncbi.nlm.nih.gov/PubMed/", //
+			new String[] { "urn:miriam:pubmed" }, //
+			new Class<?>[] { BioEntity.class }, "MIR:00000015", //
+			new Class<?>[] { Reaction.class }), //
+
+	/**
+	 * Reactome: http://www.reactome.org/.
+	 */
+	REACTOME("Reactome", //
+			"http://www.reactome.org/", //
+			"urn:miriam:reactome", //
+			new Class<?>[] { Reaction.class }, "MIR:00000018"), //
+
+	/**
+	 * RefSeq: http://www.ncbi.nlm.nih.gov/projects/RefSeq/.
+	 */
+	REFSEQ("RefSeq", //
+			"http://www.ncbi.nlm.nih.gov/projects/RefSeq/", //
+			"urn:miriam:refseq", //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000039"),
+
+	/**
+	 * SGD: http://www.yeastgenome.org/.
+	 */
+	SGD("Saccharomyces Genome Database", //
+			"http://www.yeastgenome.org/", //
+			"urn:miriam:sgd", //
+			new Class<?>[] {}, "MIR:00000023"),
+	
+	/**
 	 * STITCH: http://stitch.embl.de/.
 	 */
 	STITCH("STITCH", //
@@ -382,333 +373,332 @@ public enum MiriamType {
 			"urn:miriam:string", //
 			new Class<?>[] {}, "MIR:00000265"),
 
-  /**
-   * The Arabidopsis Information Resource (TAIR) maintains a database of genetic
-   * and molecular biology data for the model higher plant Arabidopsis thaliana.
-   * The name of a Locus is unique and used by TAIR, TIGR, and MIPS:
-   * http://arabidopsis.org/index.jsp.
-   */
-  TAIR_LOCUS("TAIR Locus", //
-      "http://arabidopsis.org/index.jsp", //
-      "urn:miriam:tair.locus", //
-      new Class<?>[] {}, "MIR:00000050"),
-
-  /**
-   * Taxonomy: http://www.ncbi.nlm.nih.gov/taxonomy/.
-   */
-  TAXONOMY("Taxonomy", //
-      "http://www.ncbi.nlm.nih.gov/taxonomy/", //
-      "urn:miriam:taxonomy", //
-      new Class<?>[] {}, "MIR:00000006"),
-  /**
-   * Toxicogenomic: Chemical: http://ctdbase.org/detail.go.
-   * http://ctdbase.org/detail.go
-   */
-  TOXICOGENOMIC_CHEMICAL("Toxicogenomic Chemical", //
-      "http://ctdbase.org/", //
-      "urn:miriam:ctd.chemical", //
-      new Class<?>[] {}, "MIR:00000098"), //
-
-  /**
-   * UniGene: http://www.ncbi.nlm.nih.gov/unigene.
-   */
-  UNIGENE("UniGene", //
-      "http://www.ncbi.nlm.nih.gov/unigene", //
-      "urn:miriam:unigene", //
-      new Class<?>[] {}, "MIR:00000346"),
-
-  /**
-   * Uniprot: http://www.uniprot.org/.
-   */
-  UNIPROT("Uniprot", //
-      "http://www.uniprot.org/", //
-      "urn:miriam:uniprot", //
-      new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000005"),
-
-  /**
-   * UniProt Isoform: http://www.uniprot.org/.
-   */
-  UNIPROT_ISOFORM("UniProt Isoform", //
-      "http://www.uniprot.org/", //
-      "urn:miriam:uniprot.isoform", //
-      new Class<?>[] { Protein.class }, "MIR:00000388"),
-
-  /**
-   * Unknown reference type...
-   */
-  UNKNOWN("Unknown", //
-      null, //
-      new String[] {}, //
-      new Class<?>[] {}, null),
-
-  /**
-   * Wikidata: https://www.wikidata.org/.
-   */
-  WIKIDATA("Wikidata", //
-      "https://www.wikidata.org/", //
-      new String[] { "urn:miriam:wikidata" }, //
-      new Class<?>[] {}, "MIR:00000549"), //
-
-  /**
-   * WikiPathways: http://www.wikipathways.org/.
-   */
-  WIKIPATHWAYS("WikiPathways", //
-      "http://www.wikipathways.org/", //
-      new String[] { "urn:miriam:wikipathways" }, //
-      new Class<?>[] {}, "MIR:00000076"), //
-
-  /**
-   * Wikipedia: http://en.wikipedia.org/wiki/Main_Page.
-   */
-  WIKIPEDIA("Wikipedia (English)", //
-      "http://en.wikipedia.org/wiki/Main_Page", // /
-      new String[] { "urn:miriam:wikipedia.en" }, //
-      new Class<?>[] {}, "MIR:00000384"),
-
-  /**
-   * WormBase: http://wormbase.bio2rdf.org/fct.
-   */
-  WORM_BASE("WormBase", //
-      "http://wormbase.bio2rdf.org/fct", // /
-      new String[] { "urn:miriam:wormbase" }, //
-      new Class<?>[] {}, "MIR:00000027");
-
-  /**
-   * User friendly name.
-   */
-  private String commonName;
-
-  /**
-   * url to homepage of given resource type.
-   */
-  private String dbHomepage;
-
-  /**
-   * Identifier of the database in miriam registry.
-   */
-  private String registryIdentifier;
-
-  /**
-   * Valid uris to this resource.
-   */
-  private List<String> uris = new ArrayList<String>();
-
-  /**
-   * Classes that can be annotated by this resource.
-   */
-  private List<Class<? extends BioEntity>> validClass = new ArrayList<>();
-
-  /**
-   * When class from this list is marked as "require at least one annotation" then
-   * annotation of this type is valid.
-   */
-  private List<Class<? extends BioEntity>> requiredClass = new ArrayList<>();
-
-  /**
-   * Constructor that initialize enum object.
-   * 
-   * @param dbHomePage
-   *          homepage of the resource {@link #dbHomepage}
-   * @param commonName
-   *          {@link #commonName}
-   * @param uris
-   *          {@link #uris}
-   * @param classes
-   *          {@link #validClass}
-   * @param registryIdentifier
-   *          {@link #registryIdentifier}
-   */
-  MiriamType(String commonName, String dbHomePage, String[] uris, Class<?>[] classes, String registryIdentifier) {
-    this(commonName, dbHomePage, uris, classes, registryIdentifier, new Class<?>[] {});
-  }
-
-  /**
-   * Constructor that initialize enum object.
-   * 
-   * @param dbHomePage
-   *          homepage of the resource {@link #dbHomepage}
-   * @param commonName
-   *          {@link #commonName}
-   * @param uris
-   *          {@link #uris}
-   * @param classes
-   *          {@link #validClass}
-   * @param registryIdentifier
-   *          {@link #registryIdentifier}
-   * @param requiredClasses
-   *          {@link #requiredClasses}
-   */
-  MiriamType(String commonName, String dbHomePage, String[] uris, Class<?>[] classes, String registryIdentifier,
-      Class<?>[] requiredClasses) {
-    this.commonName = commonName;
-    this.dbHomepage = dbHomePage;
-    for (String string : uris) {
-      this.uris.add(string);
-    }
-    for (Class<?> clazz : classes) {
-      this.validClass.add((Class<? extends BioEntity>) clazz);
-    }
-    for (Class<?> clazz : requiredClasses) {
-      this.requiredClass.add((Class<? extends BioEntity>) clazz);
-    }
-    this.registryIdentifier = registryIdentifier;
-  }
-
-  /**
-   * Constructor that initialize enum object.
-   * 
-   * @param dbHomePage
-   *          homepage of the resource {@link #dbHomepage}
-   * @param commonName
-   *          {@link #commonName}
-   * @param uri
-   *          one of {@link #uris}
-   * @param registryIdentifier
-   *          {@link #registryIdentifier}
-   * @param classes
-   *          {@link #validClass}
-   */
-  MiriamType(String commonName, String dbHomePage, String uri, Class<?>[] classes, String registryIdentifier) {
-    this(commonName, dbHomePage, new String[] { uri }, classes, registryIdentifier);
-  }
-
-  /**
-   * 
-   * @return {@link #commonName}
-   */
-  public String getCommonName() {
-    return commonName;
-  }
-
-  /**
-   * 
-   * @return {@link #uris}
-   */
-  public List<String> getUris() {
-    return uris;
-  }
-
-  /**
-   * 
-   * @return {@link #validClass}
-   */
-  public List<Class<? extends BioEntity>> getValidClass() {
-    return validClass;
-  }
-
-  /**
-   * Returns {@link MiriamType} associated with parameter uri address.
-   * 
-   * @param uri
-   *          uri to check
-   * @return {@link MiriamType} for given uri
-   */
-  public static MiriamType getTypeByUri(String uri) {
-    for (MiriamType mt : MiriamType.values()) {
-      for (String string : mt.getUris()) {
-        if (string.equalsIgnoreCase(uri)) {
-          return mt;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * @return the dbHomepage
-   * @see #dbHomepage
-   */
-  public String getDbHomepage() {
-    return dbHomepage;
-  }
-
-  /**
-   * @return the registryIdentifier
-   * @see #registryIdentifier
-   */
-  public String getRegistryIdentifier() {
-    return registryIdentifier;
-  }
-
-  /**
-   * @return the requiredClass
-   * @see #requiredClass
-   */
-  public List<Class<? extends BioEntity>> getRequiredClass() {
-    return requiredClass;
-  }
-
-  /**
-   * Returns {@link MiriamType} associated with {@link #commonName}.
-   * 
-   * @param string
-   *          {@link #commonName}
-   * @return {@link MiriamType} for given name
-   */
-  public static MiriamType getTypeByCommonName(String string) {
-    for (MiriamType mt : MiriamType.values()) {
-      if (string.equalsIgnoreCase(mt.getCommonName())) {
-        return mt;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Transforms identifier into {@link MiriamData}.
-   * 
-   * @param generalIdentifier
-   *          identifier in the format NAME:IDENTIFIER. Where NAME is the name
-   *          from {@link MiriamType#commonName} and IDENTIFIER is reasource
-   *          identifier.
-   * @return {@link MiriamData} representing generalIdentifier, when identifier is
-   *         invalid InvalidArgumentException is thrown
-   */
-  public static MiriamData getMiriamDataFromIdentifier(String generalIdentifier) {
-    int index = generalIdentifier.indexOf(":");
-    if (index < 0) {
-      throw new InvalidArgumentException("Identifier doesn't contain type");
-    }
-    String type = generalIdentifier.substring(0, index);
-    String id = generalIdentifier.substring(index + 1);
-    for (MiriamType mt : MiriamType.values()) {
-      if (mt.getCommonName().equalsIgnoreCase(type)) {
-        return new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, mt, id);
-      }
-    }
-    throw new InvalidArgumentException("Unknown miriam type: " + type + " (id: " + id + ")");
-  }
-
-  /**
-   * Creates {@link MiriamData} from miriam uri.
-   * 
-   * @param miriamUri
-   *          miriam uri defining {@link MiriamData}
-   * @return {@link MiriamData} from miriam uri
-   */
-  public static MiriamData getMiriamByUri(String miriamUri) {
-    // this hack is due to CellDesigner issue (CellDesigner incorectly handle
-    // with identifiers that have ":" inside resource ":" inside resource with
-    // "%3A" and also the last ":"
-    miriamUri = miriamUri.replace("%3A", ":");
-
-    String foundUri = "";
-    MiriamType foundType = null;
-
-    for (MiriamType type : MiriamType.values()) {
-      for (String uri : type.getUris()) {
-        if (miriamUri.startsWith(uri + ":")) {
-          if (uri.length() > foundUri.length()) {
-            foundType = type;
-            foundUri = uri;
-          }
-        }
-      }
-    }
-    if (foundType != null) {
-      return new MiriamData(foundType, miriamUri.substring(foundUri.length() + 1));
-    }
-    throw new InvalidArgumentException("Invalid miriam uri: " + miriamUri);
-  }
+	/**
+	 * The Arabidopsis Information Resource (TAIR) maintains a database of genetic
+	 * and molecular biology data for the model higher plant Arabidopsis thaliana.
+	 * The name of a Locus is unique and used by TAIR, TIGR, and MIPS:
+	 * http://arabidopsis.org/index.jsp.
+	 */
+	TAIR_LOCUS("TAIR Locus", //
+			"http://arabidopsis.org/index.jsp", //
+			"urn:miriam:tair.locus", //
+			new Class<?>[] {}, "MIR:00000050"),
+
+	/**
+	 * Taxonomy: http://www.ncbi.nlm.nih.gov/taxonomy/.
+	 */
+	TAXONOMY("Taxonomy", //
+			"http://www.ncbi.nlm.nih.gov/taxonomy/", //
+			"urn:miriam:taxonomy", //
+			new Class<?>[] {}, "MIR:00000006"),
+	/**
+	 * Toxicogenomic: Chemical: http://ctdbase.org/detail.go.
+	 * http://ctdbase.org/detail.go
+	 */
+	TOXICOGENOMIC_CHEMICAL("Toxicogenomic Chemical", //
+			"http://ctdbase.org/", //
+			"urn:miriam:ctd.chemical", //
+			new Class<?>[] {}, "MIR:00000098"), //
+
+	/**
+	 * UniGene: http://www.ncbi.nlm.nih.gov/unigene.
+	 */
+	UNIGENE("UniGene", //
+			"http://www.ncbi.nlm.nih.gov/unigene", //
+			"urn:miriam:unigene", //
+			new Class<?>[] {}, "MIR:00000346"),
+
+	/**
+	 * Uniprot: http://www.uniprot.org/.
+	 */
+	UNIPROT("Uniprot", //
+			"http://www.uniprot.org/", //
+			"urn:miriam:uniprot", //
+			new Class<?>[] { Protein.class, Gene.class, Rna.class }, "MIR:00000005"),
+
+	/**
+	 * UniProt Isoform: http://www.uniprot.org/.
+	 */
+	UNIPROT_ISOFORM("UniProt Isoform", //
+			"http://www.uniprot.org/", //
+			"urn:miriam:uniprot.isoform", //
+			new Class<?>[] { Protein.class }, "MIR:00000388"),
+
+	/**
+	 * Unknown reference type...
+	 */
+	UNKNOWN("Unknown", //
+			null, //
+			new String[] {}, //
+			new Class<?>[] {}, null),
+
+	/**
+	 * Wikidata: https://www.wikidata.org/.
+	 */
+	WIKIDATA("Wikidata", //
+			"https://www.wikidata.org/", //
+			new String[] { "urn:miriam:wikidata" }, //
+			new Class<?>[] {}, "MIR:00000549"), //
+
+	/**
+	 * WikiPathways: http://www.wikipathways.org/.
+	 */
+	WIKIPATHWAYS("WikiPathways", //
+			"http://www.wikipathways.org/", //
+			new String[] { "urn:miriam:wikipathways" }, //
+			new Class<?>[] {}, "MIR:00000076"), //
+
+	/**
+	 * Wikipedia: http://en.wikipedia.org/wiki/Main_Page.
+	 */
+	WIKIPEDIA("Wikipedia (English)", //
+			"http://en.wikipedia.org/wiki/Main_Page", // /
+			new String[] { "urn:miriam:wikipedia.en" }, //
+			new Class<?>[] {}, "MIR:00000384"),
+
+	/**
+	 * WormBase: http://wormbase.bio2rdf.org/fct.
+	 */
+	WORM_BASE("WormBase", //
+			"http://wormbase.bio2rdf.org/fct", // /
+			new String[] { "urn:miriam:wormbase" }, //
+			new Class<?>[] {}, "MIR:00000027");
+
+	/**
+	 * User friendly name.
+	 */
+	private String																 commonName;
+
+	/**
+	 * url to homepage of given resource type.
+	 */
+	private String																 dbHomepage;
 
+	/**
+	 * Identifier of the database in miriam registry.
+	 */
+	private String																 registryIdentifier;
+
+	/**
+	 * Valid uris to this resource.
+	 */
+	private List<String>													 uris					 = new ArrayList<String>();
+
+	/**
+	 * Classes that can be annotated by this resource.
+	 */
+	private List<Class<? extends BioEntity>> validClass		 = new ArrayList<>();
+
+	/**
+	 * When class from this list is marked as "require at least one annotation"
+	 * then annotation of this type is valid.
+	 */
+	private List<Class<? extends BioEntity>> requiredClass = new ArrayList<>();
+		
+
+	/**
+	 * Constructor that initialize enum object.
+	 * 
+	 * @param dbHomePage
+	 *          homepage of the resource {@link #dbHomepage}
+	 * @param commonName
+	 *          {@link #commonName}
+	 * @param uris
+	 *          {@link #uris}
+	 * @param classes
+	 *          {@link #validClass}
+	 * @param registryIdentifier
+	 *          {@link #registryIdentifier}
+	 */
+	MiriamType(String commonName, String dbHomePage, String[] uris, Class<?>[] classes, String registryIdentifier) {
+		this(commonName, dbHomePage, uris, classes, registryIdentifier, new Class<?>[] {});
+	}
+
+	/**
+	 * Constructor that initialize enum object.
+	 * 
+	 * @param dbHomePage
+	 *          homepage of the resource {@link #dbHomepage}
+	 * @param commonName
+	 *          {@link #commonName}
+	 * @param uris
+	 *          {@link #uris}
+	 * @param classes
+	 *          {@link #validClass}
+	 * @param registryIdentifier
+	 *          {@link #registryIdentifier}
+	 * @param requiredClasses
+	 *          {@link #requiredClasses}
+	 */
+	MiriamType(String commonName, String dbHomePage, String[] uris, Class<?>[] classes, String registryIdentifier, Class<?>[] requiredClasses) {
+		this.commonName = commonName;
+		this.dbHomepage = dbHomePage;
+		for (String string : uris) {
+			this.uris.add(string);
+		}
+		for (Class<?> clazz : classes) {
+			this.validClass.add((Class<? extends BioEntity>) clazz);
+		}
+		for (Class<?> clazz : requiredClasses) {
+			this.requiredClass.add((Class<? extends BioEntity>) clazz);
+		}
+		this.registryIdentifier = registryIdentifier;
+	}
+
+	/**
+	 * Constructor that initialize enum object.
+	 * 
+	 * @param dbHomePage
+	 *          homepage of the resource {@link #dbHomepage}
+	 * @param commonName
+	 *          {@link #commonName}
+	 * @param uri
+	 *          one of {@link #uris}
+	 * @param registryIdentifier
+	 *          {@link #registryIdentifier}
+	 * @param classes
+	 *          {@link #validClass}
+	 */
+	MiriamType(String commonName, String dbHomePage, String uri, Class<?>[] classes, String registryIdentifier) {
+		this(commonName, dbHomePage, new String[] { uri }, classes, registryIdentifier);
+	}
+
+	/**
+	 * 
+	 * @return {@link #commonName}
+	 */
+	public String getCommonName() {
+		return commonName;
+	}
+
+	/**
+	 * 
+	 * @return {@link #uris}
+	 */
+	public List<String> getUris() {
+		return uris;
+	}
+
+	/**
+	 * 
+	 * @return {@link #validClass}
+	 */
+	public List<Class<? extends BioEntity>> getValidClass() {
+		return validClass;
+	}
+
+	/**
+	 * Returns {@link MiriamType} associated with parameter uri address.
+	 * 
+	 * @param uri
+	 *          uri to check
+	 * @return {@link MiriamType} for given uri
+	 */
+	public static MiriamType getTypeByUri(String uri) {
+		for (MiriamType mt : MiriamType.values()) {
+			for (String string : mt.getUris()) {
+				if (string.equalsIgnoreCase(uri)) {
+					return mt;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @return the dbHomepage
+	 * @see #dbHomepage
+	 */
+	public String getDbHomepage() {
+		return dbHomepage;
+	}
+
+	/**
+	 * @return the registryIdentifier
+	 * @see #registryIdentifier
+	 */
+	public String getRegistryIdentifier() {
+		return registryIdentifier;
+	}
+
+	/**
+	 * @return the requiredClass
+	 * @see #requiredClass
+	 */
+	public List<Class<? extends BioEntity>> getRequiredClass() {
+		return requiredClass;
+	}
+
+	/**
+	 * Returns {@link MiriamType} associated with {@link #commonName}.
+	 * 
+	 * @param string
+	 *          {@link #commonName}
+	 * @return {@link MiriamType} for given name
+	 */
+	public static MiriamType getTypeByCommonName(String string) {
+		for (MiriamType mt : MiriamType.values()) {
+			if (string.equalsIgnoreCase(mt.getCommonName())) {
+				return mt;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Transforms identifier into {@link MiriamData}.
+	 * 
+	 * @param generalIdentifier
+	 *          identifier in the format NAME:IDENTIFIER. Where NAME is the name
+	 *          from {@link MiriamType#commonName} and IDENTIFIER is reasource
+	 *          identifier.
+	 * @return {@link MiriamData} representing generalIdentifier, when identifier
+	 *         is invalid InvalidArgumentException is thrown
+	 */
+	public static MiriamData getMiriamDataFromIdentifier(String generalIdentifier) {
+		int index = generalIdentifier.indexOf(":");
+		if (index < 0) {
+			throw new InvalidArgumentException("Identifier doesn't contain type");
+		}
+		String type = generalIdentifier.substring(0, index);
+		String id = generalIdentifier.substring(index + 1);
+		for (MiriamType mt : MiriamType.values()) {
+			if (mt.getCommonName().equalsIgnoreCase(type)) {
+				return new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, mt, id);
+			}
+		}
+		throw new InvalidArgumentException("Unknown miriam type: " + type + " (id: " + id + ")");
+	}
+
+	/**
+	 * Creates {@link MiriamData} from miriam uri.
+	 * 
+	 * @param miriamUri
+	 *          miriam uri defining {@link MiriamData}
+	 * @return {@link MiriamData} from miriam uri
+	 */
+	public static MiriamData getMiriamByUri(String miriamUri) {
+		// this hack is due to CellDesigner issue (CellDesigner incorectly handle
+		// with identifiers that have ":" inside resource ":" inside resource with
+		// "%3A" and also the last ":"
+		miriamUri = miriamUri.replace("%3A", ":");
+
+		String foundUri = "";
+		MiriamType foundType = null;
+
+		for (MiriamType type : MiriamType.values()) {
+			for (String uri : type.getUris()) {
+				if (miriamUri.startsWith(uri + ":")) {
+					if (uri.length() > foundUri.length()) {
+						foundType = type;
+						foundUri = uri;
+					}
+				}
+			}
+		}
+		if (foundType != null) {
+			return new MiriamData(foundType, miriamUri.substring(foundUri.length() + 1));
+		}
+		throw new InvalidArgumentException("Invalid miriam uri: " + miriamUri);
+	}
 }
diff --git a/persist/src/db/12.0.0/fix_db_20180117.sql b/persist/src/db/12.0.0/fix_db_20180117.sql
new file mode 100644
index 0000000000..af37bf7888
--- /dev/null
+++ b/persist/src/db/12.0.0/fix_db_20180117.sql
@@ -0,0 +1,2 @@
+-- column to store which annotator is responsible for given miriam data
+alter table miriam_data_table add column annotator varchar(256) default null;
-- 
GitLab