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}