001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     matic
016 */
017package org.nuxeo.ecm.platform.ws;
018
019import java.io.IOException;
020import java.util.Calendar;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.commons.codec.binary.Base64;
025import org.nuxeo.ecm.core.api.Blob;
026import org.nuxeo.ecm.core.api.DataModel;
027import org.nuxeo.ecm.core.api.DocumentModel;
028import org.nuxeo.ecm.core.api.NuxeoException;
029import org.nuxeo.ecm.platform.api.ws.DocumentLoader;
030import org.nuxeo.ecm.platform.api.ws.DocumentProperty;
031import org.nuxeo.ecm.platform.api.ws.session.WSRemotingSession;
032
033/**
034 * @author matic
035 */
036public class DocumentSchemaLoader implements DocumentLoader {
037
038    @Override
039    public void fillProperties(DocumentModel doc, List<DocumentProperty> props, WSRemotingSession rs)
040            {
041        String[] schemas = doc.getSchemas();
042        for (String schema : schemas) {
043            DataModel dm = doc.getDataModel(schema);
044            Map<String, Object> map = dm.getMap();
045            for (Map.Entry<String, Object> entry : map.entrySet()) {
046                collectNoBlobProperty("", entry.getKey(), entry.getValue(), props);
047            }
048        }
049    }
050
051    protected void collectNoBlobProperty(String prefix, String name, Object value, List<DocumentProperty> props)
052            {
053        if (value instanceof Map) {
054            @SuppressWarnings("unchecked")
055            Map<String, Object> map = (Map<String, Object>) value;
056            prefix = prefix + name + '/';
057            for (Map.Entry<String, Object> entry : map.entrySet()) {
058                collectNoBlobProperty(prefix, entry.getKey(), entry.getValue(), props);
059            }
060        } else if (value instanceof List) {
061            prefix = prefix + name + '/';
062            @SuppressWarnings("unchecked")
063            List<Object> list = (List<Object>) value;
064            for (int i = 0, len = list.size(); i < len; i++) {
065                collectNoBlobProperty(prefix, String.valueOf(i), list.get(i), props);
066            }
067        } else if (!(value instanceof Blob)) {
068            if (value == null) {
069                props.add(new DocumentProperty(prefix + name, null));
070            } else {
071                collectProperty(prefix, name, value, props);
072            }
073        }
074    }
075
076    @SuppressWarnings("unchecked")
077    protected void collectProperty(String prefix, String name, Object value, List<DocumentProperty> props)
078            {
079        final String STRINGS_LIST_SEP = ";";
080        if (value instanceof Map) {
081            Map<String, Object> map = (Map<String, Object>) value;
082            prefix = prefix + name + '/';
083            for (Map.Entry<String, Object> entry : map.entrySet()) {
084                collectProperty(prefix, entry.getKey(), entry.getValue(), props);
085            }
086        } else if (value instanceof List) {
087            prefix = prefix + name + '/';
088            List<Object> list = (List<Object>) value;
089            for (int i = 0, len = list.size(); i < len; i++) {
090                collectProperty(prefix, String.valueOf(i), list.get(i), props);
091            }
092        } else {
093            String strValue = null;
094            if (value != null) {
095                if (value instanceof Blob) {
096                    try {
097                        // strValue = ((Blob) value).getString();
098                        byte[] bytes = ((Blob) value).getByteArray();
099                        strValue = Base64.encodeBase64String(bytes);
100                    } catch (IOException e) {
101                        throw new NuxeoException("Failed to get blob property value", e);
102                    }
103                } else if (value instanceof Calendar) {
104                    strValue = ((Calendar) value).getTime().toString();
105                } else if (value instanceof String[]) {
106                    for (String each : (String[]) value) {
107                        if (strValue == null) {
108                            strValue = each;
109                        } else {
110                            strValue = strValue + STRINGS_LIST_SEP + each;
111                        }
112                    }
113                    // FIXME: this condition is always false here.
114                } else if (value instanceof List) {
115                    for (String each : (List<String>) value) {
116                        if (strValue == null) {
117                            strValue = each;
118                        } else {
119                            strValue = strValue + STRINGS_LIST_SEP + each;
120                        }
121                    }
122                } else {
123                    strValue = value.toString();
124                } // TODO: use decode method from field type?
125            }
126            props.add(new DocumentProperty(prefix + name, strValue));
127        }
128    }
129
130}