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