001/*
002 * (C) Copyright 2014 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-2.1.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 *     Nelson Silva <nelson.silva@inevo.pt>
016 */
017package org.nuxeo.ecm.automation.io.services.enricher;
018
019import java.io.IOException;
020import java.util.ArrayList;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.codehaus.jackson.JsonGenerator;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.api.model.Property;
030import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
031import org.nuxeo.ecm.core.schema.SchemaManager;
032import org.nuxeo.ecm.core.schema.types.Field;
033import org.nuxeo.ecm.core.schema.types.Schema;
034import org.nuxeo.ecm.directory.DirectoryException;
035import org.nuxeo.ecm.directory.Session;
036import org.nuxeo.ecm.directory.api.DirectoryService;
037import org.nuxeo.runtime.api.Framework;
038
039/**
040 * This enricher adds the labels for each value of a property referencing dbl10n vocabularies.
041 *
042 * @since 6.0
043 * @deprecated This enricher was migrated to org.nuxeo.ecm.platform.spreadsheet.DCVocabulariesJsonEnricher. The content
044 *             enricher service doesn't work anymore.
045 */
046@Deprecated
047public class VocabularyEnricher extends AbstractContentEnricher {
048
049    protected static final Log log = LogFactory.getLog(VocabularyEnricher.class);
050
051    public static final String DIRECTORY_DEFAULT_LABEL_PREFIX = "label_";
052
053    public static final String KEY_SEPARATOR = "/";
054
055    // Parameters keys
056    public static final String FIELD_PARAMETER = "field";
057
058    public static final String DIRECTORY_PARAMETER = "directoryName";
059
060    // Parameters values
061    private String field;
062
063    private String directoryName;
064
065    private DirectoryService directoryService;
066
067    @Override
068    public void enrich(JsonGenerator jg, RestEvaluationContext ec) throws IOException {
069
070        final DocumentModel doc = ec.getDocumentModel();
071
072        jg.writeStartObject();
073
074        try {
075
076            // Lookup directory schema to find label columns
077            List<String> labelFields = getLabelFields(directoryName);
078
079            // Get the field values
080            String[] entriesIds = getPropertyValues(doc, field);
081
082            // 'field': [
083            jg.writeFieldName(field);
084            jg.writeStartArray();
085
086            // { 'id': ..., 'label_*': ... }
087            if (entriesIds != null) {
088                writeLabels(jg, directoryName, entriesIds, labelFields);
089            }
090
091            // ]
092            jg.writeEndArray();
093
094        } catch (PropertyNotFoundException | DirectoryException e) {
095            log.error(e.getMessage());
096        }
097
098        jg.writeEndObject();
099        jg.flush();
100    }
101
102    @Override
103    public void setParameters(Map<String, String> parameters) {
104        field = parameters.get(FIELD_PARAMETER);
105        if (field == null || field.isEmpty()) {
106            throw new IllegalArgumentException("Parameter '" + FIELD_PARAMETER + "' cannot be empty");
107        }
108        directoryName = parameters.get(DIRECTORY_PARAMETER);
109        if (directoryName == null || directoryName.isEmpty()) {
110            throw new IllegalArgumentException("Parameter '" + DIRECTORY_PARAMETER + "' cannot be empty");
111        }
112    }
113
114    /**
115     * Writes the labels for each entry
116     *
117     * @param jg
118     * @param directoryName
119     * @param entriesIds
120     * @param labelFields
121     * @throws IOException
122     */
123    private void writeLabels(JsonGenerator jg, String directoryName, String[] entriesIds, List<String> labelFields)
124            throws IOException {
125        try (Session session = getDirectoryService().open(directoryName)) {
126            for (String entryId : entriesIds) {
127                Map<String, String> labels = getAbsoluteLabels(entryId, session, labelFields);
128                // Write absolute labels (<parent label> / <child label>)
129                jg.writeStartObject();
130                jg.writeStringField("id", entryId);
131                for (Map.Entry<String, String> label : labels.entrySet()) {
132                    jg.writeStringField(label.getKey(), label.getValue());
133                }
134                jg.writeEndObject();
135            }
136        }
137    }
138
139    /**
140     * Determines label columns based on the label prefix
141     *
142     * @param directoryName the name of the directory to inspect
143     * @return
144     */
145    private List<String> getLabelFields(String directoryName) {
146        String schemaName = getDirectoryService().getDirectorySchema(directoryName);
147
148        SchemaManager schemaManager = Framework.getLocalService(SchemaManager.class);
149
150        Schema schema = schemaManager.getSchema(schemaName);
151
152        List<String> labelFields = new ArrayList<>();
153        String fieldName;
154        for (Field field : schema.getFields()) {
155            fieldName = field.getName().toString();
156            if (fieldName.startsWith(DIRECTORY_DEFAULT_LABEL_PREFIX)) {
157                labelFields.add(fieldName);
158            }
159        }
160
161        return labelFields;
162    }
163
164    private DirectoryService getDirectoryService() {
165        if (directoryService == null) {
166            directoryService = Framework.getLocalService(DirectoryService.class);
167        }
168        return directoryService;
169
170    }
171
172    /**
173     * Return the values of a document's property as an array of strings
174     *
175     * @param doc
176     * @param fieldName
177     * @return
178     */
179    private static String[] getPropertyValues(DocumentModel doc, String fieldName) {
180        String[] entriesIds = null;
181        Property prop = doc.getProperty(fieldName);
182        if (prop.isList()) {
183            entriesIds = prop.getValue(String[].class);
184        } else {
185            String value = prop.getValue(String.class);
186            if (value != null) {
187                entriesIds = new String[] { value };
188            }
189        }
190        return entriesIds;
191    }
192
193    /**
194     * Returns absolute labels for a given entry (<parent label> / <child label>)
195     *
196     * @param entryId
197     * @param session
198     * @param labelFields
199     * @return a map of field: label
200     */
201    private static Map<String, String> getAbsoluteLabels(final String entryId, final Session session,
202            List<String> labelFields) {
203
204        String[] split = entryId.split(KEY_SEPARATOR);
205        Map<String, String> labels = new HashMap<>();
206
207        for (int i = 0; i < split.length; i++) {
208            DocumentModel entry = session.getEntry(split[i]);
209            if (entry == null) {
210                continue;
211            }
212
213            for (String labelField : labelFields) {
214                String result = labels.get(labelField);
215                if (result == null) {
216                    result = "";
217                }
218                String value = (String) entry.getPropertyValue(labelField);
219                result += (i > 0 ? "/" : "") + value;
220                labels.put(labelField, result);
221            }
222
223        }
224
225        return labels;
226    }
227
228}