001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Bogdan Stefanescu
011 *     Florent Guillaume
012 */
013package org.nuxeo.ecm.core.api.model;
014
015import java.io.Serializable;
016import java.util.ArrayList;
017import java.util.Collection;
018import java.util.HashMap;
019import java.util.Map;
020
021import org.nuxeo.ecm.core.api.PropertyException;
022import org.nuxeo.ecm.core.api.model.impl.ListProperty;
023import org.nuxeo.ecm.core.api.model.impl.MapProperty;
024import org.nuxeo.ecm.core.api.model.impl.ScalarProperty;
025import org.nuxeo.ecm.core.api.model.impl.primitives.BlobProperty;
026import org.nuxeo.ecm.core.schema.types.QName;
027
028/**
029 * Exporter for a document's values into a map.
030 * <p>
031 * The values of the first-level keys of the map may be prefixed (standard prefix:name naming) or not.
032 */
033@SuppressWarnings("unchecked")
034public class ValueExporter implements PropertyVisitor {
035
036    private final Map<String, Serializable> result = new HashMap<String, Serializable>();
037
038    private final boolean prefixed;
039
040    /**
041     * Constructs an exporter.
042     *
043     * @param prefixed whether first-level keys of the map are prefixed
044     */
045    public ValueExporter(boolean prefixed) {
046        this.prefixed = prefixed;
047    }
048
049    public Map<String, Serializable> getResult() {
050        return result;
051    }
052
053    public Map<String, Serializable> run(DocumentPart dp) throws PropertyException {
054        dp.accept(this, result);
055        return result;
056    }
057
058    protected String getName(Property property) {
059        QName name = property.getField().getName();
060        return prefixed ? name.getPrefixedName() : name.getLocalName();
061    }
062
063    @Override
064    public boolean acceptPhantoms() {
065        return false;
066    }
067
068    @Override
069    public Object visit(MapProperty property, Object arg) throws PropertyException {
070
071        Serializable value;
072        if (property.isContainer()) {
073            value = new HashMap<String, Serializable>();
074        } else {
075            value = property.getValue();
076        }
077
078        if (BlobProperty.class.isAssignableFrom(property.getClass())) {
079            value = property.getValue();
080            if (property.getParent().isList()) {
081                ((Collection<Serializable>) arg).add(value);
082            } else {
083                ((Map<String, Serializable>) arg).put(getName(property), value);
084            }
085            return null;
086        } else if (property.getParent().isList()) {
087            ((Collection<Serializable>) arg).add(value);
088        } else {
089            ((Map<String, Serializable>) arg).put(getName(property), value);
090        }
091        return value;
092    }
093
094    @Override
095    public Object visit(ListProperty property, Object arg) throws PropertyException {
096        Serializable value;
097        if (property.isContainer()) {
098            value = new ArrayList<Serializable>();
099        } else {
100            value = property.getValue();
101        }
102        if (property.getParent().isList()) {
103            ((Collection<Serializable>) arg).add(value);
104        } else {
105            ((Map<String, Serializable>) arg).put(getName(property), value);
106        }
107        return value;
108    }
109
110    @Override
111    public Object visit(ScalarProperty property, Object arg) throws PropertyException {
112        Serializable value = property.getValue();
113        if (property.getParent().isList()) {
114            ((Collection<Serializable>) arg).add(value);
115        } else {
116            ((Map<String, Serializable>) arg).put(getName(property), value);
117        }
118        return null;
119    }
120
121}