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.plugins.forms.data;
017
018import java.io.IOException;
019import java.text.DateFormat;
020import java.text.SimpleDateFormat;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.ProcessingException;
027import org.apache.cocoon.generation.ServiceableGenerator;
028import org.apache.cocoon.xml.AttributesImpl;
029import org.apache.cocoon.xml.XMLUtils;
030import org.apache.commons.lang.StringUtils;
031import org.xml.sax.SAXException;
032
033import org.ametys.core.util.I18nUtils;
034import org.ametys.plugins.forms.Field.FieldType;
035import org.ametys.plugins.forms.Form;
036import org.ametys.plugins.forms.FormsException;
037import org.ametys.plugins.forms.jcr.FormPropertiesManager;
038import org.ametys.plugins.forms.table.FormTableManager;
039import org.ametys.plugins.repository.AmetysObjectResolver;
040import org.ametys.plugins.workflow.store.JdbcWorkflowStore;
041import org.ametys.plugins.workflow.support.WorkflowProvider;
042import org.ametys.runtime.i18n.I18nizableText;
043
044import com.opensymphony.workflow.Workflow;
045import com.opensymphony.workflow.loader.StepDescriptor;
046import com.opensymphony.workflow.loader.WorkflowDescriptor;
047import com.opensymphony.workflow.spi.Step;
048
049/**
050 * Searches the list of forms contained in a given set of contents.
051 */
052public class FormEntriesGenerator extends ServiceableGenerator
053{
054    /** The date format. */
055    protected static final DateFormat _DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
056    
057    /** The internationalizable text symbolizing the absence of workflow step */
058    protected static final I18nizableText __MESSAGE_NO_STEP = new I18nizableText("plugin.forms", "PLUGINS_FORMS_UITOOL_ENTRY_WORKFLOW_NO_WORKFLOW");
059    
060    /** The form properties manager. */
061    protected FormPropertiesManager _formPropertiesManager;
062    
063    /** The form data manager. */
064    protected FormTableManager _formTableManager;
065    
066    /** The ametys object resolver. */
067    protected AmetysObjectResolver _resolver;
068    
069    /** The workflow provider */
070    protected WorkflowProvider _workflowProvider;
071        
072    /** Component gathering utility methods for internationalizable text */
073    protected I18nUtils _i18nUtils;
074
075    @Override
076    public void service(ServiceManager serviceManager) throws ServiceException
077    {
078        super.service(serviceManager);
079        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
080        _formPropertiesManager = (FormPropertiesManager) serviceManager.lookup(FormPropertiesManager.ROLE);
081        _formTableManager = (FormTableManager) serviceManager.lookup(FormTableManager.ROLE);
082        _workflowProvider = (WorkflowProvider) serviceManager.lookup(WorkflowProvider.ROLE);
083        _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE);
084    }
085    
086    @Override
087    public void generate() throws IOException, SAXException, ProcessingException
088    {
089        String siteName = parameters.getParameter("site", "");
090        String formId = parameters.getParameter("id", "");
091        int start = parameters.getParameterAsInteger("start", 0);
092        int limit = parameters.getParameterAsInteger("limit", Integer.MAX_VALUE);
093        
094        if (StringUtils.isEmpty(siteName) || StringUtils.isEmpty(formId))
095        {
096            throw new ProcessingException("The site name and form ID must be provided.");
097        }
098        
099        try
100        {
101            Form form = _formPropertiesManager.getForm(siteName, formId);
102            
103            if (form == null)
104            {
105                throw new ProcessingException("The form of ID '" + formId + " can't be found in the site '" + siteName + "'.");
106            }
107            
108            Map<String, FieldValue> columns = _formTableManager.getColumns(form);
109            List<UserEntry> entries = _formTableManager.getSubmissions(form, columns, start, limit, null);
110            int totalSubmissions = _formTableManager.getTotalSubmissions(form.getId());
111            
112            contentHandler.startDocument();
113            
114            AttributesImpl atts = new AttributesImpl();
115            atts.addCDATAAttribute("id", form.getId());
116            atts.addCDATAAttribute("label", form.getLabel());
117            atts.addCDATAAttribute("total", String.valueOf(totalSubmissions));
118            
119            XMLUtils.startElement(contentHandler, "form", atts);
120            
121            XMLUtils.startElement(contentHandler, "columns");
122            for (FieldValue column : columns.values())
123            {
124                atts.clear();
125                atts.addCDATAAttribute("id", column.getColumnName());
126                atts.addCDATAAttribute("label", column.getField().getLabel());
127                atts.addCDATAAttribute("type", column.getField().getType().toString());
128                atts.addCDATAAttribute("field-name", column.getField().getName());
129                
130                Map<String, String> properties = column.getField().getProperties();
131                if (properties.containsKey("regexptype"))
132                {
133                    atts.addCDATAAttribute("regexptype", properties.get("regexptype"));
134                }
135                
136                XMLUtils.createElement(contentHandler, "column", atts);
137            }
138            XMLUtils.endElement(contentHandler, "columns");
139            
140            Workflow workflow = _workflowProvider.getExternalWorkflow(JdbcWorkflowStore.ROLE);
141            for (UserEntry entry : entries)
142            {
143                _saxUserEntry(entry, workflow);
144            }
145            
146            XMLUtils.endElement(contentHandler, "form");
147            contentHandler.endDocument();
148        }
149        catch (FormsException e)
150        {
151            getLogger().error("An error occurred while getting the results of a form.", e);
152            throw new ProcessingException("An error occurred while getting the results of a form.", e);
153        }
154    }
155    
156    /**
157     * Sax a user entry.
158     * @param entry the user entry.
159     * @param workflow the workflow component for form entries
160     * @throws IOException if an I/O error occurs.
161     * @throws SAXException if an error occurs generating the XML.
162     * @throws ProcessingException if a processing error occurs.
163     */
164    protected void _saxUserEntry(UserEntry entry, Workflow workflow) throws IOException, SAXException, ProcessingException
165    {
166        AttributesImpl atts = new AttributesImpl();
167        atts.addCDATAAttribute("id", Integer.toString(entry.getId()));
168        atts.addCDATAAttribute("submission-date", _DATE_FORMAT.format(entry.getCreationDate()));
169        
170        // Workflow step
171        Integer workflowId = entry.getWorkflowId();
172        if (workflowId != null)
173        {
174            _saxWorkflowStep (atts, workflow, workflowId);
175        }
176        else
177        {
178            atts.addCDATAAttribute("workflowStep", _i18nUtils.translate(__MESSAGE_NO_STEP));
179        }
180        
181        XMLUtils.startElement(contentHandler, "entry", atts);
182        
183        for (FieldValue fdValue : entry.getValues())
184        {
185            atts.clear();
186            atts.addCDATAAttribute("id", fdValue.getColumnName());
187
188            String defaultValue = fdValue.getField().getProperties().get("value");
189            if (StringUtils.trimToNull(fdValue.getField().getProperties().get("value")) != null)
190            {
191                atts.addCDATAAttribute("defaultvalue", defaultValue);
192            }
193            
194            String displayValue = "";
195            Object rawValue = fdValue.getValue();
196            if (rawValue == null)
197            {
198                atts.addCDATAAttribute("null", "true");
199            }
200            else
201            {
202                displayValue = String.valueOf(rawValue);
203                if (fdValue.getField().getType().equals(FieldType.SELECT) || fdValue.getField().getType().equals(FieldType.RADIO))
204                {
205                    atts.addCDATAAttribute("value", String.valueOf(rawValue));
206                    displayValue = _formPropertiesManager.getDisplayValue(fdValue.getField(), String.valueOf(rawValue));
207                }
208            }
209            
210            XMLUtils.createElement(contentHandler, "field", atts, displayValue);
211        }
212        
213        XMLUtils.endElement(contentHandler, "entry");
214    }
215    
216    /**
217     * SAX the workflow step
218     * @param attrs The XML attributes
219     * @param workflow the workflow component for form entries
220     * @param workflowId The workflow id
221     */
222    protected void _saxWorkflowStep (AttributesImpl attrs, Workflow workflow, int workflowId)
223    {
224        String workflowName = workflow.getWorkflowName(workflowId);
225        Step step = (Step) workflow.getCurrentSteps(workflowId).iterator().next();
226        
227        WorkflowDescriptor workflowDescriptor = workflow.getWorkflowDescriptor(workflowName);
228        int stepId = step.getStepId();
229        attrs.addCDATAAttribute("workflowStepId", String.valueOf(stepId));
230        
231        StepDescriptor stepDescriptor = workflowDescriptor.getStep(stepId);
232        
233        I18nizableText workflowStepName = stepDescriptor == null ? __MESSAGE_NO_STEP : new I18nizableText("application", stepDescriptor.getName());
234        attrs.addCDATAAttribute("workflowStep", _i18nUtils.translate(workflowStepName));
235        
236        if ("application".equals(workflowStepName.getCatalogue()))
237        {
238            attrs.addCDATAAttribute("workflowStepIcon", "/plugins/cms/resources_workflow/" + workflowStepName.getKey() + "-small.png");
239        }
240        else
241        {
242            String pluginName = workflowStepName.getCatalogue().substring("plugin.".length());
243            attrs.addCDATAAttribute("workflowStepIcon", "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + "-small.png");
244        }
245    }
246    
247    
248
249}