
org.pathvisio.libgpml.model.GPML2013aFormatAbstract Maven / Gradle / Ivy
/*******************************************************************************
* PathVisio, a tool for data visualization and analysis using biological pathways
* Copyright 2006-2022 BiGCaT Bioinformatics, WikiPathways
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package org.pathvisio.libgpml.model;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
import org.bridgedb.DataSource;
import org.bridgedb.Xref;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.pathvisio.libgpml.io.ConverterException;
import org.pathvisio.libgpml.model.type.ShapeType;
import org.pathvisio.libgpml.model.type.ArrowHeadType;
import org.pathvisio.libgpml.util.ColorUtils;
import org.pathvisio.libgpml.util.Utils;
/**
* Abstract class for GPML2013a format. Contains static properties and methods
* used in reading or writing GPML2013a.
*
* @author finterly
*/
public abstract class GPML2013aFormatAbstract extends GPMLFormatAbstract {
/**
* Constructor for GPML2013aFormat Abstract.
*
* @param xsdFile the schema file.
* @param nsGPML the GPML namespace.
*/
protected GPML2013aFormatAbstract(String xsdFile, Namespace nsGPML) {
super(xsdFile, nsGPML);
}
// ================================================================================
// Static Variables
// ================================================================================
/**
* In GPML2013a, specific {@link Namespace} are defined for Biopax elements.
*/
public static final Namespace RDF_NAMESPACE = Namespace.getNamespace("rdf",
"http://www.w3.org/1999/02/22-rdf-syntax-ns#");
public static final Namespace RDFS_NAMESPACE = Namespace.getNamespace("rdfs",
"http://www.w3.org/2000/01/rdf-schema#");
public static final Namespace BIOPAX_NAMESPACE = Namespace.getNamespace("bp",
"http://www.biopax.org/release/biopax-level3.owl#");
public static final Namespace OWL_NAMESPACE = Namespace.getNamespace("owl", "http://www.w3.org/2002/07/owl#");
public final static String RDF_STRING = "http://www.w3.org/2001/XMLSchema#string";
/**
* Some GPML2013a properties are removed from GPML2021 and therefore cannot be
* mapped to the Java model. These deprecated properties are stored in dynamic
* properties with the following static strings as keys.
*/
public final static String PATHWAY_AUTHOR = "pathway_author_gpml2013a";
public final static String PATHWAY_MAINTAINER = "pathway_maintainer_gpml2013a";
public final static String PATHWAY_EMAIL = "pathway_email_gpml2013a";
public final static String PATHWAY_LASTMODIFIED = "pathway_lastModified_gpml2013a";
public final static String INFOBOX_CENTER_X = "pathway_infobox_centerX_gpml2013a";
public final static String INFOBOX_CENTER_Y = "pathway_infobox_centerY_gpml2013a";
public final static String LEGEND_CENTER_X = "pathway_legend_centerX_gpml2013a";
public final static String LEGEND_CENTER_Y = "pathway_legend_centerY_gpml2013a";
/**
* This {@link Set} stores the deprecated GPML2013a properties. Dynamic
* properties with these keys are ignored when writing GPML2013a
* {@link GPML2013aWriter#writePathwayDynamicProperties} and GPML2021
* {@link GPML2021Writer#writeDynamicProperties}.
*/
public static final Set GPML2013A_KEY_SET = new HashSet<>(Arrays.asList(PATHWAY_AUTHOR, PATHWAY_MAINTAINER,
PATHWAY_EMAIL, PATHWAY_LASTMODIFIED, INFOBOX_CENTER_X, INFOBOX_CENTER_Y, LEGEND_CENTER_X, LEGEND_CENTER_Y));
/**
* In GPML2013a, {@link Pathway} description is written as a
* {@link PathwayElement.Comment} with source="WikiPathways-description".
*/
public final static String WP_DESCRIPTION = "WikiPathways-description";
/**
* In GPML2013a, Double LineStyleType, Cellular Component Shape Types, and State
* rotation were stored as a dynamic properties using the following String keys.
*/
public final static String DOUBLE_LINE_KEY = "org.pathvisio.DoubleLineProperty";
public final static String CELL_CMPNT_KEY = "org.pathvisio.CellularComponentProperty";
public final static String STATE_ROTATION = "org.pathvisio.core.StateRotation";
/**
* This {@link BidiMap}is used for mapping {@link ShapeType} Strings to their
* new camelCase spelling for reading and writing GPML2013a.
*/
public static final BidiMap SHAPETYPE_TO_CAMELCASE = new DualHashBidiMap<>();
static {
SHAPETYPE_TO_CAMELCASE.put("Sarcoplasmic Reticulum", "SarcoplasmicReticulum");
SHAPETYPE_TO_CAMELCASE.put("Endoplasmic Reticulum", "EndoplasmicReticulum");
SHAPETYPE_TO_CAMELCASE.put("Golgi Apparatus", "GolgiApparatus");
SHAPETYPE_TO_CAMELCASE.put("Cytosol region", "CytosolRegion");
SHAPETYPE_TO_CAMELCASE.put("Extracellular region", "ExtracellularRegion");
SHAPETYPE_TO_CAMELCASE.put("Membrane region", "MembraneRegion");
}
/**
* Converts shapeType {@link String} to UpperCamelCase convention. In GPML2013a,
* naming convention was inconsistent. Moving forward, enum types strings are
* all in UpperCamelCase.
*
* @param str the string.
* @return the string in camelCase format, or string as it was.
* @throws ConverterException
*/
protected String toCamelCase(String str) throws ConverterException {
if (SHAPETYPE_TO_CAMELCASE.containsKey(str)) {
return SHAPETYPE_TO_CAMELCASE.get(str);
} else
return str;
}
/**
* Converts shapeType {@link String} from UpperCamelCase convention back to its
* original appearance in GPML2013a.
*
* @param str the string.
* @return the string in its original format.
* @throws ConverterException
*/
protected String fromCamelCase(String str) throws ConverterException {
if (SHAPETYPE_TO_CAMELCASE.containsValue(str)) {
return SHAPETYPE_TO_CAMELCASE.getKey(str);
} else
return str;
}
/**
* This {@link Map} maps deprecated {@link String} to the new {@link ShapeType}
* when reading GPML2013a {@link GPML2013aReader#readShapeStyleProperty}.
*
* NB: for mim-degradation
*/
public static final BidiMap DEPRECATED_MAP = new DualHashBidiMap();
static {
DEPRECATED_MAP.put("mim-degradation", ShapeType.DEGRADATION);
}
/**
* This cellular component {@link Map} maps {@link ShapeType}s. In GPML2013a,
* cellular component shapeTypes are written as dynamic properties
* {@link GPML2013aWriter#writeShapedOrStateDynamicProperties} with
* {@link #CELL_CMPNT_KEY} key and a value (e.g. "Nucleus); and property
* shapeType in Graphics is written with a corresponding shapeType value (e.g.
* "Oval") {@link GPML2013aWriter#writeShapeStyleProperty}.
*/
public static final Map CELL_CMPNT_MAP = new HashMap();
static {
CELL_CMPNT_MAP.put(ShapeType.CELL, ShapeType.ROUNDED_RECTANGLE);
CELL_CMPNT_MAP.put(ShapeType.NUCLEUS, ShapeType.OVAL);
CELL_CMPNT_MAP.put(ShapeType.ENDOPLASMIC_RETICULUM, ShapeType.ENDOPLASMIC_RETICULUM);
CELL_CMPNT_MAP.put(ShapeType.GOLGI_APPARATUS, ShapeType.GOLGI_APPARATUS);
CELL_CMPNT_MAP.put(ShapeType.MITOCHONDRIA, ShapeType.MITOCHONDRIA);
CELL_CMPNT_MAP.put(ShapeType.SARCOPLASMIC_RETICULUM, ShapeType.SARCOPLASMIC_RETICULUM);
CELL_CMPNT_MAP.put(ShapeType.ORGANELLE, ShapeType.ROUNDED_RECTANGLE);
CELL_CMPNT_MAP.put(ShapeType.VESICLE, ShapeType.OVAL);
CELL_CMPNT_MAP.put(ShapeType.EXTRACELLULAR_REGION, ShapeType.ROUNDED_RECTANGLE);
}
/**
* This {@link BidiMap} maps GPML2013a openControlledVocabulary Ontology types
* to their {@link DataSource} Prefix for reading
* {@link GPML2013aReader#readOpenControlledVocabulary} and writing
* {@link GPML2013aWriter#writeOpenControlledVocabulary}.
*/
public static final BidiMap OCV_ONTOLOGY_MAP = new DualHashBidiMap<>();
static {
OCV_ONTOLOGY_MAP.put("Disease", "DOID");
OCV_ONTOLOGY_MAP.put("Pathway Ontology", "PW");
OCV_ONTOLOGY_MAP.put("Cell Type", "CL");
}
/**
* String values for {@link DataNode.State} phosphosite
* {@link PathwayElement.Comment} information in GPML2013a.
*/
public final static String PARENT = "parent";
public final static String POSITION = "position";
public final static String PARENTID = "parentid";
public final static String PARENTSYMBOL = "parentsymbol";
public final static String PTM = "ptm";
public final static String DIRECTION = "direction";
public final static String SITE = "site";
public final static String SITEGRPID = "sitegrpid";
public final static String PARENTID_DB = "uniprot";
public final static String PARENTSYMBOL_DB = "hgnc";
public final static String SITEGRPID_DB = "phosphositeplus";
/**
* This {@link Set} contains known phosphosite related annotation types for
* {@link DataNode.State} phosphosite {@link PathwayElement.Comment} in
* GPML2013a. This set is used in determining whether a state comment should be
* written as {@link Annotation}s and {@link Xref} in
* {@link GPML2013aReader#convertStateCommentToRefs}.
*/
Set STATE_REF_LIST = new HashSet<>(
Arrays.asList(PARENT, POSITION, PTM, DIRECTION, PARENTID, PARENTSYMBOL, SITE, SITEGRPID));
/**
* This {@link Map} for {@link DataNode.State} phosphosite
* {@link PathwayElement.Comment} maps PTM character to {@link Annotation} and
* {@link Xref} information. E.g. for ptm=p, Annotation value=Phosphorylation,
* Xref identifier=0000216, and dataSource = SBO. Used in writing state comments
* to annotations and xref {@link GPML2013aReader#convertStateCommentToRefs}.
*/
public static final Map> STATE_PTM_MAP = new HashMap>();
static {
STATE_PTM_MAP.put("p", new ArrayList<>(Arrays.asList("Phosphorylation", "0000216", "SBO")));
STATE_PTM_MAP.put("m", new ArrayList<>(Arrays.asList("Methylation", "0000214", "SBO")));
STATE_PTM_MAP.put("me", new ArrayList<>(Arrays.asList("Methylation", "0000214", "SBO")));
STATE_PTM_MAP.put("u", new ArrayList<>(Arrays.asList("Ubiquitination", "000022", "SBO")));
STATE_PTM_MAP.put("ub", new ArrayList<>(Arrays.asList("Ubiquitination", "000022", "SBO")));
}
/**
* Map for {@link DataNode.State} phosphosite {@link PathwayElement.Comment}
* direction character to {@link Annotation} and {@link Xref} information. "u"
* for up-regulated and "d" for down-regulated. Used in writing state comments
* to annotations and xref {@link GPML2013aReader#convertStateCommentToRefs}.
*/
public static final Map> STATE_DIRECTION_MAP = new HashMap>();
static {
STATE_DIRECTION_MAP.put("u",
new ArrayList<>(Arrays.asList("positive regulation of biological process", "0048518", "GO")));
STATE_DIRECTION_MAP.put("d",
new ArrayList<>(Arrays.asList("negative regulation of biological process", "0048519", "GO")));
}
/**
* In GPML2013a, we introduce a new Interaction Panel of {@link ArrowHeadType}.
* For each new arrowHead type we define a {@link List} of the old arrowHead
* types from GPML2013a which correspond to it. The first GPML2013a arrow head
* type string in the list is prioritized when writing from GPML2021 to
* GPML2013a.
*/
public static final List UNDIRECTED_LIST = new ArrayList<>(Arrays.asList("Line"));
public static final List DIRECTED_LIST = new ArrayList<>(Arrays.asList("Arrow"));
public static final List CONVERSION_LIST = new ArrayList<>(Arrays.asList("mim-conversion",
"mim-modification", "mim-cleavage", "mim-gap", "mim-branching-left", "mim-branching-right"));
public static final List INHIBITION_LIST = new ArrayList<>(Arrays.asList("mim-inhibition", "TBar"));
public static final List CATALYSIS_LIST = new ArrayList<>(Arrays.asList("mim-catalysis"));
public static final List STIMULATION_LIST = new ArrayList<>(
Arrays.asList("mim-stimulation", "mim-necessary-stimulation"));
public static final List BINDING_LIST = new ArrayList<>(Arrays.asList("mim-binding", "mim-covalent-bond"));
public static final List TRANSLOCATION_LIST = new ArrayList<>(Arrays.asList("mim-translocation"));
public static final List TRANSCRIPTION_TRANSLATION_LIST = new ArrayList<>(
Arrays.asList("mim-transcription-translation"));
/**
* This {@link Map} maps new Interaction Panel arrow head types to the defined
* {@link List} for corresponding GPML2013a arrowHead types.
*/
public static final Map> IA_PANEL_MAP = new HashMap>();
static {
IA_PANEL_MAP.put(ArrowHeadType.UNDIRECTED, UNDIRECTED_LIST);
IA_PANEL_MAP.put(ArrowHeadType.DIRECTED, DIRECTED_LIST);
IA_PANEL_MAP.put(ArrowHeadType.CONVERSION, CONVERSION_LIST);
IA_PANEL_MAP.put(ArrowHeadType.INHIBITION, INHIBITION_LIST);
IA_PANEL_MAP.put(ArrowHeadType.CATALYSIS, CATALYSIS_LIST);
IA_PANEL_MAP.put(ArrowHeadType.STIMULATION, STIMULATION_LIST);
IA_PANEL_MAP.put(ArrowHeadType.BINDING, BINDING_LIST);
IA_PANEL_MAP.put(ArrowHeadType.TRANSLOCATION, TRANSLOCATION_LIST);
IA_PANEL_MAP.put(ArrowHeadType.TRANSCRIPTION_TRANSLATION, TRANSCRIPTION_TRANSLATION_LIST);
}
/**
* Returns the GPML2021 Interaction Panel arrow head type for given GPML2013a
* arrowHead type string.
*
* @param arrowHeadStr the string for GPML2013a arrow head type.
* @return arrowHead the interaction panel arrow head type which corresponds to
* arrowHeadStr, or null if no corresponding type exists.
* @throws ConverterException
*/
protected ArrowHeadType getInteractionPanelType(String arrowHeadStr) throws ConverterException {
Set arrowHeads = IA_PANEL_MAP.keySet();
for (ArrowHeadType arrowHead : arrowHeads) {
List arrowHeadStrs = IA_PANEL_MAP.get(arrowHead);
// case insensitive method for matching in list
if (Utils.containsCaseInsensitive(arrowHeadStr, arrowHeadStrs)) {
return arrowHead;
}
}
return null;
}
/**
* Returns the prioritized GPML2013a arrowHead type string for given GPML2021
* Interaction Panel arrow head type.
*
* @param arrowHead the interaction panel arrow head type for GPML2021e.
* @return the first GPML2013a arrow head which corresponds to the interaction
* panel arrow head type, or null if no corresponding type exists.
* @throws ConverterException
*/
protected String getArrowHeadTypeStr(ArrowHeadType arrowHead) throws ConverterException {
List arrowHeadStrs = IA_PANEL_MAP.get(arrowHead);
if (arrowHeadStrs != null && !arrowHeadStrs.isEmpty()) {
// first arrow head string is priority.
return arrowHeadStrs.get(0);
} else {
return null;
}
}
/**
* Attribute info map is initiated with {@link #initAttributeInfo()}.
*
*/
private static final Map ATTRIBUTE_INFO = initAttributeInfo();
/**
* The {@link Map} initAttributeInfo maps {@link String} tag to
* {@link AttributeInfo}. For GPML2013a reading/writing, we often use
* {@link #getAttr} and {@link #setAttr} in place of standard jdom methods
* {@link Element#getAttributeValue} and {@link Element#setAttribute}
* respectively. If an attribute is null when reading, its default value is
* fetched from this map. When writing, if trying to set a default value or an
* optional value to null, the attribute is omitted which results in a leaner
* xml output.
*
* This map defines custom default values not in the GPML2013a schema such as
* default "Label.Graphics@FillColor" as "Transparent". We do not do this for
* GPML2021 as it can be confusing to have custom reading/writing resulting in
* xml which do not adhere to the schema.
*
* @return
*/
private static Map initAttributeInfo() {
Map result = new HashMap();
result.put("Comment@Source", new AttributeInfo("xsd:string", null, "optional"));
result.put("PublicationXref@ID", new AttributeInfo("xsd:string", null, "required"));
result.put("PublicationXref@Database", new AttributeInfo("xsd:string", null, "required"));
result.put("Attribute@Key", new AttributeInfo("xsd:string", null, "required"));
result.put("Attribute@Value", new AttributeInfo("xsd:string", null, "required"));
result.put("Pathway.Graphics@BoardWidth", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("Pathway.Graphics@BoardHeight", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("Pathway@Name", new AttributeInfo("xsd:string", null, "required"));
result.put("Pathway@Organism", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@Data-Source", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@Version", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@Author", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@Maintainer", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@Email", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@License", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@Last-Modified", new AttributeInfo("xsd:string", null, "optional"));
result.put("Pathway@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("DataNode.Graphics@CenterX", new AttributeInfo("xsd:float", null, "required"));
result.put("DataNode.Graphics@CenterY", new AttributeInfo("xsd:float", null, "required"));
result.put("DataNode.Graphics@Width", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("DataNode.Graphics@Height", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("DataNode.Graphics@FontName", new AttributeInfo("xsd:string", "Arial", "optional"));
result.put("DataNode.Graphics@FontStyle", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("DataNode.Graphics@FontDecoration", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("DataNode.Graphics@FontStrikethru", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("DataNode.Graphics@FontWeight", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("DataNode.Graphics@FontSize", new AttributeInfo("xsd:nonNegativeInteger", "12", "optional"));
result.put("DataNode.Graphics@Align", new AttributeInfo("xsd:string", "Center", "optional"));
result.put("DataNode.Graphics@Valign", new AttributeInfo("xsd:string", "Top", "optional"));
result.put("DataNode.Graphics@Color", new AttributeInfo("gpml:ColorType", "Black", "optional"));
result.put("DataNode.Graphics@LineStyle", new AttributeInfo("gpml:StyleType", "Solid", "optional"));
result.put("DataNode.Graphics@LineThickness", new AttributeInfo("xsd:float", "1.0", "optional"));
result.put("DataNode.Graphics@FillColor", new AttributeInfo("gpml:ColorType", "White", "optional"));
result.put("DataNode.Graphics@ShapeType", new AttributeInfo("xsd:string", "Rectangle", "optional"));
result.put("DataNode.Graphics@ZOrder", new AttributeInfo("xsd:integer", null, "optional"));
result.put("DataNode.Xref@Database", new AttributeInfo("xsd:string", null, "required"));
result.put("DataNode.Xref@ID", new AttributeInfo("xsd:string", null, "required"));
result.put("DataNode@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("DataNode@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("DataNode@GroupRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("DataNode@TextLabel", new AttributeInfo("xsd:string", null, "required"));
result.put("DataNode@Type", new AttributeInfo("xsd:string", "Unknown", "optional"));
result.put("State.Graphics@RelX", new AttributeInfo("xsd:float", null, "required"));
result.put("State.Graphics@RelY", new AttributeInfo("xsd:float", null, "required"));
result.put("State.Graphics@Width", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("State.Graphics@Height", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("State.Graphics@Color", new AttributeInfo("gpml:ColorType", "Black", "optional"));
result.put("State.Graphics@LineStyle", new AttributeInfo("gpml:StyleType", "Solid", "optional"));
result.put("State.Graphics@LineThickness", new AttributeInfo("xsd:float", "1.0", "optional"));
result.put("State.Graphics@FillColor", new AttributeInfo("gpml:ColorType", "White", "optional"));
result.put("State.Graphics@ShapeType", new AttributeInfo("xsd:string", "Rectangle", "optional"));
result.put("State.Graphics@ZOrder", new AttributeInfo("xsd:integer", null, "optional"));
result.put("State.Xref@Database", new AttributeInfo("xsd:string", null, "required"));
result.put("State.Xref@ID", new AttributeInfo("xsd:string", null, "required"));
result.put("State@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("State@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("State@GraphRef", new AttributeInfo("xsd:IDREF", null, "optional"));
result.put("State@TextLabel", new AttributeInfo("xsd:string", null, "required"));
result.put("State@StateType", new AttributeInfo("xsd:string", "Unknown", "optional"));
result.put("GraphicalLine.Graphics.Point@X", new AttributeInfo("xsd:float", null, "required"));
result.put("GraphicalLine.Graphics.Point@Y", new AttributeInfo("xsd:float", null, "required"));
result.put("GraphicalLine.Graphics.Point@RelX", new AttributeInfo("xsd:float", null, "optional"));
result.put("GraphicalLine.Graphics.Point@RelY", new AttributeInfo("xsd:float", null, "optional"));
result.put("GraphicalLine.Graphics.Point@GraphRef", new AttributeInfo("xsd:IDREF", null, "optional"));
result.put("GraphicalLine.Graphics.Point@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("GraphicalLine.Graphics.Point@ArrowHead", new AttributeInfo("xsd:string", "Line", "optional"));
result.put("GraphicalLine.Graphics.Anchor@Position", new AttributeInfo("xsd:float", null, "required"));
result.put("GraphicalLine.Graphics.Anchor@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("GraphicalLine.Graphics.Anchor@Shape", new AttributeInfo("xsd:string", "ReceptorRound", "optional"));
result.put("GraphicalLine.Graphics@Color", new AttributeInfo("gpml:ColorType", "Black", "optional"));
result.put("GraphicalLine.Graphics@LineThickness", new AttributeInfo("xsd:float", null, "optional"));
result.put("GraphicalLine.Graphics@LineStyle", new AttributeInfo("gpml:StyleType", "Solid", "optional"));
result.put("GraphicalLine.Graphics@ConnectorType", new AttributeInfo("xsd:string", "Straight", "optional"));
result.put("GraphicalLine.Graphics@ZOrder", new AttributeInfo("xsd:integer", null, "optional"));
result.put("GraphicalLine@GroupRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("GraphicalLine@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("GraphicalLine@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("GraphicalLine@Type", new AttributeInfo("xsd:string", null, "optional"));
result.put("Interaction.Graphics.Point@X", new AttributeInfo("xsd:float", null, "required"));
result.put("Interaction.Graphics.Point@Y", new AttributeInfo("xsd:float", null, "required"));
result.put("Interaction.Graphics.Point@RelX", new AttributeInfo("xsd:float", null, "optional"));
result.put("Interaction.Graphics.Point@RelY", new AttributeInfo("xsd:float", null, "optional"));
result.put("Interaction.Graphics.Point@GraphRef", new AttributeInfo("xsd:IDREF", null, "optional"));
result.put("Interaction.Graphics.Point@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("Interaction.Graphics.Point@ArrowHead", new AttributeInfo("xsd:string", "Line", "optional"));
result.put("Interaction.Graphics.Anchor@Position", new AttributeInfo("xsd:float", null, "required"));
result.put("Interaction.Graphics.Anchor@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("Interaction.Graphics.Anchor@Shape", new AttributeInfo("xsd:string", "ReceptorRound", "optional"));
result.put("Interaction.Graphics@Color", new AttributeInfo("gpml:ColorType", "Black", "optional"));
result.put("Interaction.Graphics@LineThickness", new AttributeInfo("xsd:float", null, "optional"));
result.put("Interaction.Graphics@LineStyle", new AttributeInfo("gpml:StyleType", "Solid", "optional"));
result.put("Interaction.Graphics@ConnectorType", new AttributeInfo("xsd:string", "Straight", "optional"));
result.put("Interaction.Graphics@ZOrder", new AttributeInfo("xsd:integer", null, "optional"));
result.put("Interaction.Xref@Database", new AttributeInfo("xsd:string", null, "required"));
result.put("Interaction.Xref@ID", new AttributeInfo("xsd:string", null, "required"));
result.put("Interaction@GroupRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Interaction@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Interaction@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("Interaction@Type", new AttributeInfo("xsd:string", null, "optional"));
result.put("Label.Graphics@CenterX", new AttributeInfo("xsd:float", null, "required"));
result.put("Label.Graphics@CenterY", new AttributeInfo("xsd:float", null, "required"));
result.put("Label.Graphics@Width", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("Label.Graphics@Height", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("Label.Graphics@FontName", new AttributeInfo("xsd:string", "Arial", "optional"));
result.put("Label.Graphics@FontStyle", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Label.Graphics@FontDecoration", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Label.Graphics@FontStrikethru", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Label.Graphics@FontWeight", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Label.Graphics@FontSize", new AttributeInfo("xsd:nonNegativeInteger", "12", "optional"));
result.put("Label.Graphics@Align", new AttributeInfo("xsd:string", "Center", "optional"));
result.put("Label.Graphics@Valign", new AttributeInfo("xsd:string", "Top", "optional"));
result.put("Label.Graphics@Color", new AttributeInfo("gpml:ColorType", "Black", "optional"));
result.put("Label.Graphics@LineStyle", new AttributeInfo("gpml:StyleType", "Solid", "optional"));
result.put("Label.Graphics@LineThickness", new AttributeInfo("xsd:float", "1.0", "optional"));
result.put("Label.Graphics@FillColor", new AttributeInfo("gpml:ColorType", "Transparent", "optional"));
result.put("Label.Graphics@ShapeType", new AttributeInfo("xsd:string", "None", "optional"));
result.put("Label.Graphics@ZOrder", new AttributeInfo("xsd:integer", null, "optional"));
result.put("Label@Href", new AttributeInfo("xsd:string", null, "optional"));
result.put("Label@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Label@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("Label@GroupRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Label@TextLabel", new AttributeInfo("xsd:string", null, "required"));
result.put("Shape.Graphics@CenterX", new AttributeInfo("xsd:float", null, "required"));
result.put("Shape.Graphics@CenterY", new AttributeInfo("xsd:float", null, "required"));
result.put("Shape.Graphics@Width", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("Shape.Graphics@Height", new AttributeInfo("gpml:Dimension", null, "required"));
result.put("Shape.Graphics@FontName", new AttributeInfo("xsd:string", "Arial", "optional"));
result.put("Shape.Graphics@FontStyle", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Shape.Graphics@FontDecoration", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Shape.Graphics@FontStrikethru", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Shape.Graphics@FontWeight", new AttributeInfo("xsd:string", "Normal", "optional"));
result.put("Shape.Graphics@FontSize", new AttributeInfo("xsd:nonNegativeInteger", "12", "optional"));
result.put("Shape.Graphics@Align", new AttributeInfo("xsd:string", "Center", "optional"));
result.put("Shape.Graphics@Valign", new AttributeInfo("xsd:string", "Top", "optional"));
result.put("Shape.Graphics@Color", new AttributeInfo("gpml:ColorType", "Black", "optional"));
result.put("Shape.Graphics@LineStyle", new AttributeInfo("gpml:StyleType", "Solid", "optional"));
result.put("Shape.Graphics@LineThickness", new AttributeInfo("xsd:float", "1.0", "optional"));
result.put("Shape.Graphics@FillColor", new AttributeInfo("gpml:ColorType", "Transparent", "optional"));
result.put("Shape.Graphics@ShapeType", new AttributeInfo("xsd:string", null, "required"));
result.put("Shape.Graphics@ZOrder", new AttributeInfo("xsd:integer", null, "optional"));
result.put("Shape.Graphics@Rotation", new AttributeInfo("gpml:RotationType", "Top", "optional"));
result.put("Shape@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Shape@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("Shape@GroupRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Shape@TextLabel", new AttributeInfo("xsd:string", null, "optional"));
result.put("Group@BiopaxRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Group@GroupId", new AttributeInfo("xsd:string", null, "required"));
result.put("Group@GroupRef", new AttributeInfo("xsd:string", null, "optional"));
result.put("Group@Style", new AttributeInfo("xsd:string", "None", "optional"));
result.put("Group@TextLabel", new AttributeInfo("xsd:string", null, "optional"));
result.put("Group@GraphId", new AttributeInfo("xsd:ID", null, "optional"));
result.put("InfoBox@CenterX", new AttributeInfo("xsd:float", null, "required"));
result.put("InfoBox@CenterY", new AttributeInfo("xsd:float", null, "required"));
result.put("Legend@CenterX", new AttributeInfo("xsd:float", null, "required"));
result.put("Legend@CenterY", new AttributeInfo("xsd:float", null, "required"));
return result;
}
/**
* Returns {@link Map} ATTRIBUTE_INFO collection that contains {@link String} as
* key and {@link AttributeInfo} as value.
*/
protected Map getAttributeInfo() {
return ATTRIBUTE_INFO;
}
/**
* Name of resource containing the gpml schema definition.
*/
protected static class AttributeInfo {
/**
* xsd validated type. Note that in the current implementation we don't do
* anything with restrictions, only with the base type.
*/
public String schemaType;
/**
* default value for the attribute
*/
public String def; // default
/**
* use of the attribute: can be "required" or "optional"
*/
public String use;
/**
* Creates an object containing the gpml schema definition of a given attribute.
*
* @param aSchemaType the xsd validated type of the attribute.
* @param aDef the default value for the attribute.
* @param aUse the use of the attribute.
*/
AttributeInfo(String aSchemaType, String aDef, String aUse) {
schemaType = aSchemaType;
def = aDef;
use = aUse;
}
}
/**
* Returns true if given string value and default value are equal.
*
* @param def the default string.
* @param value the given string.
* @return true if the specified arguments are equal, or both null.
*/
private boolean isEqualsString(String def, String value) {
return ((def == null && value == null) || (def != null && def.equals(value))
|| (def == null && value != null && value.equals("")));
}
/**
* Returns true if given string value and default value are numerically equal.
*
* @param def the string for default number value.
* @param value the string for given number value.
* @return true if absolute value of difference between def and value is less
* than 1e-6, and false otherwise.
*/
private boolean isEqualsNumber(String def, String value) {
if (def != null && value != null) {
Double x = Double.parseDouble(def);
Double y = Double.parseDouble(value);
if (Math.abs(x - y) < 1e-6)
return true;
}
return false;
}
/**
* Returns true if given value and default value are the same color object.
*
* @param def the string for default color object.
* @param value the string for given color object.
* @return true if color is equal, false otherwise.
*/
private boolean isEqualsColor(String def, String value) {
if (def != null && value != null) {
boolean aTrans = "Transparent".equals(def);
boolean bTrans = "Transparent".equals(value);
Color a = ColorUtils.stringToColor(def);
Color b = ColorUtils.stringToColor(value);
return (a.equals(b) && aTrans == bTrans);
}
return def == null && value == null;
}
/**
* Sets a certain attribute value, performs a basic check for some types, and
* throws an exception if trying to set an invalid value. If trying to set a
* default value or an optional value to null, the attribute is omitted, which
* results in a leaner xml output. This customized method is often used in place
* of {@link Element#setAttribute} for writing GPML2013a.
*
* @param tag used for lookup in the defaults table.
* @param name used for lookup in the defaults table.
* @param el jdom element where this attribute belongs in.
* @param value value you want to check and set.
* @throws ConverterException if value invalid.
*/
protected void setAttr(String tag, String name, Element el, String value) throws ConverterException {
String key = tag + "@" + name;
// throw exception for value invalid
if (!getAttributeInfo().containsKey(key))
throw new ConverterException("Trying to set invalid attribute " + key);
AttributeInfo aInfo = getAttributeInfo().get(key);
boolean isDefault = false;
// if attribute equal to the default value, leave out from the jdom
if (aInfo.use.equals("optional")) {
if (aInfo.schemaType.equals("xsd:string") || aInfo.schemaType.equals("xsd:ID")
|| aInfo.schemaType.equals("gpml:StyleType")) {
isDefault = isEqualsString(aInfo.def, value);
} else if (aInfo.schemaType.equals("xsd:float") || aInfo.schemaType.equals("Dimension")) {
isDefault = isEqualsNumber(aInfo.def, value);
} else if (aInfo.schemaType.equals("gpml:ColorType")) {
isDefault = isEqualsColor(aInfo.def, value);
}
}
if (!isDefault)
el.setAttribute(name, value);
}
/**
* Gets a certain attribute value, and replaces it with a suitable default under
* certain conditions. This customized method is often used in place of
* {@link Element#getAttributeValue} for reading GPML2013a.
*
* @param tag used for lookup in the defaults table.
* @param name used for lookup in the defaults table.
* @param el jdom element to get the attribute from.
* @throws ConverterException if {@link #getAttributeInfo} does not contain a
* mapping for the specified key.
*/
protected String getAttr(String tag, String name, Element el) throws ConverterException {
String key = tag + "@" + name;
if (!getAttributeInfo().containsKey(key))
throw new ConverterException("Trying to get invalid attribute " + key);
AttributeInfo aInfo = getAttributeInfo().get(key);
String result = ((el == null) ? aInfo.def : el.getAttributeValue(name, aInfo.def));
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy