package org.nuxeo.ecm.automation.jaxrs.io.documents;

import java.io.OutputStream;
import java.util.Map;

import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.platform.tag.Tag;
import org.nuxeo.ecm.platform.tag.TagService;
import org.nuxeo.runtime.api.Framework;

/**
 * JSon writer that outputs a format ready to eat by elasticsearch.
 * 
 * 
 * @since 5.9.3
 */
@Provider
@Produces({ "application/json+esentity" })
public class JsonESDocumentWriter extends JsonDocumentWriter {

    public static void writeDoc(JsonGenerator jg, DocumentModel doc, String[] schemas,
            Map<String, String> contextParameters, HttpHeaders headers) throws Exception {

        jg.writeStartObject();
        jg.writeStringField("repository", doc.getRepositoryName());
        jg.writeStringField("ecm:uuid", doc.getId());
        jg.writeStringField("ecm:name", doc.getName());
        jg.writeStringField("ecm:title", doc.getTitle());
        jg.writeStringField("ecm:path", doc.getPathAsString());
        jg.writeStringField("ecm:primarytype", doc.getType());
        jg.writeStringField("ecm:parentId", doc.getParentRef().toString());
        jg.writeStringField("ecm:currentLifeCycleState", doc.getCurrentLifeCycleState());
        jg.writeStringField("ecm:versionLabel", doc.getVersionLabel());
        jg.writeBooleanField("ecm:isCheckedIn", !doc.isCheckedOut());
        jg.writeBooleanField("ecm:isProxy", doc.isProxy());
        jg.writeBooleanField("ecm:isVersion", doc.isVersion());
        jg.writeArrayFieldStart("ecm:mixinType");
        for (String facet : doc.getFacets()) {
            jg.writeString(facet);
        }
        jg.writeEndArray();
        TagService tagService = Framework.getService(TagService.class);
        if (tagService != null) {
            jg.writeArrayFieldStart("ecm:tag");
            for (Tag tag : tagService.getDocumentTags(doc.getCoreSession(), doc.getId(),
                    null)) {
                jg.writeString(tag.getLabel());
            }
            jg.writeEndArray();
        }
        jg.writeStringField("changeToken", doc.getChangeToken());
        // TODO Add acl
        jg.writeArrayFieldStart("acl");
        jg.writeString("fake");
        jg.writeString("members");
        jg.writeEndArray();
        // TODO Add fulltext
        jg.writeStringField("fulltext", doc.getTitle() + " " + doc.getName());
        if (schemas == null || (schemas.length == 1 && "*".equals(schemas[0]))) {
            schemas = doc.getSchemas();
        }
        for (String schema : schemas) {
            writeProperties(jg, doc, schema);
        }
        if (contextParameters != null && !contextParameters.isEmpty()) {
            for (Map.Entry<String, String> parameter : contextParameters.entrySet()) {
                jg.writeStringField(parameter.getKey(), parameter.getValue());
            }
        }
        jg.writeEndObject();
        jg.flush();
    }

    @Override
    public void writeDocument(OutputStream out, DocumentModel doc, String[] schemas,
            Map<String, String> contextParameters) throws Exception {
        writeDoc(factory.createJsonGenerator(out, JsonEncoding.UTF8), doc, schemas,
                contextParameters, headers);
    }

    public static void writeESDocument(JsonGenerator jg, DocumentModel doc,
            String[] schemas, Map<String, String> contextParameters) throws Exception {
        writeDoc(jg, doc, schemas, contextParameters, null);
    }

}

@@ -58,28 +58,251 @@
 ort 
-java.io.OutputStream
+static org.nuxeo.ecm.core.api.security.SecurityConstants.BROWSE;%0Aimport static org.nuxeo.ecm.core.api.security.SecurityConstants.EVERYONE;%0A%0Aimport java.io.OutputStream;%0Aimport java.util.ArrayList;%0Aimport java.util.Arrays;%0Aimport java.util.List
 ;%0Aim
@@ -552,16 +552,200 @@
 tModel;%0A
+import org.nuxeo.ecm.core.api.security.ACE;%0Aimport org.nuxeo.ecm.core.api.security.ACL;%0Aimport org.nuxeo.ecm.core.api.security.ACP;%0Aimport org.nuxeo.ecm.core.security.SecurityService;%0A
 import o
@@ -2711,127 +2711,793 @@
  // 
-TODO Add acl%0A        jg.writeArrayFieldStart(%22acl%22);%0A        jg.writeString(%22fake%22);%0A        jg.writeString(%22members%22);
+Add a positive ACL only%0A        SecurityService securityService = Framework.getService(SecurityService.class);%0A        List%3CString%3E browsePermissions = new ArrayList%3CString%3E(%0A                Arrays.asList(securityService.getPermissionsToCheck(BROWSE)));%0A        ACP acp = doc.getACP();%0A        ACL acl = acp.getACL(ACL.INHERITED_ACL);%0A        jg.writeArrayFieldStart(%22acl%22);%0A        for (ACE ace : acl.getACEs()) %7B%0A            if (ace.isGranted() && browsePermissions.contains(ace.getPermission())) %7B%0A                jg.writeString(ace.getUsername());%0A            %7D%0A            if (ace.isDenied()) %7B%0A                if (!EVERYONE.equals(ace.getUsername())) %7B%0A                    jg.writeString(%22UNSUPPORTED_DENIED_ACL%22);%0A                %7D%0A                break;%0A            %7D%0A        %7D
 %0A   

Add positive ACL to ES dump