001/*
002 *  Copyright 2010 Anyware Services
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 */
016package org.ametys.web.repository.page.actions;
017
018import java.lang.reflect.Array;
019import java.util.Enumeration;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.apache.avalon.framework.parameters.Parameters;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.environment.ObjectModelHelper;
027import org.apache.cocoon.environment.Redirector;
028import org.apache.cocoon.environment.Request;
029import org.apache.cocoon.environment.SourceResolver;
030import org.apache.commons.lang3.ArrayUtils;
031import org.apache.commons.lang3.StringUtils;
032
033import org.ametys.core.observation.AbstractNotifierAction;
034import org.ametys.core.observation.Event;
035import org.ametys.plugins.repository.AmetysObjectResolver;
036import org.ametys.plugins.repository.data.holder.ModifiableModelLessDataHolder;
037import org.ametys.runtime.model.ModelItem;
038import org.ametys.runtime.model.type.ElementType;
039import org.ametys.runtime.model.type.ModelItemType;
040import org.ametys.web.ObservationConstants;
041import org.ametys.web.repository.page.ModifiablePage;
042
043/**
044 * Edit the metadata of a page
045 * The attempt request parameters are like 'page.input.[type].[single|multiple].[path].[path]'
046 *
047 */
048public class EditMetadataAction extends AbstractNotifierAction
049{
050    /** Prefix for form elements. */
051    public static final String FORM_ELEMENTS_PREFIX = "page.input.";
052    
053    private AmetysObjectResolver _resolver;
054    
055    @Override
056    public void service(ServiceManager smanager) throws ServiceException
057    {
058        super.service(smanager);
059        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
060    }
061    
062    @Override
063    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
064    {
065        Request request = ObjectModelHelper.getRequest(objectModel);
066        String id = request.getParameter("id");
067        
068        ModifiablePage page = _resolver.resolveById(id);
069        
070        Enumeration paramNames = request.getParameterNames();
071        while (paramNames.hasMoreElements())
072        {
073            String paramName = (String) paramNames.nextElement();
074            
075            if (paramName.startsWith(FORM_ELEMENTS_PREFIX))
076            {
077                String[] metadataValues = request.getParameterValues(paramName);
078                
079                // ex: page.input.string.multiple.keywords.title
080                // ex: page.input.date.single.publication.date
081                paramName = paramName.substring(FORM_ELEMENTS_PREFIX.length());
082                
083                String[] a = paramName.split("\\.");
084                boolean isMultiple = a[1].equals("multiple");
085                
086                String dataPath = StringUtils.join(ArrayUtils.subarray(a, 2, a.length), ModelItem.ITEM_PATH_SEPARATOR);
087                _saveMetadata(page, dataPath, metadataValues, isMultiple);
088            }
089        }
090        
091        if (page.needsSave())
092        {
093            page.saveChanges();
094        }
095        
096        // Notify observer
097        Map<String, Object> eventParams = new HashMap<>();
098        eventParams.put(ObservationConstants.ARGS_PAGE, page);
099        _observationManager.notify(new Event(ObservationConstants.EVENT_PAGE_CHANGED, _getCurrentUser(), eventParams));
100        
101        return EMPTY_MAP;
102    }
103    
104    private void _saveMetadata (ModifiableModelLessDataHolder dataHolder, String dataPath, String[] values, boolean isMultiple)
105    {
106        ModelItemType itemType = dataHolder.getType(dataPath);
107        if (itemType instanceof ElementType)
108        {
109            ElementType type = (ElementType) itemType;
110            if (values.length <= 0)
111            {
112                if (dataHolder.hasValue(dataPath))
113                {
114                    dataHolder.removeValue(dataPath);
115                }
116            }
117            else if (isMultiple)
118            {
119                Object value = Array.newInstance(type.getManagedClass(), values.length);
120                for (int i = 0; i < values.length; i++)
121                {
122                    Array.set(value, i, type.castValue(values[i]));
123                }
124            }
125            else
126            {
127                Object value = type.castValue(values[0]);
128                dataHolder.setValue(dataPath, value);
129            }
130            
131        }
132    }
133}