From 805fc960e7c2d92e1c5222a303c2d65817b04957 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Thu, 14 Dec 2017 15:02:04 +0000 Subject: [PATCH] JAL-2879 save/restore feature sub-attributes in Jalview project --- schemas/jalview.xsd | 5 + src/jalview/gui/Jalview2XML.java | 71 ++- src/jalview/schemabinding/version2/OtherData.java | 336 +++++++------- .../version2/descriptors/OtherDataDescriptor.java | 468 ++++++++++---------- 4 files changed, 486 insertions(+), 394 deletions(-) diff --git a/schemas/jalview.xsd b/schemas/jalview.xsd index f0bd638..d0bdf42 100755 --- a/schemas/jalview.xsd +++ b/schemas/jalview.xsd @@ -559,6 +559,11 @@ + + + key2 may be used for a sub-attribute of key + + diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 4a15024..7a06d08 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -879,15 +879,33 @@ public class Jalview2XML } if (sf.otherDetails != null) { - String key; - Iterator keys = sf.otherDetails.keySet().iterator(); - while (keys.hasNext()) + /* + * save feature attributes, which may be simple strings or + * map valued (have sub-attributes) + */ + for (Entry entry : sf.otherDetails.entrySet()) { - key = keys.next(); - OtherData keyValue = new OtherData(); - keyValue.setKey(key); - keyValue.setValue(sf.otherDetails.get(key).toString()); - features.addOtherData(keyValue); + String key = entry.getKey(); + Object value = entry.getValue(); + if (value instanceof Map) + { + for (Entry subAttribute : ((Map) value) + .entrySet()) + { + OtherData otherData = new OtherData(); + otherData.setKey(key); + otherData.setKey2(subAttribute.getKey()); + otherData.setValue(subAttribute.getValue().toString()); + features.addOtherData(otherData); + } + } + else + { + OtherData otherData = new OtherData(); + otherData.setKey(key); + otherData.setValue(value.toString()); + features.addOtherData(otherData); + } } } @@ -2962,19 +2980,46 @@ public class Jalview2XML features[f].getEnd(), features[f].getScore(), features[f].getFeatureGroup()); sf.setStatus(features[f].getStatus()); + + /* + * load any feature attributes - include map-valued attributes + */ + Map> mapAttributes = new HashMap<>(); for (int od = 0; od < features[f].getOtherDataCount(); od++) { OtherData keyValue = features[f].getOtherData(od); - if (keyValue.getKey().startsWith("LINK")) + String attributeName = keyValue.getKey(); + String attributeValue = keyValue.getValue(); + if (attributeName.startsWith("LINK")) { - sf.addLink(keyValue.getValue()); + sf.addLink(attributeValue); } else { - sf.setValue(keyValue.getKey(), keyValue.getValue()); + String subAttribute = keyValue.getKey2(); + if (subAttribute == null) + { + // simple string-valued attribute + sf.setValue(attributeName, attributeValue); + } + else + { + // attribute 'key' has sub-attribute 'key2' + if (!mapAttributes.containsKey(attributeName)) + { + mapAttributes.put(attributeName, new HashMap<>()); + } + mapAttributes.get(attributeName).put(subAttribute, + attributeValue); + } } - } + for (Entry> mapAttribute : mapAttributes + .entrySet()) + { + sf.setValue(mapAttribute.getKey(), mapAttribute.getValue()); + } + // adds feature to datasequence's feature set (since Jalview 2.10) al.getSequenceAt(i).addSequenceFeature(sf); } @@ -5333,7 +5378,7 @@ public class Jalview2XML if (this.frefedSequence == null) { - frefedSequence = new Vector(); + frefedSequence = new Vector<>(); } viewportsAdded.clear(); diff --git a/src/jalview/schemabinding/version2/OtherData.java b/src/jalview/schemabinding/version2/OtherData.java index fb6b276..31797fe 100644 --- a/src/jalview/schemabinding/version2/OtherData.java +++ b/src/jalview/schemabinding/version2/OtherData.java @@ -7,8 +7,8 @@ package jalview.schemabinding.version2; -//---------------------------------/ -//- Imported classes and packages -/ + //---------------------------------/ + //- Imported classes and packages -/ //---------------------------------/ import org.exolab.castor.xml.Marshaller; @@ -19,163 +19,181 @@ import org.exolab.castor.xml.Unmarshaller; * * @version $Revision$ $Date$ */ -public class OtherData implements java.io.Serializable -{ - - // --------------------------/ - // - Class/Member Variables -/ - // --------------------------/ - - /** - * Field _key. - */ - private java.lang.String _key; - - /** - * Field _value. - */ - private java.lang.String _value; - - // ----------------/ - // - Constructors -/ - // ----------------/ - - public OtherData() - { - super(); - } - - // -----------/ - // - Methods -/ - // -----------/ - - /** - * Returns the value of field 'key'. - * - * @return the value of field 'Key'. - */ - public java.lang.String getKey() - { - return this._key; - } - - /** - * Returns the value of field 'value'. - * - * @return the value of field 'Value'. - */ - public java.lang.String getValue() - { - return this._value; - } - - /** - * Method isValid. - * - * @return true if this object is valid according to the schema - */ - public boolean isValid() - { - try - { - validate(); - } catch (org.exolab.castor.xml.ValidationException vex) - { - return false; +public class OtherData implements java.io.Serializable { + + + //--------------------------/ + //- Class/Member Variables -/ + //--------------------------/ + + /** + * Field _key. + */ + private java.lang.String _key; + + /** + * key2 may be used for a sub-attribute of key + */ + private java.lang.String _key2; + + /** + * Field _value. + */ + private java.lang.String _value; + + + //----------------/ + //- Constructors -/ + //----------------/ + + public OtherData() { + super(); + } + + + //-----------/ + //- Methods -/ + //-----------/ + + /** + * Returns the value of field 'key'. + * + * @return the value of field 'Key'. + */ + public java.lang.String getKey( + ) { + return this._key; + } + + /** + * Returns the value of field 'key2'. The field 'key2' has the + * following description: key2 may be used for a sub-attribute + * of key + * + * @return the value of field 'Key2'. + */ + public java.lang.String getKey2( + ) { + return this._key2; + } + + /** + * Returns the value of field 'value'. + * + * @return the value of field 'Value'. + */ + public java.lang.String getValue( + ) { + return this._value; + } + + /** + * Method isValid. + * + * @return true if this object is valid according to the schema + */ + public boolean isValid( + ) { + try { + validate(); + } catch (org.exolab.castor.xml.ValidationException vex) { + return false; + } + return true; + } + + /** + * + * + * @param out + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + */ + public void marshal( + final java.io.Writer out) + throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + Marshaller.marshal(this, out); + } + + /** + * + * + * @param handler + * @throws java.io.IOException if an IOException occurs during + * marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + */ + public void marshal( + final org.xml.sax.ContentHandler handler) + throws java.io.IOException, org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + Marshaller.marshal(this, handler); + } + + /** + * Sets the value of field 'key'. + * + * @param key the value of field 'key'. + */ + public void setKey( + final java.lang.String key) { + this._key = key; + } + + /** + * Sets the value of field 'key2'. The field 'key2' has the + * following description: key2 may be used for a sub-attribute + * of key + * + * @param key2 the value of field 'key2'. + */ + public void setKey2( + final java.lang.String key2) { + this._key2 = key2; + } + + /** + * Sets the value of field 'value'. + * + * @param value the value of field 'value'. + */ + public void setValue( + final java.lang.String value) { + this._value = value; + } + + /** + * Method unmarshal. + * + * @param reader + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + * @return the unmarshaled + * jalview.schemabinding.version2.OtherData + */ + public static jalview.schemabinding.version2.OtherData unmarshal( + final java.io.Reader reader) + throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + return (jalview.schemabinding.version2.OtherData) Unmarshaller.unmarshal(jalview.schemabinding.version2.OtherData.class, reader); + } + + /** + * + * + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + */ + public void validate( + ) + throws org.exolab.castor.xml.ValidationException { + org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator(); + validator.validate(this); } - return true; - } - - /** - * - * - * @param out - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - */ - public void marshal(final java.io.Writer out) - throws org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - Marshaller.marshal(this, out); - } - - /** - * - * - * @param handler - * @throws java.io.IOException - * if an IOException occurs during marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - */ - public void marshal(final org.xml.sax.ContentHandler handler) - throws java.io.IOException, - org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - Marshaller.marshal(this, handler); - } - - /** - * Sets the value of field 'key'. - * - * @param key - * the value of field 'key'. - */ - public void setKey(final java.lang.String key) - { - this._key = key; - } - - /** - * Sets the value of field 'value'. - * - * @param value - * the value of field 'value'. - */ - public void setValue(final java.lang.String value) - { - this._value = value; - } - - /** - * Method unmarshal. - * - * @param reader - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - * @return the unmarshaled jalview.schemabinding.version2.OtherData - */ - public static jalview.schemabinding.version2.OtherData unmarshal( - final java.io.Reader reader) - throws org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - return (jalview.schemabinding.version2.OtherData) Unmarshaller - .unmarshal(jalview.schemabinding.version2.OtherData.class, - reader); - } - - /** - * - * - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - */ - public void validate() throws org.exolab.castor.xml.ValidationException - { - org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator(); - validator.validate(this); - } } diff --git a/src/jalview/schemabinding/version2/descriptors/OtherDataDescriptor.java b/src/jalview/schemabinding/version2/descriptors/OtherDataDescriptor.java index f582311..ab7a626 100644 --- a/src/jalview/schemabinding/version2/descriptors/OtherDataDescriptor.java +++ b/src/jalview/schemabinding/version2/descriptors/OtherDataDescriptor.java @@ -7,8 +7,8 @@ package jalview.schemabinding.version2.descriptors; -//---------------------------------/ -//- Imported classes and packages -/ + //---------------------------------/ + //- Imported classes and packages -/ //---------------------------------/ import jalview.schemabinding.version2.OtherData; @@ -18,231 +18,255 @@ import jalview.schemabinding.version2.OtherData; * * @version $Revision$ $Date$ */ -public class OtherDataDescriptor extends - org.exolab.castor.xml.util.XMLClassDescriptorImpl -{ - - // --------------------------/ - // - Class/Member Variables -/ - // --------------------------/ - - /** - * Field _elementDefinition. - */ - private boolean _elementDefinition; - - /** - * Field _nsPrefix. - */ - private java.lang.String _nsPrefix; - - /** - * Field _nsURI. - */ - private java.lang.String _nsURI; - - /** - * Field _xmlName. - */ - private java.lang.String _xmlName; - - // ----------------/ - // - Constructors -/ - // ----------------/ - - public OtherDataDescriptor() - { - super(); - _nsURI = "www.jalview.org"; - _xmlName = "otherData"; - _elementDefinition = true; - org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null; - org.exolab.castor.mapping.FieldHandler handler = null; - org.exolab.castor.xml.FieldValidator fieldValidator = null; - // -- initialize attribute descriptors - - // -- _key - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_key", "key", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - OtherData target = (OtherData) object; - return target.getKey(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - OtherData target = (OtherData) object; - target.setKey((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); +public class OtherDataDescriptor extends org.exolab.castor.xml.util.XMLClassDescriptorImpl { + + + //--------------------------/ + //- Class/Member Variables -/ + //--------------------------/ + + /** + * Field _elementDefinition. + */ + private boolean _elementDefinition; + + /** + * Field _nsPrefix. + */ + private java.lang.String _nsPrefix; + + /** + * Field _nsURI. + */ + private java.lang.String _nsURI; + + /** + * Field _xmlName. + */ + private java.lang.String _xmlName; + + + //----------------/ + //- Constructors -/ + //----------------/ + + public OtherDataDescriptor() { + super(); + _nsURI = "www.jalview.org"; + _xmlName = "otherData"; + _elementDefinition = true; + org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null; + org.exolab.castor.mapping.FieldHandler handler = null; + org.exolab.castor.xml.FieldValidator fieldValidator = null; + //-- initialize attribute descriptors + + //-- _key + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_key", "key", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + OtherData target = (OtherData) object; + return target.getKey(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + OtherData target = (OtherData) object; + target.setKey( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setRequired(true); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _key + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + fieldValidator.setMinOccurs(1); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _key2 + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_key2", "key2", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + OtherData target = (OtherData) object; + return target.getKey2(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + OtherData target = (OtherData) object; + target.setKey2( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _key2 + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _value + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_value", "value", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + OtherData target = (OtherData) object; + return target.getValue(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + OtherData target = (OtherData) object; + target.setValue( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setRequired(true); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _value + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + fieldValidator.setMinOccurs(1); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); } - } + desc.setValidator(fieldValidator); + //-- initialize element descriptors + + } + + + //-----------/ + //- Methods -/ + //-----------/ - public java.lang.Object newInstance(java.lang.Object parent) - { + /** + * Method getAccessMode. + * + * @return the access mode specified for this class. + */ + public org.exolab.castor.mapping.AccessMode getAccessMode( + ) { return null; - } - }; - desc.setHandler(handler); - desc.setRequired(true); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _key - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - fieldValidator.setMinOccurs(1); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); } - desc.setValidator(fieldValidator); - // -- _value - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_value", "value", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - OtherData target = (OtherData) object; - return target.getValue(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - OtherData target = (OtherData) object; - target.setValue((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setRequired(true); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _value - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - fieldValidator.setMinOccurs(1); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); + /** + * Method getIdentity. + * + * @return the identity field, null if this class has no + * identity. + */ + public org.exolab.castor.mapping.FieldDescriptor getIdentity( + ) { + return super.getIdentity(); + } + + /** + * Method getJavaClass. + * + * @return the Java class represented by this descriptor. + */ + public java.lang.Class getJavaClass( + ) { + return jalview.schemabinding.version2.OtherData.class; + } + + /** + * Method getNameSpacePrefix. + * + * @return the namespace prefix to use when marshaling as XML. + */ + public java.lang.String getNameSpacePrefix( + ) { + return _nsPrefix; + } + + /** + * Method getNameSpaceURI. + * + * @return the namespace URI used when marshaling and + * unmarshaling as XML. + */ + public java.lang.String getNameSpaceURI( + ) { + return _nsURI; + } + + /** + * Method getValidator. + * + * @return a specific validator for the class described by this + * ClassDescriptor. + */ + public org.exolab.castor.xml.TypeValidator getValidator( + ) { + return this; + } + + /** + * Method getXMLName. + * + * @return the XML Name for the Class being described. + */ + public java.lang.String getXMLName( + ) { + return _xmlName; + } + + /** + * Method isElementDefinition. + * + * @return true if XML schema definition of this Class is that + * of a global + * element or element with anonymous type definition. + */ + public boolean isElementDefinition( + ) { + return _elementDefinition; } - desc.setValidator(fieldValidator); - // -- initialize element descriptors - - } - - // -----------/ - // - Methods -/ - // -----------/ - - /** - * Method getAccessMode. - * - * @return the access mode specified for this class. - */ - public org.exolab.castor.mapping.AccessMode getAccessMode() - { - return null; - } - - /** - * Method getIdentity. - * - * @return the identity field, null if this class has no identity. - */ - public org.exolab.castor.mapping.FieldDescriptor getIdentity() - { - return super.getIdentity(); - } - - /** - * Method getJavaClass. - * - * @return the Java class represented by this descriptor. - */ - public java.lang.Class getJavaClass() - { - return jalview.schemabinding.version2.OtherData.class; - } - - /** - * Method getNameSpacePrefix. - * - * @return the namespace prefix to use when marshaling as XML. - */ - public java.lang.String getNameSpacePrefix() - { - return _nsPrefix; - } - - /** - * Method getNameSpaceURI. - * - * @return the namespace URI used when marshaling and unmarshaling as XML. - */ - public java.lang.String getNameSpaceURI() - { - return _nsURI; - } - - /** - * Method getValidator. - * - * @return a specific validator for the class described by this - * ClassDescriptor. - */ - public org.exolab.castor.xml.TypeValidator getValidator() - { - return this; - } - - /** - * Method getXMLName. - * - * @return the XML Name for the Class being described. - */ - public java.lang.String getXMLName() - { - return _xmlName; - } - - /** - * Method isElementDefinition. - * - * @return true if XML schema definition of this Class is that of a global - * element or element with anonymous type definition. - */ - public boolean isElementDefinition() - { - return _elementDefinition; - } } -- 1.7.10.2