001/*
002 * (C) Copyright 2006-2013 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 *     Benjamin JALON <bjalon@nuxeo.com>
018 */
019package org.nuxeo.ecm.automation.core.operations.document;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.List;
025
026import org.nuxeo.ecm.automation.OperationException;
027import org.nuxeo.ecm.automation.core.Constants;
028import org.nuxeo.ecm.automation.core.annotations.Context;
029import org.nuxeo.ecm.automation.core.annotations.Operation;
030import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
031import org.nuxeo.ecm.automation.core.annotations.Param;
032import org.nuxeo.ecm.automation.core.collectors.DocumentModelCollector;
033import org.nuxeo.ecm.core.api.CoreSession;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.api.model.Property;
036import org.nuxeo.ecm.core.schema.types.Type;
037
038/**
039 * See operation documentation
040 *
041 * @author <a href="mailto:bjalon@nuxeo.com">Benjamin JALON</a>
042 * @since 5.7
043 */
044@Operation(id = AddEntryToMultiValuedProperty.ID, category = Constants.CAT_DOCUMENT, label = "Add entry into multi-valued metadata", description = "Add value into the field expressed by the xpath parameter. This field must be a multivalued metadata.<p> 'checkExists' parameter enables to add value only if doesn't already exists in the field: <ul><li> if checked, the value will not be added if it exists already in the list</li><li>if not checked the value will be always added</li</ul>.<p> Remark: <b>only works for a field that stores a list of scalars (string, boolean, date, int, long) and not list of complex types.</b></p><p>Save parameter automatically saves the document in the database. It has to be turned off when this operation is used in the context of the empty document created, about to create, before document modification, document modified events.</p>", aliases = { "AddEntryToMultivaluedProperty" })
045public class AddEntryToMultiValuedProperty extends AbstractOperationMultiValuedProperty {
046
047    public static final String ID = "DocumentMultivaluedProperty.addItem";
048
049    @Context
050    protected CoreSession session;
051
052    @Param(name = "xpath")
053    protected String xpath;
054
055    @Param(name = "value")
056    protected Serializable value;
057
058    @Param(name = "save", required = false, values = { "true" })
059    protected boolean save = true;
060
061    @Param(name = "checkExists", required = false, values = { "true" })
062    protected boolean checkExists = true;
063
064    @OperationMethod(collector = DocumentModelCollector.class)
065    public DocumentModel run(DocumentModel doc) throws OperationException {
066        Property p = doc.getProperty(xpath);
067        Type type = p.getType();
068        checkFieldType(type, value);
069
070        List<Serializable> array = p.getValue() != null ? Arrays.asList((Serializable[]) p.getValue()) : null;
071
072        Serializable newValue = addValueIntoList(array, value);
073
074        p.setValue(newValue);
075
076        if (save) {
077            doc = session.saveDocument(doc);
078            session.save();
079        }
080
081        return doc;
082    }
083
084    private Serializable addValueIntoList(List<Serializable> array, Object valueToAdd) {
085
086        List<Object> list = new ArrayList<Object>();
087
088        if (array != null) {
089            list.addAll(array);
090        }
091
092        if (!list.contains(valueToAdd) || !checkExists) {
093            list.add(valueToAdd);
094        }
095
096        return (Serializable) list;
097
098    }
099}