001/*
002 * (C) Copyright 2016 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 *     Gabriel Barata <gbarata@nuxeo.com>
018 */
019package org.nuxeo.ecm.platform.search.core;
020
021import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
022import static org.nuxeo.ecm.core.io.registry.MarshallingConstants.WILDCARD_VALUE;
023import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
024import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
025
026import java.io.Closeable;
027import java.io.IOException;
028import java.io.OutputStream;
029import java.util.HashMap;
030import java.util.Iterator;
031import java.util.Map;
032import java.util.Set;
033
034import javax.inject.Inject;
035
036import org.codehaus.jackson.JsonGenerator;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.model.Property;
039import org.nuxeo.ecm.core.io.marshallers.json.ExtensibleEntityJsonWriter;
040import org.nuxeo.ecm.core.io.marshallers.json.OutputStreamWithJsonWriter;
041import org.nuxeo.ecm.core.io.registry.Writer;
042import org.nuxeo.ecm.core.io.registry.reflect.Setup;
043import org.nuxeo.ecm.core.schema.SchemaManager;
044import org.nuxeo.ecm.core.schema.types.Field;
045import org.nuxeo.ecm.core.schema.types.Schema;
046
047/**
048 * @since 8.3
049 */
050@Setup(mode = SINGLETON, priority = REFERENCE)
051public class SavedSearchWriter extends ExtensibleEntityJsonWriter<SavedSearch> {
052
053    public static final String ENTITY_TYPE = "savedSearch";
054
055    @Inject
056    private SchemaManager schemaManager;
057
058    public SavedSearchWriter() {
059        super(ENTITY_TYPE, SavedSearch.class);
060    }
061
062    @Override
063    protected void writeEntityBody(SavedSearch search, JsonGenerator jg) throws IOException {
064        jg.writeStringField("id", search.getId());
065        jg.writeStringField("title", search.getTitle());
066        jg.writeStringField("queryParams", search.getQueryParams());
067        jg.writeStringField("query", search.getQuery());
068        jg.writeStringField("queryLanguage", search.getQueryLanguage());
069        jg.writeStringField("pageProviderName", search.getPageProviderName());
070        jg.writeStringField("pageSize", search.getPageSize() == null ? null : search.getPageSize().toString());
071        jg.writeStringField("currentPageIndex", search.getCurrentPageIndex() == null ? null
072                : search.getCurrentPageIndex().toString());
073        jg.writeStringField("maxResults", search.getMaxResults() == null ? null : search.getMaxResults().toString());
074        jg.writeStringField("sortBy", search.getSortBy());
075        jg.writeStringField("sortOrder", search.getSortOrder());
076        jg.writeStringField("contentViewData", search.getContentViewData());
077
078        Map<String, String> params = search.getNamedParams();
079        if (params == null) {
080            params = new HashMap<>();
081        }
082
083        jg.writeObjectFieldStart("params");
084        Iterator<String> it = params.keySet().iterator();
085        while (it.hasNext()) {
086            String param = it.next();
087            jg.writeStringField(param, search.getNamedParams().get(param));
088        }
089
090        Set<String> schemas = ctx.getProperties();
091        if (schemas.size() > 0) {
092            DocumentModel doc = search.getDocument();
093            if (schemas.contains(WILDCARD_VALUE)) {
094                // full document
095                for (String schema : doc.getSchemas()) {
096                    writeSchemaProperties(jg, doc, schema);
097                }
098            } else {
099                for (String schema : schemas) {
100                    if (doc.hasSchema(schema)) {
101                        writeSchemaProperties(jg, doc, schema);
102                    }
103                }
104            }
105        }
106
107        jg.writeEndObject();
108    }
109
110    // taken from DocumentModelJsonWriter
111    private void writeSchemaProperties(JsonGenerator jg, DocumentModel doc, String schemaName) throws IOException {
112        Writer<Property> propertyWriter = registry.getWriter(ctx, Property.class, APPLICATION_JSON_TYPE);
113        // provides the current document to the property marshaller
114        try (Closeable resource = ctx.wrap().with(ENTITY_TYPE, doc).open()) {
115            Schema schema = schemaManager.getSchema(schemaName);
116            String prefix = schema.getNamespace().prefix;
117            if (prefix == null || prefix.length() == 0) {
118                prefix = schemaName;
119            }
120            prefix = prefix + ":";
121            for (Field field : schema.getFields()) {
122                String prefixedName = prefix + field.getName().getLocalName();
123                jg.writeFieldName(prefixedName);
124                Property property = doc.getProperty(prefixedName);
125                OutputStream out = new OutputStreamWithJsonWriter(jg);
126                propertyWriter.write(property, Property.class, Property.class, APPLICATION_JSON_TYPE, out);
127            }
128        }
129    }
130}