001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     matic
018 */
019package org.nuxeo.ecm.platform.ws;
020
021import java.io.IOException;
022import java.util.Calendar;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.commons.codec.binary.Base64;
027import org.nuxeo.ecm.core.api.Blob;
028import org.nuxeo.ecm.core.api.DataModel;
029import org.nuxeo.ecm.core.api.DocumentModel;
030import org.nuxeo.ecm.core.api.NuxeoException;
031import org.nuxeo.ecm.platform.api.ws.DocumentLoader;
032import org.nuxeo.ecm.platform.api.ws.DocumentProperty;
033import org.nuxeo.ecm.platform.api.ws.session.WSRemotingSession;
034
035/**
036 * @author matic
037 */
038public class DocumentSchemaLoader implements DocumentLoader {
039
040    @Override
041    public void fillProperties(DocumentModel doc, List<DocumentProperty> props, WSRemotingSession rs)
042            {
043        String[] schemas = doc.getSchemas();
044        for (String schema : schemas) {
045            DataModel dm = doc.getDataModel(schema);
046            Map<String, Object> map = dm.getMap();
047            for (Map.Entry<String, Object> entry : map.entrySet()) {
048                collectNoBlobProperty("", entry.getKey(), entry.getValue(), props);
049            }
050        }
051    }
052
053    protected void collectNoBlobProperty(String prefix, String name, Object value, List<DocumentProperty> props)
054            {
055        if (value instanceof Map) {
056            @SuppressWarnings("unchecked")
057            Map<String, Object> map = (Map<String, Object>) value;
058            prefix = prefix + name + '/';
059            for (Map.Entry<String, Object> entry : map.entrySet()) {
060                collectNoBlobProperty(prefix, entry.getKey(), entry.getValue(), props);
061            }
062        } else if (value instanceof List) {
063            prefix = prefix + name + '/';
064            @SuppressWarnings("unchecked")
065            List<Object> list = (List<Object>) value;
066            for (int i = 0, len = list.size(); i < len; i++) {
067                collectNoBlobProperty(prefix, String.valueOf(i), list.get(i), props);
068            }
069        } else if (!(value instanceof Blob)) {
070            if (value == null) {
071                props.add(new DocumentProperty(prefix + name, null));
072            } else {
073                collectProperty(prefix, name, value, props);
074            }
075        }
076    }
077
078    @SuppressWarnings("unchecked")
079    protected void collectProperty(String prefix, String name, Object value, List<DocumentProperty> props)
080            {
081        final String STRINGS_LIST_SEP = ";";
082        if (value instanceof Map) {
083            Map<String, Object> map = (Map<String, Object>) value;
084            prefix = prefix + name + '/';
085            for (Map.Entry<String, Object> entry : map.entrySet()) {
086                collectProperty(prefix, entry.getKey(), entry.getValue(), props);
087            }
088        } else if (value instanceof List) {
089            prefix = prefix + name + '/';
090            List<Object> list = (List<Object>) value;
091            for (int i = 0, len = list.size(); i < len; i++) {
092                collectProperty(prefix, String.valueOf(i), list.get(i), props);
093            }
094        } else {
095            String strValue = null;
096            if (value != null) {
097                if (value instanceof Blob) {
098                    try {
099                        // strValue = ((Blob) value).getString();
100                        byte[] bytes = ((Blob) value).getByteArray();
101                        strValue = Base64.encodeBase64String(bytes);
102                    } catch (IOException e) {
103                        throw new NuxeoException("Failed to get blob property value", e);
104                    }
105                } else if (value instanceof Calendar) {
106                    strValue = ((Calendar) value).getTime().toString();
107                } else if (value instanceof String[]) {
108                    for (String each : (String[]) value) {
109                        if (strValue == null) {
110                            strValue = each;
111                        } else {
112                            strValue = strValue + STRINGS_LIST_SEP + each;
113                        }
114                    }
115                    // FIXME: this condition is always false here.
116                } else if (value instanceof List) {
117                    for (String each : (List<String>) value) {
118                        if (strValue == null) {
119                            strValue = each;
120                        } else {
121                            strValue = strValue + STRINGS_LIST_SEP + each;
122                        }
123                    }
124                } else {
125                    strValue = value.toString();
126                } // TODO: use decode method from field type?
127            }
128            props.add(new DocumentProperty(prefix + name, strValue));
129        }
130    }
131
132}