From 38a94dbf0748c9488ef36464a66afc2acff69b04 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Tue, 13 Feb 2018 18:15:14 +0100
Subject: [PATCH] colorSchema simplified - it contains set of miriam data
 extracted from user input insted of preparsed information

---
 .../mapviewer/commands/ColorModelCommand.java |  25 +-
 .../commands/ColorModelCommandTest.java       |  16 +-
 .../model/map/layout/ColorSchema.java         |  89 ++----
 .../model/map/layout/ColorSchemaTest.java     | 253 +++++++++---------
 .../services/impl/LayoutService.java          |  12 +-
 .../services/utils/ColorSchemaReader.java     |  32 +--
 .../services/utils/ColorSchemaXlsxReader.java |  10 +-
 .../services/impl/LayoutServiceTest2.java     |   4 +-
 .../services/utils/ColorSchemaReaderTest.java |  11 +-
 9 files changed, 180 insertions(+), 272 deletions(-)

diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java
index 43df86700d..07d2e6faed 100644
--- a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java
+++ b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java
@@ -134,22 +134,11 @@ public class ColorModelCommand extends ModelCommand {
       return false;
     }
 
-    if (schema.getGeneralIdentifier() != null && !schema.getGeneralIdentifier().equals("")) {
-      MiriamData md = MiriamType.getMiriamDataFromIdentifier(schema.getGeneralIdentifier());
-
+    for (MiriamData md : schema.getMiriamData()) {
       if (!reaction.getMiriamData().contains(md)) {
         return false;
       }
     }
-    for (Pair<MiriamType, String> pair : schema.getIdentifierColumns()) {
-      if (pair.getRight() != null && !pair.getRight().equals("")) {
-
-        MiriamData md = new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, pair.getLeft(), pair.getRight());
-        if (!reaction.getMiriamData().contains(md)) {
-          return false;
-        }
-      }
-    }
 
     return true;
   }
@@ -234,21 +223,11 @@ public class ColorModelCommand extends ModelCommand {
           return false;
         }
       }
-      if (schema.getGeneralIdentifier() != null && !schema.getGeneralIdentifier().equals("")) {
-        MiriamData md = MiriamType.getMiriamDataFromIdentifier(schema.getGeneralIdentifier());
-
+      for (MiriamData md : schema.getMiriamData()) {
         if (!element.getMiriamData().contains(md)) {
           return false;
         }
       }
-      for (Pair<MiriamType, String> pair : schema.getIdentifierColumns()) {
-        if (pair.getRight() != null && !pair.getRight().equals("")) {
-          MiriamData md = new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, pair.getLeft(), pair.getRight());
-          if (!element.getMiriamData().contains(md)) {
-            return false;
-          }
-        }
-      }
 
       if (schema.getCompartments().size() > 0) {
         boolean found = false;
diff --git a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java
index b8d977f446..59fe3d09bf 100644
--- a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java
+++ b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java
@@ -87,15 +87,15 @@ public class ColorModelCommandTest extends CommandTestFunctions {
       Model model = getModelForFile("testFiles/coloring_model.xml", true);
       Collection<ColorSchema> schemas = new ArrayList<>();
       ColorSchema schema = new GenericColorSchema();
-      schema.setGeneralIdentifier("HGNC:11138");
+      schema.addMiriamData(new MiriamData(MiriamType.HGNC,"11138"));
       schema.setValue(1.0);
       schemas.add(schema);
       schema = new GenericColorSchema();
-      schema.setGeneralIdentifier("CHEBI:CHEBI:15377");
+      schema.addMiriamData(new MiriamData(MiriamType.CHEBI,"CHEBI:15377"));
       schema.setValue(1.0);
       schemas.add(schema);
       schema = new GenericColorSchema();
-      schema.setGeneralIdentifier("CHEBI:CHEBI:15376");
+      schema.addMiriamData(new MiriamData(MiriamType.CHEBI,"CHEBI:15376"));
       schema.setValue(1.0);
       schemas.add(schema);
 
@@ -188,11 +188,7 @@ public class ColorModelCommandTest extends CommandTestFunctions {
       Reaction re3 = model.getReactionByReactionId("re3");
       Collection<ColorSchema> schemas = new ArrayList<ColorSchema>();
       ColorSchema schema = new GenericColorSchema();
-      Pair<MiriamType, String> pair = new Pair<MiriamType, String>(MiriamType.PUBMED, "12345");
-      List<Pair<MiriamType, String>> identifiers = new ArrayList<Pair<MiriamType, String>>();
-      identifiers.add(pair);
-
-      schema.setIdentifierColumns(identifiers);
+      schema.addMiriamData(new MiriamData(MiriamType.PUBMED, "12345"));
       schema.setValue(-1.0);
       schemas.add(schema);
 
@@ -368,7 +364,7 @@ public class ColorModelCommandTest extends CommandTestFunctions {
   public void testReactionMatchWithProteinMiriamData() throws Exception {
     try {
       GenericColorSchema colorSchema = new GenericColorSchema();
-      colorSchema.setGeneralIdentifier(MiriamType.HGNC_SYMBOL.getCommonName()+":SNCA");
+      colorSchema.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL,"SNCA"));
 
       Reaction reaction = new Reaction();
 
@@ -390,7 +386,7 @@ public class ColorModelCommandTest extends CommandTestFunctions {
   public void testReactionMatchWithMiriamData() throws Exception {
     try {
       GenericColorSchema colorSchema = new GenericColorSchema();
-      colorSchema.setGeneralIdentifier(MiriamType.PUBMED.getCommonName()+":1234");
+      colorSchema.addMiriamData(new MiriamData(MiriamType.PUBMED,"1234"));
 
       Reaction reaction = new Reaction();
       reaction.addMiriamData(new MiriamData(MiriamType.PUBMED, "1234"));
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java
index a8628a8345..53174c04f4 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java
@@ -4,11 +4,12 @@ import java.awt.Color;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
-import lcsb.mapviewer.common.Pair;
 import lcsb.mapviewer.model.map.BioEntity;
-import lcsb.mapviewer.model.map.MiriamType;
+import lcsb.mapviewer.model.map.MiriamData;
 import lcsb.mapviewer.model.map.model.Model;
 import lcsb.mapviewer.model.map.species.Element;
 
@@ -78,14 +79,9 @@ public abstract class ColorSchema implements Serializable {
   private Color color = null;
 
   /**
-   * General identifier that identifies the element.
+   * Set of identifiers that filter the elements.
    */
-  private String generalIdentifier = null;
-
-  /**
-   * List of specific identifiers that filter the elements.
-   */
-  private List<Pair<MiriamType, String>> identifierColumns = new ArrayList<>();
+  private Set<MiriamData> miriamData = new HashSet<>();
 
   /**
    * Number of elements matched by this entry.
@@ -118,25 +114,11 @@ public abstract class ColorSchema implements Serializable {
     this.addTypes(original.getTypes());
     this.setValue(original.getValue());
     this.setColor(original.getColor());
-    this.setGeneralIdentifier(original.getGeneralIdentifier());
-    this.addIdentifierColumns(original.getIdentifierColumns());
+    this.miriamData.addAll(original.getMiriamData());
     this.setMatches(original.getMatches());
     this.setDescription(original.getDescription());
   }
 
-  /**
-   * Adds identifiers to {@link #identifierColumns} list.
-   * 
-   * @param identifierColumnsList
-   *          list of pairs defining type of identifier and the identifier value
-   */
-  public void addIdentifierColumns(List<Pair<MiriamType, String>> identifierColumnsList) {
-    for (Pair<MiriamType, String> pair : identifierColumnsList) {
-      addIdentifierColumn(pair);
-    }
-
-  }
-
   /**
    * Adds class types to {@link #types} list.
    * 
@@ -200,16 +182,8 @@ public abstract class ColorSchema implements Serializable {
     if (color != null) {
       result.append(color + ",");
     }
-    if (generalIdentifier != null) {
-      result.append(generalIdentifier + ",");
-    }
-    if (types.size() > 0) {
-      result.append("(");
-      for (Pair<MiriamType, String> pair : identifierColumns) {
-        result.append(pair.getLeft() + "-" + pair.getRight() + ",");
-      }
-      result.append("),");
-    }
+    result.append(miriamData + ",");
+
     result.append(matches + "]");
     return result.toString();
   }
@@ -303,40 +277,6 @@ public abstract class ColorSchema implements Serializable {
     this.color = color;
   }
 
-  /**
-   * @return the generalIdentifier
-   * @see #generalIdentifier
-   */
-  public String getGeneralIdentifier() {
-    return generalIdentifier;
-  }
-
-  /**
-   * @param generalIdentifier
-   *          the generalIdentifier to set
-   * @see #generalIdentifier
-   */
-  public void setGeneralIdentifier(String generalIdentifier) {
-    this.generalIdentifier = generalIdentifier;
-  }
-
-  /**
-   * @return the identifierColumns
-   * @see #identifierColumns
-   */
-  public List<Pair<MiriamType, String>> getIdentifierColumns() {
-    return identifierColumns;
-  }
-
-  /**
-   * @param identifierColumns
-   *          the identifierColumns to set
-   * @see #identifierColumns
-   */
-  public void setIdentifierColumns(List<Pair<MiriamType, String>> identifierColumns) {
-    this.identifierColumns = identifierColumns;
-  }
-
   /**
    * @return the matches
    * @see #matches
@@ -355,14 +295,11 @@ public abstract class ColorSchema implements Serializable {
   }
 
   /**
-   * Adds identifier to {@link #identifierColumns} list.
+   * Adds identifier to {@link #miriamData} set.
    * 
-   * @param pair
-   *          pair defining type of identifier and the identifier value
    */
-  public void addIdentifierColumn(Pair<MiriamType, String> pair) {
-    identifierColumns.add(pair);
-
+  public void addMiriamData(MiriamData md) {
+    miriamData.add(md);
   }
 
   /**
@@ -459,4 +396,8 @@ public abstract class ColorSchema implements Serializable {
     this.elementId = elementId;
   }
 
+  public Set<MiriamData> getMiriamData() {
+    return miriamData;
+  }
+
 }
diff --git a/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java b/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java
index 717ca331c5..1f58992fcf 100644
--- a/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java
@@ -12,6 +12,7 @@ import org.junit.Before;
 import org.junit.Test;
 
 import lcsb.mapviewer.common.Pair;
+import lcsb.mapviewer.model.map.MiriamData;
 import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.species.Element;
 import lcsb.mapviewer.model.map.species.Protein;
@@ -19,134 +20,128 @@ import lcsb.mapviewer.model.map.species.Species;
 
 public class ColorSchemaTest {
 
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testSetGetters() throws Exception {
-		try {
-			ColorSchema cs = new GenericColorSchema();
-			List<String> compartments = new ArrayList<>();
-			List<Class<? extends Element>> types = new ArrayList<>();
-			String name = "S";
-			String generalIdentifier = "id";
-			List<Pair<MiriamType, String>> identifierColumns = new ArrayList<>();
-			int matches = 79;
-			Double lineWidth = 5.89;
-			String reactionIdentifier = "re id";
-			Boolean reverseReaction = true;
-
-			cs.setName(name);
-			assertEquals(name, cs.getName());
-
-			cs.setCompartments(compartments);
-			assertEquals(compartments, cs.getCompartments());
-
-			cs.setTypes(types);
-			assertEquals(types, cs.getTypes());
-
-			cs.setGeneralIdentifier(generalIdentifier);
-			assertEquals(generalIdentifier, cs.getGeneralIdentifier());
-
-			cs.setIdentifierColumns(identifierColumns);
-			assertEquals(identifierColumns, cs.getIdentifierColumns());
-
-			cs.setMatches(matches);
-			assertEquals(matches, cs.getMatches());
-
-			cs.setLineWidth(lineWidth);
-			assertEquals(lineWidth, cs.getLineWidth());
-
-			cs.setElementId(reactionIdentifier);
-			assertEquals(reactionIdentifier, cs.getElementId());
-
-			cs.setReverseReaction(reverseReaction);
-			assertEquals(reverseReaction, cs.getReverseReaction());
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testToString() throws Exception {
-		try {
-			ColorSchema cs = new GenericColorSchema();
-			assertNotNull(cs.toString());
-			cs.setName("gene name");
-			cs.addCompartment("A");
-			cs.addType(Species.class);
-			cs.setValue(1.2);
-			cs.setColor(Color.BLACK);
-			cs.setGeneralIdentifier("a");
-			cs.addIdentifierColumn(new Pair<MiriamType, String>(MiriamType.CAS, "X"));
-			assertNotNull(cs.toString());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAddCompartments() throws Exception {
-		try {
-			ColorSchema cs = new GenericColorSchema();
-			cs.addCompartments(new String[] { "a", "b" });
-			assertEquals(2, cs.getCompartments().size());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAddCompartments2() throws Exception {
-		try {
-			ColorSchema cs = new GenericColorSchema();
-			List<String> compartments = new ArrayList<>();
-			compartments.add("a");
-			compartments.add("b");
-			cs.addCompartments(compartments);
-			assertEquals(2, cs.getCompartments().size());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAddIdentifgierColumns() throws Exception {
-		try {
-			ColorSchema cs = new GenericColorSchema();
-			List<Pair<MiriamType, String>> compartments = new ArrayList<>();
-			compartments.add(new Pair<MiriamType, String>(MiriamType.CAS, "x"));
-			cs.addIdentifierColumns(compartments);
-			assertEquals(1, cs.getIdentifierColumns().size());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	@Test
-	public void testAddTypes() throws Exception {
-		try {
-			ColorSchema cs = new GenericColorSchema();
-			List<Class<? extends Element>> compartments = new ArrayList<>();
-			compartments.add(Species.class);
-			compartments.add(Protein.class);
-			cs.addTypes(compartments);
-			assertEquals(2, cs.getTypes().size());
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testSetGetters() throws Exception {
+    try {
+      ColorSchema cs = new GenericColorSchema();
+      List<String> compartments = new ArrayList<>();
+      List<Class<? extends Element>> types = new ArrayList<>();
+      String name = "S";
+      int matches = 79;
+      Double lineWidth = 5.89;
+      String reactionIdentifier = "re id";
+      Boolean reverseReaction = true;
+
+      cs.setName(name);
+      assertEquals(name, cs.getName());
+
+      cs.setCompartments(compartments);
+      assertEquals(compartments, cs.getCompartments());
+
+      cs.setTypes(types);
+      assertEquals(types, cs.getTypes());
+
+      cs.setMatches(matches);
+      assertEquals(matches, cs.getMatches());
+
+      cs.setLineWidth(lineWidth);
+      assertEquals(lineWidth, cs.getLineWidth());
+
+      cs.setElementId(reactionIdentifier);
+      assertEquals(reactionIdentifier, cs.getElementId());
+
+      cs.setReverseReaction(reverseReaction);
+      assertEquals(reverseReaction, cs.getReverseReaction());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testToString() throws Exception {
+    try {
+      ColorSchema cs = new GenericColorSchema();
+      assertNotNull(cs.toString());
+      cs.setName("gene name");
+      cs.addCompartment("A");
+      cs.addType(Species.class);
+      cs.setValue(1.2);
+      cs.setColor(Color.BLACK);
+      cs.addMiriamData(new MiriamData(MiriamType.CAS, "X"));
+      assertNotNull(cs.toString());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAddCompartments() throws Exception {
+    try {
+      ColorSchema cs = new GenericColorSchema();
+      cs.addCompartments(new String[] { "a", "b" });
+      assertEquals(2, cs.getCompartments().size());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAddCompartments2() throws Exception {
+    try {
+      ColorSchema cs = new GenericColorSchema();
+      List<String> compartments = new ArrayList<>();
+      compartments.add("a");
+      compartments.add("b");
+      cs.addCompartments(compartments);
+      assertEquals(2, cs.getCompartments().size());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAddIdentifgierColumns() throws Exception {
+    try {
+      MiriamData generalIdentifier = new MiriamData();
+      ColorSchema cs = new GenericColorSchema();
+      List<Pair<MiriamType, String>> compartments = new ArrayList<>();
+      compartments.add(new Pair<MiriamType, String>(MiriamType.CAS, "x"));
+      cs.addMiriamData(generalIdentifier);
+
+      assertEquals(1, cs.getMiriamData().size());
+      assertEquals(generalIdentifier, cs.getMiriamData().iterator().next());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testAddTypes() throws Exception {
+    try {
+      ColorSchema cs = new GenericColorSchema();
+      List<Class<? extends Element>> compartments = new ArrayList<>();
+      compartments.add(Species.class);
+      compartments.add(Protein.class);
+      cs.addTypes(compartments);
+      assertEquals(2, cs.getTypes().size());
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
 
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java
index 990e348f5e..be6946bd40 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java
@@ -807,10 +807,8 @@ public class LayoutService implements ILayoutService {
       }
       sb.append("\t");
     } else if (column.equals(ColorSchemaColumn.IDENTIFIER)) {
-      for (Pair<MiriamType, String> pair : schema.getIdentifierColumns()) {
-        if (pair.getRight() != null && !pair.getRight().trim().equals("")) {
-          sb.append(pair.getLeft().getCommonName() + ": " + pair.getRight() + ", ");
-        }
+      for (MiriamData md : schema.getMiriamData()) {
+        sb.append(md.getDataType().getCommonName() + ": " + md.getResource() + ", ");
       }
       sb.append("\t");
     } else if (column.equals(ColorSchemaColumn.ELEMENT_IDENTIFIER)) {
@@ -864,10 +862,8 @@ public class LayoutService implements ILayoutService {
       }
       sb.append("\t");
     } else if (column.equals(ColorSchemaColumn.IDENTIFIER)) {
-      for (Pair<MiriamType, String> pair : schema.getIdentifierColumns()) {
-        if (pair.getRight() != null && !pair.getRight().trim().equals("")) {
-          sb.append(pair.getLeft().getCommonName() + ": " + pair.getRight() + ", ");
-        }
+      for (MiriamData md : schema.getMiriamData()) {
+        sb.append(md.getDataType().getCommonName() + ": " + md.getResource() + ", ");
       }
       sb.append("\t");
     } else if (column.equals(ColorSchemaColumn.ELEMENT_IDENTIFIER)) {
diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java
index e2a41ccbe2..624927757a 100644
--- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java
+++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java
@@ -194,6 +194,7 @@ public class ColorSchemaReader {
       line = br.readLine();
       while (line != null) {
         lineIndex++;
+        String errorPrefix = "[Line " + lineIndex + "]\t";
         if (!line.trim().equals("")) {
           String[] values = line.split("\t", -1);
           if (values.length != columns.length) {
@@ -224,12 +225,7 @@ public class ColorSchemaReader {
             schema.setColor(colorParser.parse(values[colorColumn]));
           }
           if (identifierColumn != null && !values[identifierColumn].equals("")) {
-            if (mc.isValidIdentifier(values[identifierColumn])) {
-              schema.setGeneralIdentifier(values[identifierColumn]);
-            } else {
-              throw new InvalidColorSchemaException(
-                  "[Line " + lineIndex + "] Invalid identifier: " + values[identifierColumn]);
-            }
+            processGeneralIdentifier(values[identifierColumn], schema, errorPrefix);
           }
           if (descriptionColumn != null) {
             schema.setDescription(values[descriptionColumn]);
@@ -303,6 +299,15 @@ public class ColorSchemaReader {
     return mergeSchemas(result);
   }
 
+  private void processGeneralIdentifier(String string, ColorSchema schema, String errorPrefix)
+      throws InvalidColorSchemaException {
+    if (mc.isValidIdentifier(string)) {
+      schema.addMiriamData(MiriamType.getMiriamDataFromIdentifier(string));
+    } else {
+      throw new InvalidColorSchemaException(errorPrefix + " Invalid identifier: " + string);
+    }
+  }
+
   /**
    * Sets proper value of identifier to {@link ColorSchema} from cell content.
    * 
@@ -315,7 +320,7 @@ public class ColorSchemaReader {
    */
   private void processIdentifier(String content, MiriamType type, ColorSchema schema) {
     if (!content.isEmpty()) {
-      schema.addIdentifierColumn(new Pair<MiriamType, String>(type, content));
+      schema.addMiriamData(new MiriamData(type, content));
     }
   }
 
@@ -487,9 +492,8 @@ public class ColorSchemaReader {
 
       if (nameColumn == null && identifierColumn == null && customIdentifiers.size() == 0
           && elementIdentifierColumn == null) {
-        throw new InvalidColorSchemaException(
-            "One of these columns is obligatory: " + ColorSchemaColumn.NAME.getTitle() + ","
-                + ColorSchemaColumn.IDENTIFIER.getTitle() + "," + ColorSchemaColumn.ELEMENT_IDENTIFIER.getTitle());
+        throw new InvalidColorSchemaException("One of these columns is obligatory: " + ColorSchemaColumn.NAME.getTitle()
+            + "," + ColorSchemaColumn.IDENTIFIER.getTitle() + "," + ColorSchemaColumn.ELEMENT_IDENTIFIER.getTitle());
       }
 
       if (valueColumn == null && colorColumn == null) {
@@ -552,11 +556,7 @@ public class ColorSchemaReader {
           schema.setReverseReaction("true".equalsIgnoreCase(values[reverseReactionColumn]));
         }
         if (identifierColumn != null && !values[identifierColumn].equals("")) {
-          if (mc.isValidIdentifier(values[identifierColumn])) {
-            schema.setGeneralIdentifier(values[identifierColumn]);
-          } else {
-            throw new InvalidColorSchemaException(errorPrefix + "Invalid identifier: " + values[identifierColumn]);
-          }
+          processGeneralIdentifier(values[identifierColumn], schema, errorPrefix);
         }
         for (Pair<MiriamType, Integer> pair : customIdentifiers) {
           processIdentifier(values[pair.getRight()], pair.getLeft(), schema);
@@ -738,7 +738,7 @@ public class ColorSchemaReader {
       if (schema.getCompartments().size() > 0) {
         result.add(ColorSchemaColumn.COMPARTMENT);
       }
-      if (schema.getGeneralIdentifier() != null || schema.getIdentifierColumns().size() > 0) {
+      if (schema.getMiriamData().size() > 0) {
         result.add(ColorSchemaColumn.IDENTIFIER);
       }
       if (schema.getLineWidth() != null) {
diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java
index 12a4f24bb4..c3df713257 100644
--- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java
+++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java
@@ -12,7 +12,6 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.Cell;
@@ -28,6 +27,7 @@ import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.Pair;
 import lcsb.mapviewer.common.geometry.ColorParser;
 import lcsb.mapviewer.converter.model.celldesigner.species.SpeciesMapping;
+import lcsb.mapviewer.model.map.MiriamData;
 import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 import lcsb.mapviewer.model.map.layout.GenericColorSchema;
@@ -257,7 +257,7 @@ public class ColorSchemaXlsxReader {
               MiriamConnector miriamConnector = new MiriamConnector();
               String value = cell.getStringCellValue().trim();
               if (miriamConnector.isValidIdentifier(value)) {
-                schema.setGeneralIdentifier(value);
+                schema.addMiriamData(MiriamType.getMiriamDataFromIdentifier(value));
               } else {
                 throw new InvalidColorSchemaException("[Line " + lineIndex + "]" + " Invalid identifier: " + value);
               }
@@ -266,7 +266,7 @@ public class ColorSchemaXlsxReader {
           for (Pair<MiriamType, Integer> pair : foundCustomIdentifiers) {
             cell = row.getCell(pair.getRight());
             if (cell != null) {
-              schema.addIdentifierColumn(new Pair<MiriamType, String>(pair.getLeft(), cell.getStringCellValue()));
+              schema.addMiriamData(new MiriamData(pair.getLeft(), cell.getStringCellValue()));
             }
           }
 
@@ -275,7 +275,7 @@ public class ColorSchemaXlsxReader {
             throw new InvalidColorSchemaException("Value or Color is needed not both");
           }
 
-          if (schema.getName() == null && schema.getGeneralIdentifier() == null && foundCustomIdentifiers.size() == 0
+          if (schema.getName() == null && schema.getMiriamData().size() == 0 && foundCustomIdentifiers.size() == 0
               && schema.getElementId() == null) {
             throw new InvalidColorSchemaException(
                 "One of these columns values is obligatory: name, identifier, reactionIdentifier");
@@ -316,7 +316,7 @@ public class ColorSchemaXlsxReader {
       if (schema.getCompartments().size() > 0) {
         result.add(ColorSchemaColumn.COMPARTMENT);
       }
-      if (schema.getGeneralIdentifier() != null || schema.getIdentifierColumns().size() > 0) {
+      if (schema.getMiriamData().size() > 0) {
         result.add(ColorSchemaColumn.IDENTIFIER);
       }
       if (schema.getLineWidth() != null) {
diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java b/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java
index 1bf9bb3ab4..ef9c4ddf5b 100644
--- a/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java
+++ b/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java
@@ -66,7 +66,7 @@ public class LayoutServiceTest2 {
       ColorSchema cs = new GenericColorSchema();
       cs.setColor(Color.CYAN);
       cs.addCompartment("BLA");
-      cs.addIdentifierColumn(new Pair<MiriamType, String>(MiriamType.CAS, "CAS_ID"));
+      cs.addMiriamData(new MiriamData(MiriamType.CAS, "CAS_ID"));
       cs.setLineWidth(3.3);
       cs.setMatches(2);
       cs.setName("UUU");
@@ -105,7 +105,7 @@ public class LayoutServiceTest2 {
       GeneVariationColorSchema cs = new GeneVariationColorSchema();
       cs.setColor(Color.CYAN);
       cs.addCompartment("BLA");
-      cs.addIdentifierColumn(new Pair<MiriamType, String>(MiriamType.CAS, "CAS_ID"));
+      cs.addMiriamData(new MiriamData(MiriamType.CAS, "CAS_ID"));
       cs.setLineWidth(3.3);
       cs.setMatches(2);
       cs.setName("UUU");
diff --git a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java
index d5cc32a208..671877a0c7 100644
--- a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java
+++ b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java
@@ -26,6 +26,7 @@ import lcsb.mapviewer.commands.ColorExtractor;
 import lcsb.mapviewer.commands.ColorModelCommand;
 import lcsb.mapviewer.common.Pair;
 import lcsb.mapviewer.common.TextFileUtils;
+import lcsb.mapviewer.model.map.MiriamData;
 import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException;
@@ -322,9 +323,9 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions {
 
       Collection<ColorSchema> schemas = reader.readColorSchema("testFiles/coloring/schemaWithIdentifiers.txt");
       for (ColorSchema colorSchema : schemas) {
-        for (Pair<MiriamType, String> pair : colorSchema.getIdentifierColumns()) {
-          assertNotNull(pair.getRight());
-          assertFalse(pair.getRight().isEmpty());
+        for (MiriamData md: colorSchema.getMiriamData()) {
+          assertNotNull(md.getResource());
+          assertFalse(md.getResource().isEmpty());
         }
       }
 
@@ -341,8 +342,8 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions {
 
       Collection<ColorSchema> schemas = reader.readColorSchema("testFiles/coloring/schemaIdWithoutName.txt");
       for (ColorSchema colorSchema : schemas) {
-        for (Pair<MiriamType, String> pair : colorSchema.getIdentifierColumns()) {
-          assertFalse(pair.getRight().isEmpty());
+        for (MiriamData md: colorSchema.getMiriamData()) {
+          assertFalse(md.getResource().isEmpty());
           assertNull(colorSchema.getName());
         }
       }
-- 
GitLab