/* * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * ataillefer */ package org.nuxeo.ecm.core.io.impl; import java.io.IOException; import java.util.List; import java.util.Map; import org.dom4j.Element; import org.dom4j.QName; import org.nuxeo.common.collections.PrimitiveArrays; import org.nuxeo.common.utils.Path; import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.schema.Namespace; import org.nuxeo.ecm.core.schema.TypeConstants; import org.nuxeo.ecm.core.schema.types.ComplexType; import org.nuxeo.ecm.core.schema.types.Field; import org.nuxeo.ecm.core.schema.types.ListType; import org.nuxeo.ecm.core.schema.types.Type; import org.nuxeo.ecm.core.schema.types.primitives.BinaryType; import org.nuxeo.ecm.core.schema.types.primitives.BooleanType; import org.nuxeo.ecm.core.schema.types.primitives.DateType; import org.nuxeo.ecm.core.schema.types.primitives.DoubleType; import org.nuxeo.ecm.core.schema.types.primitives.IntegerType; import org.nuxeo.ecm.core.schema.types.primitives.LongType; import org.nuxeo.ecm.core.schema.types.primitives.StringType; /** * A representation for an exported document aware of property types. * * @author <a href="mailto:ataillefer@nuxeo.com">Antoine Taillefer</a> * @since 5.6 */ public class TypedExportedDocumentImpl extends ExportedDocumentImpl { private static final String TYPE_ATTRIBUTE = "type"; private static final String COMPLEX_TYPE_ID = "complex"; private static final String SCALAR_LIST_TYPE_ID = "scalarList"; private static final String COMPLEX_LIST_TYPE_ID = "complexList"; private static final String CONTENT_LIST_TYPE_ID = "contentList"; public TypedExportedDocumentImpl() { super(); } /** * Instantiates a new typed exported document impl. * * @param doc the doc * @param path the path to use for this document this is used to remove full paths * @param inlineBlobs the inline blobs * @throws IOException Signals that an I/O exception has occurred. */ public TypedExportedDocumentImpl(DocumentModel doc, Path path, boolean inlineBlobs) throws IOException { super(doc, path, inlineBlobs); } /** * Instantiates a new typed exported document impl. * * @param doc the doc * @throws IOException Signals that an I/O exception has occurred. */ public TypedExportedDocumentImpl(DocumentModel doc) throws IOException { super(doc, false); } /** * Instantiates a new typed exported document impl. * * @param doc the doc * @param inlineBlobs the inline blobs * @throws IOException Signals that an I/O exception has occurred. */ public TypedExportedDocumentImpl(DocumentModel doc, boolean inlineBlobs) throws IOException { super(doc, doc.getPath(), inlineBlobs); } /** * Here we do what super does but add the "type" attribute to the XML elements. */ @Override @SuppressWarnings("rawtypes") protected void readProperty(Element parent, Namespace targetNs, Field field, Object value, boolean inlineBlobs) throws IOException { Type type = field.getType(); QName name = QName.get(field.getName().getLocalName(), targetNs.prefix, targetNs.uri); Element element = parent.addElement(name); // extract the element content if (type.isSimpleType()) { element.addAttribute(TYPE_ATTRIBUTE, getSimpleTypeId(type)); if (value != null) { element.addText(type.encode(value)); } } else if (type.isComplexType()) { ComplexType ctype = (ComplexType) type; if (TypeConstants.isContentType(ctype)) { element.addAttribute(TYPE_ATTRIBUTE, TypeConstants.CONTENT); if (value != null) { readBlob(element, ctype, (Blob) value, inlineBlobs); } } else { element.addAttribute(TYPE_ATTRIBUTE, COMPLEX_TYPE_ID); if (value != null) { readComplex(element, ctype, (Map) value, inlineBlobs); } } } else if (type.isListType()) { String typeId; ListType listType = ((ListType) type); // Scalar list if (listType.isScalarList()) { typeId = SCALAR_LIST_TYPE_ID; } // Content list else if (TypeConstants.isContentType(listType.getFieldType())) { typeId = CONTENT_LIST_TYPE_ID; } // Complex list else { typeId = COMPLEX_LIST_TYPE_ID; } element.addAttribute(TYPE_ATTRIBUTE, typeId); if (value != null) { if (value instanceof List) { readList(element, (ListType) type, (List) value, inlineBlobs); } else if (value.getClass().getComponentType() != null) { readList(element, (ListType) type, PrimitiveArrays.toList(value), inlineBlobs); } else { throw new IllegalArgumentException("A value of list type is neither list neither array: " + value); } } } } /** * Gets the simple type id. * * @param type the type * @return the simple type id */ protected String getSimpleTypeId(Type type) { String typeId = StringType.ID; if (BooleanType.INSTANCE == type) { typeId = BooleanType.ID; } else if (DateType.INSTANCE == type) { typeId = DateType.ID; } else if (LongType.INSTANCE == type) { typeId = LongType.ID; } else if (IntegerType.INSTANCE == type) { typeId = IntegerType.ID; } else if (DoubleType.INSTANCE == type) { typeId = DoubleType.ID; } else if (BinaryType.INSTANCE == type) { typeId = BinaryType.ID; } return typeId; } }