org.hisrc.jsonix.Jsonix.Model.AbstractElementRefsPropertyInfo.js Maven / Gradle / Ivy
Jsonix.Model.AbstractElementRefsPropertyInfo = Jsonix.Class(Jsonix.Binding.ElementMarshaller, Jsonix.Binding.ElementUnmarshaller, Jsonix.Model.PropertyInfo, {
wrapperElementName : null,
allowDom : true,
allowTypedObject : true,
mixed : true,
initialize : function(mapping) {
Jsonix.Util.Ensure.ensureObject(mapping, 'Mapping must be an object.');
Jsonix.Model.PropertyInfo.prototype.initialize.apply(this, [ mapping ]);
var wen = mapping.wrapperElementName || mapping.wen || undefined;
if (Jsonix.Util.Type.isObject(wen)) {
this.wrapperElementName = Jsonix.XML.QName.fromObject(wen);
} else if (Jsonix.Util.Type.isString(wen)) {
this.wrapperElementName = new Jsonix.XML.QName(this.defaultElementNamespaceURI, wen);
} else {
this.wrapperElementName = null;
}
var dom = Jsonix.Util.Type.defaultValue(mapping.allowDom, mapping.dom, true);
var typed = Jsonix.Util.Type.defaultValue(mapping.allowTypedObject, mapping.typed, true);
var mx = Jsonix.Util.Type.defaultValue(mapping.mixed, mapping.mx, true);
this.allowDom = dom;
this.allowTypedObject = typed;
this.mixed = mx;
},
unmarshal : function(context, input, scope) {
var et = input.eventType;
if (et === Jsonix.XML.Input.START_ELEMENT) {
if (Jsonix.Util.Type.exists(this.wrapperElementName)) {
return this.unmarshalWrapperElement(context, input, scope);
} else {
return this.unmarshalElement(context, input, scope);
}
} else if (this.mixed && (et === Jsonix.XML.Input.CHARACTERS || et === Jsonix.XML.Input.CDATA || et === Jsonix.XML.Input.ENTITY_REFERENCE)) {
var value = input.getText();
if (this.collection) {
return [ value ];
} else {
return value;
}
} else if (et === Jsonix.XML.Input.SPACE || et === Jsonix.XML.Input.COMMENT || et === Jsonix.XML.Input.PROCESSING_INSTRUCTION) {
// Skip whitespace
} else {
// TODO better exception
throw new Error("Illegal state: unexpected event type [" + et + "].");
}
},
unmarshalWrapperElement : function(context, input, scope) {
var result = null;
var et = input.next();
while (et !== Jsonix.XML.Input.END_ELEMENT) {
if (et === Jsonix.XML.Input.START_ELEMENT) {
var value = this.unmarshalElement(context, input, scope);
if (this.collection) {
if (result === null) {
result = [];
}
for (var index = 0; index < value.length; index++) {
result.push(value[index]);
}
} else {
if (result === null) {
result = value;
} else {
// TODO Report validation error
throw new Error("Value already set.");
}
}
} else
// Characters
if (this.mixed && (et === Jsonix.XML.Input.CHARACTERS || et === Jsonix.XML.Input.CDATA || et === Jsonix.XML.Input.ENTITY_REFERENCE)) {
var text = input.getText();
if (this.collection) {
if (result === null) {
result = [];
}
result.push(text);
} else {
if (result === null) {
result = text;
} else {
// TODO Report validation error
throw new Error("Value already set.");
}
}
} else if (et === Jsonix.XML.Input.SPACE || et === Jsonix.XML.Input.COMMENT || et === Jsonix.XML.Input.PROCESSING_INSTRUCTION) {
// Skip whitespace
} else {
throw new Error("Illegal state: unexpected event type [" + et + "].");
}
et = input.next();
}
return result;
},
unmarshalElement : function(context, input, scope) {
var name = input.getName();
var elementValue;
var typeInfo = this.getElementTypeInfo(name, context, scope);
if (Jsonix.Util.Type.exists(typeInfo)) {
var value = typeInfo.unmarshal(context, input, scope);
elementValue = this.convertToElementValue({
name : name,
value : value
}, context, input, scope);
} else if (this.allowDom) {
elementValue = input.getElement();
} else {
// TODO better exception
throw new Error("Element [" + name.toString() + "] is not known in this context and property does not allow DOM.");
}
if (this.collection) {
return [ elementValue ];
} else {
return elementValue;
}
},
marshal : function(value, context, output, scope) {
if (Jsonix.Util.Type.exists(value)) {
if (Jsonix.Util.Type.exists(this.wrapperElementName)) {
output.writeStartElement(this.wrapperElementName);
}
if (!this.collection) {
this.marshalItem(value, context, output, scope);
} else {
Jsonix.Util.Ensure.ensureArray(value, 'Collection property requires an array value.');
for (var index = 0; index < value.length; index++) {
var item = value[index];
this.marshalItem(item, context, output, scope);
}
}
if (Jsonix.Util.Type.exists(this.wrapperElementName)) {
output.writeEndElement();
}
}
},
marshalItem : function(value, context, output, scope) {
if (Jsonix.Util.Type.isString(value)) {
if (!this.mixed) {
// TODO
throw new Error("Property is not mixed, can't handle string values.");
} else {
output.writeCharacters(value);
}
} else if (this.allowDom && Jsonix.Util.Type.exists(value.nodeType)) {
// DOM node
output.writeNode(value);
} else if (Jsonix.Util.Type.isObject(value)) {
this.marshalElementNode(value, context, output, scope);
} else {
if (this.mixed) {
throw new Error("Unsupported content type, either objects or strings are supported.");
} else {
throw new Error("Unsupported content type, only objects are supported.");
}
}
},
getElementTypeInfo : function(elementName, context, scope) {
var propertyElementTypeInfo = this.getPropertyElementTypeInfo(elementName, context);
if (Jsonix.Util.Type.exists(propertyElementTypeInfo)) {
return propertyElementTypeInfo.typeInfo;
} else {
var contextElementTypeInfo = context.getElementInfo(elementName, scope);
if (Jsonix.Util.Type.exists(contextElementTypeInfo)) {
return contextElementTypeInfo.typeInfo;
} else {
return undefined;
}
}
},
getPropertyElementTypeInfo : function(elementName, context) {
throw new Error("Abstract method [getPropertyElementTypeInfo].");
},
buildStructure : function(context, structure) {
Jsonix.Util.Ensure.ensureObject(structure);
if (Jsonix.Util.Type.exists(structure.value)) {
// TODO better exception
throw new Error("The structure already defines a value property.");
} else if (!Jsonix.Util.Type.exists(structure.elements)) {
structure.elements = {};
}
if (Jsonix.Util.Type.exists(this.wrapperElementName)) {
structure.elements[this.wrapperElementName.key] = this;
} else {
this.buildStructureElements(context, structure);
}
// if (Jsonix.Util.Type.exists(structure.elements[key]))
// {
// // TODO better exception
// throw new Error("The structure already defines an element for
// the key ["
// + key + "].");
// } else
// {
// structure.elements[key] = this;
// }
if ((this.allowDom || this.allowTypedObject)) {
structure.any = this;
}
if (this.mixed && !Jsonix.Util.Type.exists(this.wrapperElementName)) {
// if (Jsonix.Util.Type.exists(structure.mixed)) {
// // TODO better exception
// throw new Error("The structure already defines the mixed
// property.");
// } else
// {
structure.mixed = this;
// }
}
},
buildStructureElements : function(context, structure) {
throw new Error("Abstract method [buildStructureElements].");
},
buildStructureElementTypeInfos : function(context, structure, elementTypeInfo) {
structure.elements[elementTypeInfo.elementName.key] = this;
var substitutionMembers = context.getSubstitutionMembers(elementTypeInfo.elementName);
if (Jsonix.Util.Type.isArray(substitutionMembers)) {
for (var jndex = 0; jndex < substitutionMembers.length; jndex++) {
var substitutionElementInfo = substitutionMembers[jndex];
this.buildStructureElementTypeInfos(context, structure, substitutionElementInfo);
}
}
},
CLASS_NAME : 'Jsonix.Model.AbstractElementRefsPropertyInfo'
});
© 2015 - 2024 Weber Informatics LLC | Privacy Policy