Skip to content

Commit

Permalink
Almost works. Again.
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Jan 27, 2014
1 parent bc802fe commit 92b4845
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 73 deletions.
Expand Up @@ -85,7 +85,7 @@ public static PrismContext create(SchemaRegistry schemaRegistry) {
prismContext.beanConverter = new PrismBeanConverter(schemaRegistry);

prismContext.parserMap = new HashMap<String, Parser>();
DOMParser parserDom = new DOMParser();
DOMParser parserDom = new DOMParser(schemaRegistry);
prismContext.parserMap.put(LANG_XML, parserDom);
prismContext.parserDom = parserDom;

Expand Down
Expand Up @@ -1076,14 +1076,16 @@ public Element serializeToDom(PrismObject<?> object) throws SchemaException {
public Element serializeToDom(PrismObject<?> object, boolean serializeCompositeObjects) throws SchemaException {
DomSerializer domSerializer = null;
domSerializer.setSerializeCompositeObjects(serializeCompositeObjects);
return domSerializer.serialize(object);
// return domSerializer.serialize(object);
return null;
}

public <T extends Containerable> Element serializeToDom(PrismContainerValue<T> object, Element parentElement)
throws SchemaException {

DomSerializer domSerializer = null;
return domSerializer.serializeContainerValue(object, parentElement);
// return domSerializer.serializeContainerValue(object, parentElement);
return null;
}

public <T extends Objectable> String serializeObjectToString(PrismObject<T> object) throws SchemaException {
Expand Down
Expand Up @@ -47,6 +47,11 @@ public class DOMParser implements Parser {

private SchemaRegistry schemaRegistry;

public DOMParser(SchemaRegistry schemaRegistry) {
super();
this.schemaRegistry = schemaRegistry;
}

@Override
public XNode parse(File file) throws SchemaException {
Document document = DOMUtil.parseFile(file);
Expand Down Expand Up @@ -241,6 +246,27 @@ public boolean canParse(String dataString) {
return dataString.startsWith("<?xml");
}

@Override
public String serializeToString(XNode xnode, QName rootElementName) throws SchemaException {
DomSerializer serializer = new DomSerializer(this, schemaRegistry);
RootXNode xroot;
if (xnode instanceof RootXNode) {
xroot = (RootXNode) xnode;
} else {
xroot = new RootXNode(rootElementName);
xroot.setSubnode(xnode);
}
Element element = serializer.serialize(xroot);
return DOMUtil.serializeDOMToString(element);
}

@Override
public String serializeToString(RootXNode xnode) throws SchemaException {
DomSerializer serializer = new DomSerializer(this, schemaRegistry);
Element element = serializer.serialize(xnode);
return DOMUtil.serializeDOMToString(element);
}

public Element serializeValueToDom(PrismReferenceValue rval, QName elementName, Document document) {
// TODO Auto-generated method stub
return null;
Expand Down
Expand Up @@ -16,11 +16,15 @@
package com.evolveum.midpoint.prism.parser;

import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import org.apache.commons.lang.StringUtils;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

Expand All @@ -44,8 +48,14 @@
import com.evolveum.midpoint.prism.xml.DynamicNamespacePrefixMapper;
import com.evolveum.midpoint.prism.xml.PrismJaxbProcessor;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.prism.xnode.ListXNode;
import com.evolveum.midpoint.prism.xnode.MapXNode;
import com.evolveum.midpoint.prism.xnode.PrimitiveXNode;
import com.evolveum.midpoint.prism.xnode.RootXNode;
import com.evolveum.midpoint.prism.xnode.XNode;
import com.evolveum.midpoint.util.DOMUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;

/**
* @author semancik
Expand Down Expand Up @@ -78,58 +88,107 @@ private DynamicNamespacePrefixMapper getNamespacePrefixMapper() {
return schemaRegistry.getNamespacePrefixMapper();
}

public Element serialize(PrismObject<?> object) throws SchemaException {
initialize();
Element topElement = createElement(object.getElementName());
serialize(object, topElement);
private void initialize() {
doc = DOMUtil.getDocument();
topElement = null;
}

public Element serialize(RootXNode rootxnode) throws SchemaException {
initialize();
QName rootElementName = rootxnode.getRootElementName();
Element topElement = createElement(rootxnode.getRootElementName());
QName typeQName = rootxnode.getTypeQName();
if (typeQName != null && !schemaRegistry.hasImplicitTypeDefinition(rootElementName, typeQName)) {
DOMUtil.setXsiType(topElement, rootxnode.getTypeQName());
}
XNode subnode = rootxnode.getSubnode();
if (!(subnode instanceof MapXNode)) {
throw new SchemaException("Sub-root xnode is not map, cannot serialize to XML (it is "+subnode+")");
}
serializeMap((MapXNode)subnode, topElement);
return topElement;
}

private void serialize(PrismObject<?> object, QName elementName, Element parentElement) throws SchemaException {
Element topElement = createElement(elementName);
parentElement.appendChild(topElement);
serialize(object, topElement);

private void serializeMap(MapXNode xmap, Element topElement) throws SchemaException {
for (Entry<QName,XNode> entry: xmap.entrySet()) {
QName elementQName = entry.getKey();
XNode xsubnode = entry.getValue();
if (xsubnode instanceof ListXNode) {
ListXNode xlist = (ListXNode)xsubnode;
for (XNode xsubsubnode: xlist) {
serializeSubnode(xsubsubnode, topElement, elementQName);
}
} else {
serializeSubnode(xsubnode, topElement, elementQName);
}
}
}

private void serialize(PrismObject<?> object, Element topElement) throws SchemaException {
serializeItems(object.getValue().getItems(), object.getDefinition(), topElement);
if (object.getOid() != null) {
topElement.setAttribute(PrismConstants.ATTRIBUTE_OID_LOCAL_NAME, object.getOid());
}
if (object.getVersion() != null) {
topElement.setAttribute(PrismConstants.ATTRIBUTE_VERSION_LOCAL_NAME, object.getVersion());
}
QName elementQName = new QName(topElement.getNamespaceURI(), topElement.getLocalName());
if (object.getDefinition() != null &&
// !prismContext.getSchemaRegistry().hasImplicitTypeDefinition(object.getName(), object.getDefinition().getTypeName())) {
!schemaRegistry.hasImplicitTypeDefinition(elementQName, object.getDefinition().getTypeName())) {
DOMUtil.setXsiType(topElement, object.getDefinition().getTypeName());
private void serializeSubnode(XNode xsubnode, Element parentElement, QName elementName) throws SchemaException {
if (xsubnode instanceof MapXNode) {
Element element = createElement(elementName);
parentElement.appendChild(element);
serializeMap((MapXNode)xsubnode, element);
} else if (xsubnode instanceof PrimitiveXNode<?>) {
PrimitiveXNode<?> xprim = (PrimitiveXNode<?>)xsubnode;
if (xprim.isAttribute()) {
serializePrimitiveAttribute(xprim, parentElement, elementName);
} else {
serializePrimitiveElement(xprim, parentElement, elementName);
}
} else if (xsubnode instanceof ListXNode) {
ListXNode xlist = (ListXNode)xsubnode;
for (XNode xsubsubnode: xlist) {
serializeSubnode(xsubsubnode, parentElement, elementName);
}
}
}

private void initialize() {
doc = DOMUtil.getDocument();
topElement = null;
private <T> void serializePrimitiveAttribute(PrimitiveXNode<T> xprim, Element parentElement, QName attributeName) {
QName typeQName = xprim.getTypeQName();
if (typeQName.equals(DOMUtil.XSD_QNAME)) {
QName value = (QName) xprim.getValue();
try {
DOMUtil.setQNameAttribute(parentElement, attributeName.getLocalPart(), value);
} catch (DOMException e) {
throw new DOMException(e.code, e.getMessage() + "; setting attribute "+attributeName.getLocalPart()+" in element "+DOMUtil.getQName(parentElement)+" to QName value "+value);
}
} else {
String value = xprim.getFormattedValue();
parentElement.setAttribute(attributeName.getLocalPart(), value);
}
}

public Element serializeContainerValue(PrismContainerValue<?> value, Element parentElement) throws SchemaException {
initialize();
doc = parentElement.getOwnerDocument();

serialize(value, parentElement);
return parentElement;
}

private void serialize(PrismContainerValue<?> value, Element parentElement) throws SchemaException {
PrismContainerable<?> parent = value.getParent();
QName elementQName = parent.getElementName();
Element element = createElement(elementQName);
private void serializePrimitiveElement(PrimitiveXNode<?> xprim, Element parentElement, QName elementName) {
Element element;
try {
element = createElement(elementName);
} catch (DOMException e) {
throw new DOMException(e.code, e.getMessage() + "; creating element "+elementName+" in element "+DOMUtil.getQName(parentElement));
}
parentElement.appendChild(element);
serializeItems(value.getItems(), parent.getDefinition(), element);
if (value.getId() != null) {
element.setAttribute(PrismConstants.ATTRIBUTE_ID_LOCAL_NAME, value.getId().toString());

QName typeQName = xprim.getTypeQName();
if (xprim.isExplicitTypeDeclaration()) {
DOMUtil.setXsiType(element, typeQName);
}

if (typeQName.equals(DOMUtil.XSD_QNAME)) {
QName value = (QName) xprim.getValue();
DOMUtil.setQNameValue(element, value);
} else {
String value = xprim.getFormattedValue();
element.setTextContent(value);
}
}






// OLD CODE


private void serialize(PrismPropertyValue<?> value, Element parentElement) throws SchemaException {
Itemable parent = value.getParent();
Expand Down Expand Up @@ -218,22 +277,7 @@ private void serializeObject(PrismReferenceValue value, Element parentElement) t
throw new SchemaException("Cannot serialize composite object in "+DOMUtil.getQName(parentElement)+" because the composite element" +
"name for reference "+definition+" is not defined");
}
serialize(value.getObject(), compositeObjectElementName, parentElement);
}

private void serializeItems(List<Item<?>> items, PrismContainerDefinition definition, Element parentElement) throws SchemaException {
if (definition != null && !definition.isDynamic()) {
ComplexTypeDefinition complexTypeDefinition = definition.getComplexTypeDefinition();
if (complexTypeDefinition != null) {
serializeItemsUsingDefinition(items, complexTypeDefinition, parentElement);
return;
}
}
// We have no choice here. Just follow the "natural" order of items
for (Item<?> item: items) {
serialize(item, parentElement);
}

// serialize(value.getObject(), compositeObjectElementName, parentElement);
}

private void serializeItemsUsingDefinition(List<Item<?>> items, ComplexTypeDefinition definition, Element parentElement) throws SchemaException {
Expand Down Expand Up @@ -369,6 +413,10 @@ void serialize(PrismValue pval, Element parentElement) throws SchemaException {
* @return created DOM element
*/
private Element createElement(QName qname) {
String namespaceURI = qname.getNamespaceURI();
if (StringUtils.isBlank(namespaceURI)) {
return doc.createElement(qname.getLocalPart());
}
QName qnameWithPrefix = getNamespacePrefixMapper().setQNamePrefix(qname);
if (topElement != null) {
return DOMUtil.createElement(doc, qnameWithPrefix, topElement, topElement);
Expand Down
Expand Up @@ -18,6 +18,9 @@
import java.io.File;
import java.io.IOException;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.xnode.RootXNode;
import com.evolveum.midpoint.prism.xnode.XNode;
import com.evolveum.midpoint.util.exception.SchemaException;

Expand All @@ -35,4 +38,8 @@ public interface Parser {

boolean canParse(String dataString);

String serializeToString(XNode xnode, QName rootElementName) throws SchemaException;

String serializeToString(RootXNode xnode) throws SchemaException;

}
Expand Up @@ -157,7 +157,7 @@ public <T> MapXNode marshall(T bean) {

Field field;
try {
field = beanClass.getField(fieldName);
field = beanClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException | SecurityException e) {
throw new SystemException("Cannot accesss field "+fieldName+" in "+beanClass+": "+e.getMessage(), e);
}
Expand Down
Expand Up @@ -539,5 +539,9 @@ private Long getContainerId(MapXNode xmap) throws SchemaException {
// -- SERIALIZATION
// --------------------------

public <O extends Objectable> XNode serializeObject(PrismObject<O> object) throws SchemaException {
XNodeSerializer serializer = new XNodeSerializer(prismContext.getBeanConverter());
return serializer.serializeObject(object);
}

}
Expand Up @@ -133,16 +133,20 @@ private <V extends PrismValue> XNode serializeItem(Item<V> item) throws SchemaEx
}

private <V extends PrismValue> XNode serializeItemValue(V itemValue, ItemDefinition definition) throws SchemaException {
// special handling for reference values (account vs accountRef).
XNode xnode;
if (itemValue instanceof PrismReferenceValue) {
return serializeReferenceValue((PrismReferenceValue)itemValue, (PrismReferenceDefinition) definition);
xnode = serializeReferenceValue((PrismReferenceValue)itemValue, (PrismReferenceDefinition) definition);
} else if (itemValue instanceof PrismPropertyValue<?>) {
return serializePropertyValue((PrismPropertyValue<?>)itemValue, (PrismPropertyDefinition)definition);
xnode = serializePropertyValue((PrismPropertyValue<?>)itemValue, (PrismPropertyDefinition)definition);
} else if (itemValue instanceof PrismContainerValue<?>) {
return serializeContainerValue((PrismContainerValue<?>)itemValue, (PrismContainerDefinition)definition);
xnode = serializeContainerValue((PrismContainerValue<?>)itemValue, (PrismContainerDefinition)definition);
} else {
throw new IllegalArgumentException("Unsupported value type "+itemValue.getClass());
}
if (definition.isDynamic()) {
xnode.setExplicitTypeDeclaration(true);
}
return xnode;
}

private XNode serializeReferenceValue(PrismReferenceValue value, PrismReferenceDefinition definition) throws SchemaException {
Expand Down
Expand Up @@ -18,6 +18,7 @@
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.SchemaException;
Expand All @@ -33,7 +34,7 @@ public class PrimitiveXNode<T> extends XNode {
* is capable of representing attributes)
*/
private boolean isAttribute = false;

public void parseValue(QName typeName) throws SchemaException {
if (valueParser != null) {
value = valueParser.parse(typeName);
Expand Down Expand Up @@ -79,9 +80,16 @@ public void setAttribute(boolean isAttribute) {
* Returns a value that is correctly string-formatted according
* to its type definition. Works properly only if definition is set.
*/
// public String getValueAsString() {
//
// }
public String getFormattedValue() {
if (getTypeQName() == null) {
throw new IllegalStateException("Cannot fetch formatted value if type definition is not set");
}
if (!isParsed()) {
throw new IllegalStateException("Cannot fetch formatted value if the xnode is not parsed");
}
T value = getValue();
return XmlTypeConverter.toXmlTextContent(value, null);
}

@Override
public String debugDump(int indent) {
Expand Down

0 comments on commit 92b4845

Please sign in to comment.