1 21 package com.jaspersoft.jasperserver.war.action; 22 23 import java.beans.PropertyEditorSupport ; 24 import java.util.ArrayList ; 25 import java.util.Date ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Locale ; 29 import java.util.Set ; 30 import java.util.SortedSet ; 31 import java.util.TreeSet ; 32 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.springframework.beans.propertyeditors.CustomCollectionEditor; 36 import org.springframework.beans.propertyeditors.CustomDateEditor; 37 import org.springframework.beans.propertyeditors.CustomNumberEditor; 38 import org.springframework.context.MessageSource; 39 import org.springframework.context.i18n.LocaleContextHolder; 40 import org.springframework.validation.DataBinder; 41 import org.springframework.webflow.Event; 42 import org.springframework.webflow.RequestContext; 43 import org.springframework.webflow.action.FormAction; 44 45 import com.jaspersoft.jasperserver.api.JSException; 46 import com.jaspersoft.jasperserver.api.JSExceptionWrapper; 47 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJob; 48 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJobCalendarTrigger; 49 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJobMailNotification; 50 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJobRepositoryDestination; 51 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJobSimpleTrigger; 52 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJobSource; 53 import com.jaspersoft.jasperserver.api.engine.scheduling.domain.ReportJobTrigger; 54 import com.jaspersoft.jasperserver.api.engine.scheduling.service.ReportSchedulingService; 55 import com.jaspersoft.jasperserver.api.metadata.common.domain.Folder; 56 import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService; 57 import com.jaspersoft.jasperserver.war.common.JasperServerUtil; 58 import com.jaspersoft.jasperserver.war.common.LocalesList; 59 import com.jaspersoft.jasperserver.war.common.TimeZonesList; 60 import com.jaspersoft.jasperserver.war.common.UserLocale; 61 import com.jaspersoft.jasperserver.war.dto.ByteEnum; 62 63 67 public class ReportJobEditAction extends FormAction { 68 69 protected static final Log log = LogFactory.getLog(ReportJobEditAction.class); 70 71 public static final byte RECURRENCE_TYPE_NONE = 1; 72 public static final byte RECURRENCE_TYPE_SIMPLE = 2; 73 public static final byte RECURRENCE_TYPE_CALENDAR = 3; 74 75 public static final String ATTR_NAME_TRIGGER_RECURRENCE_TYPE = "triggerRecurrenceType"; 76 public static final String ATTR_NAME_TRIGGER_ALL_WEEK_DAYS = "allWeekDays"; 77 public static final String ATTR_NAME_TRIGGER_ALL_MONTHS = "allMonths"; 78 79 private MessageSource messageSource; 80 private RepositoryService repositoryService; 81 private ReportSchedulingService schedulingService; 82 private String isNewModeAttrName; 83 private String reportUnitURIAttrName; 84 private String editJobIdParamName; 85 private String contentFoldersAttrName; 86 private String outputFormatsAttrName; 87 private String intervalUnitsAttrName; 88 89 private LocalesList localesList; 90 private String localesAttrName; 91 92 private TimeZonesList timeZonesList; 93 private String timeZonesAttrName; 94 95 private MailAddressesEditor mailAddressesEditor; 96 private CustomDateEditor customDateEditor; 97 private CustomNumberEditor customNumberEditor; 98 private CustomCollectionEditor byteSetEditor; 99 private CustomCollectionEditor byteSortedSetEditor; 100 101 private final List intervalUnits; 102 private final List allOutputFormats; 103 private final List weekDays; 104 private final List months; 105 106 public ReportJobEditAction() { 107 intervalUnits = getRecurrenceIntervalUnits(); 108 allOutputFormats = getOutputFormats(); 109 weekDays = getWeekDays(); 110 months = getMonths(); 111 } 112 113 protected List getRecurrenceIntervalUnits() { 114 List intervalUnitsList = new ArrayList (); 115 intervalUnitsList.add(new ByteEnum(ReportJobSimpleTrigger.INTERVAL_MINUTE, "job.interval.unit.minute.label")); 116 intervalUnitsList.add(new ByteEnum(ReportJobSimpleTrigger.INTERVAL_HOUR, "job.interval.unit.hour.label")); 117 intervalUnitsList.add(new ByteEnum(ReportJobSimpleTrigger.INTERVAL_DAY, "job.interval.unit.day.label")); 118 intervalUnitsList.add(new ByteEnum(ReportJobSimpleTrigger.INTERVAL_WEEK, "job.interval.unit.week.label")); 119 return intervalUnitsList; 120 } 121 122 protected List getOutputFormats() { 123 List allOutputFormatsList = new ArrayList (); 124 allOutputFormatsList.add(new ByteEnum(ReportJob.OUTPUT_FORMAT_PDF, "report.output.pdf.label")); 125 allOutputFormatsList.add(new ByteEnum(ReportJob.OUTPUT_FORMAT_HTML, "report.output.html.label")); 126 allOutputFormatsList.add(new ByteEnum(ReportJob.OUTPUT_FORMAT_XLS, "report.output.xls.label")); 127 allOutputFormatsList.add(new ByteEnum(ReportJob.OUTPUT_FORMAT_RTF, "report.output.rtf.label")); 128 return allOutputFormatsList; 129 } 130 131 protected List getWeekDays() { 132 List weekDaysList = new ArrayList (); 133 weekDaysList.add(new ByteEnum((byte) 2, "week.days.label.mon")); 134 weekDaysList.add(new ByteEnum((byte) 3, "week.days.label.tue")); 135 weekDaysList.add(new ByteEnum((byte) 4, "week.days.label.wen")); 136 weekDaysList.add(new ByteEnum((byte) 5, "week.days.label.thu")); 137 weekDaysList.add(new ByteEnum((byte) 6, "week.days.label.fri")); 138 weekDaysList.add(new ByteEnum((byte) 7, "week.days.label.sat")); 139 weekDaysList.add(new ByteEnum((byte) 1, "week.days.label.sun")); 140 return weekDaysList; 141 } 142 143 protected List getMonths() { 144 List monthsList = new ArrayList (); 145 monthsList.add(new ByteEnum((byte) 1, "monts.label.jan")); 146 monthsList.add(new ByteEnum((byte) 2, "monts.label.feb")); 147 monthsList.add(new ByteEnum((byte) 3, "monts.label.mar")); 148 monthsList.add(new ByteEnum((byte) 4, "monts.label.apr")); 149 monthsList.add(new ByteEnum((byte) 5, "monts.label.may")); 150 monthsList.add(new ByteEnum((byte) 6, "monts.label.jun")); 151 monthsList.add(new ByteEnum((byte) 7, "monts.label.jul")); 152 monthsList.add(new ByteEnum((byte) 8, "monts.label.aug")); 153 monthsList.add(new ByteEnum((byte) 9, "monts.label.sep")); 154 monthsList.add(new ByteEnum((byte) 10, "monts.label.oct")); 155 monthsList.add(new ByteEnum((byte) 11, "monts.label.nov")); 156 monthsList.add(new ByteEnum((byte) 12, "monts.label.dec")); 157 return monthsList; 158 } 159 160 public void afterPropertiesSet() throws Exception { 161 super.afterPropertiesSet(); 162 163 mailAddressesEditor = new MailAddressesEditor(); 164 customDateEditor = new CustomDateEditor(JasperServerUtil.createCalendarDateTimeFormat(getMessageSource()), true); 165 customNumberEditor = new CustomNumberEditor(Integer .class, true); 166 byteSetEditor = new ByteCollectionEditor(Set .class); 167 byteSortedSetEditor = new ByteCollectionEditor(SortedSet .class); 168 } 169 170 public MessageSource getMessageSource() { 171 return messageSource; 172 } 173 174 public void setMessageSource(MessageSource messageSource) { 175 this.messageSource = messageSource; 176 } 177 178 public RepositoryService getRepositoryService() 179 { 180 return repositoryService; 181 } 182 183 public void setRepositoryService(RepositoryService repositoryService) 184 { 185 this.repositoryService = repositoryService; 186 } 187 188 public ReportSchedulingService getSchedulingService() { 189 return schedulingService; 190 } 191 192 public void setSchedulingService(ReportSchedulingService schedulingService) { 193 this.schedulingService = schedulingService; 194 } 195 196 public String getEditJobIdParamName() { 197 return editJobIdParamName; 198 } 199 200 public void setEditJobIdParamName(String editJobIdParamName) { 201 this.editJobIdParamName = editJobIdParamName; 202 } 203 204 public String getIsNewModeAttrName() { 205 return isNewModeAttrName; 206 } 207 208 public void setIsNewModeAttrName(String isNewModeAttrName) { 209 this.isNewModeAttrName = isNewModeAttrName; 210 } 211 212 public String getReportUnitURIAttrName() { 213 return reportUnitURIAttrName; 214 } 215 216 public void setReportUnitURIAttrName(String reportUnitURIAttrName) { 217 this.reportUnitURIAttrName = reportUnitURIAttrName; 218 } 219 220 public String getContentFoldersAttrName() { 221 return contentFoldersAttrName; 222 } 223 224 public void setContentFoldersAttrName(String contentFoldersAttrName) { 225 this.contentFoldersAttrName = contentFoldersAttrName; 226 } 227 228 public String getOutputFormatsAttrName() { 229 return outputFormatsAttrName; 230 } 231 232 public void setOutputFormatsAttrName(String outputFormatsAttrName) { 233 this.outputFormatsAttrName = outputFormatsAttrName; 234 } 235 236 public String getIntervalUnitsAttrName() { 237 return intervalUnitsAttrName; 238 } 239 240 public void setIntervalUnitsAttrName(String intervalUnitsAttrName) { 241 this.intervalUnitsAttrName = intervalUnitsAttrName; 242 } 243 244 public String getLocalesAttrName() { 245 return localesAttrName; 246 } 247 248 public void setLocalesAttrName(String localesAttrName) { 249 this.localesAttrName = localesAttrName; 250 } 251 252 public LocalesList getLocalesList() { 253 return localesList; 254 } 255 256 public void setLocalesList(LocalesList localesList) { 257 this.localesList = localesList; 258 } 259 260 public String getTimeZonesAttrName() { 261 return timeZonesAttrName; 262 } 263 264 public void setTimeZonesAttrName(String timeZonesAttrName) { 265 this.timeZonesAttrName = timeZonesAttrName; 266 } 267 268 public TimeZonesList getTimeZonesList() { 269 return timeZonesList; 270 } 271 272 public void setTimeZonesList(TimeZonesList timeZonesList) { 273 this.timeZonesList = timeZonesList; 274 } 275 276 protected void initBinder(RequestContext context, DataBinder binder) { 277 super.initBinder(context, binder); 278 279 binder.registerCustomEditor(List .class, "mailNotification.toAddresses", mailAddressesEditor); 280 binder.registerCustomEditor(List .class, "mailNotification.ccAddresses", mailAddressesEditor); 281 binder.registerCustomEditor(List .class, "mailNotification.bccAddresses", mailAddressesEditor); 282 binder.registerCustomEditor(Date .class, customDateEditor); 283 binder.registerCustomEditor(Integer .class, customNumberEditor); 284 binder.registerCustomEditor(Set .class, "outputFormats", byteSetEditor); 285 binder.registerCustomEditor(SortedSet .class, "trigger.weekDays", byteSortedSetEditor); 286 binder.registerCustomEditor(SortedSet .class, "trigger.months", byteSortedSetEditor); 287 } 288 289 protected Object loadFormObject(RequestContext context) { 290 ReportJob job; 291 if (isNewMode(context)) { 292 job = createNewReportJob(context); 293 } else { 294 Long jobIdParam = context.getRequestParameters().getRequiredLong(getEditJobIdParamName()); 295 long jobId = jobIdParam.longValue(); 296 job = schedulingService.getScheduledJob(JasperServerUtil.getExecutionContext(context), jobId); 297 if (job == null) { 298 throw new JSException("Report job with id " + jobId + " not found."); 299 } 300 } 301 302 if (job.getMailNotification() == null) { 303 job.setMailNotification(new ReportJobMailNotification()); 304 } 305 306 return job; 307 } 308 309 protected ReportJob createNewReportJob(RequestContext context) { 310 ReportJob job; 311 job = new ReportJob(); 312 ReportJobSimpleTrigger trigger = new ReportJobSimpleTrigger(); 313 job.setTrigger(trigger); 314 job.setSource(new ReportJobSource()); 315 316 String reportUnitURI = context.getFlowScope().getString(getReportUnitURIAttrName()); 317 job.getSource().setReportUnitURI(reportUnitURI); 318 319 String reportName; 320 int lastSepIdx = reportUnitURI.lastIndexOf(Folder.SEPARATOR); 321 if (lastSepIdx >= 0) { 322 reportName = reportUnitURI.substring(lastSepIdx + Folder.SEPARATOR_LENGTH); 323 job.setBaseOutputFilename(reportName); 324 } else { 325 throw new JSException("\"" + reportUnitURI + "\" is not a valid resource URI."); 326 } 327 328 trigger.setStartType(ReportJobTrigger.START_TYPE_NOW); 329 trigger.setOccurrenceCount(1); 330 331 ReportJobRepositoryDestination repositoryDestination = new ReportJobRepositoryDestination(); 332 job.setContentRepositoryDestination(repositoryDestination); 333 334 job.addOutputFormat(ReportJob.OUTPUT_FORMAT_PDF); 335 336 return job; 337 } 338 339 protected ReportJob getReportJob(RequestContext context) throws Exception { 340 return (ReportJob) getFormObject(context); 341 } 342 343 protected boolean isNewMode(RequestContext context) { 344 Boolean isNewMode = context.getFlowScope().getBoolean(getIsNewModeAttrName()); 345 return isNewMode != null && isNewMode.booleanValue(); 346 } 347 348 public Event setNowModeDefaults(RequestContext context) throws Exception { 349 ReportJob job = getReportJob(context); 350 String jobLabel = messageSource.getMessage("report.scheduling.job.runNow.label", null, "Run once job", getUserLocale()); 351 job.setLabel(jobLabel); 352 return success(); 353 } 354 355 public Event setOutputReferenceData(RequestContext context) { 356 List folders = repositoryService.getAllFolders(JasperServerUtil.getExecutionContext(context)); 357 context.getRequestScope().put(getContentFoldersAttrName(), folders); 358 359 context.getRequestScope().put(getOutputFormatsAttrName(), allOutputFormats); 360 361 if (getLocalesList() != null) { 362 UserLocale[] userLocales = getLocalesList().getUserLocales(getUserLocale()); 363 if (userLocales != null && userLocales.length > 0) { 364 context.getRequestScope().put(getLocalesAttrName(), userLocales); 365 } 366 } 367 368 return success(); 369 } 370 371 protected Locale getUserLocale() { 372 return LocaleContextHolder.getLocale(); 373 } 374 375 public Event setTriggerReferenceData(RequestContext context) throws Exception { 376 context.getRequestScope().put(getIntervalUnitsAttrName(), intervalUnits); 377 378 ReportJob reportJob = getReportJob(context); 379 byte triggerRecurrenceType = getTriggerRecurrenceType(reportJob.getTrigger()); 380 context.getRequestScope().put(ATTR_NAME_TRIGGER_RECURRENCE_TYPE, new Byte (triggerRecurrenceType)); 381 382 if (triggerRecurrenceType == RECURRENCE_TYPE_CALENDAR) { 383 context.getRequestScope().put(ATTR_NAME_TRIGGER_ALL_WEEK_DAYS, weekDays); 384 context.getRequestScope().put(ATTR_NAME_TRIGGER_ALL_MONTHS, months); 385 } 386 387 if (getTimeZonesList() != null) { 388 List timeZones = getTimeZonesList().getTimeZones(getUserLocale()); 389 context.getRequestScope().put(getTimeZonesAttrName(), timeZones); 390 } 391 392 return success(); 393 } 394 395 protected byte getTriggerRecurrenceType(ReportJobTrigger trigger) { 396 byte type; 397 if (trigger instanceof ReportJobSimpleTrigger) { 398 ReportJobSimpleTrigger simpleTrigger = (ReportJobSimpleTrigger) trigger; 399 if (simpleTrigger.getOccurrenceCount() > 1 || 400 simpleTrigger.getOccurrenceCount() == ReportJobSimpleTrigger.RECUR_INDEFINITELY) { 401 type = RECURRENCE_TYPE_SIMPLE; 402 } else { 403 type = RECURRENCE_TYPE_NONE; 404 } 405 } else if (trigger instanceof ReportJobCalendarTrigger) { 406 type = RECURRENCE_TYPE_CALENDAR; 407 } else { 408 throw new JSException("Unknow report job trigger type \"" + trigger.getClass().getName() + "\""); 409 } 410 return type; 411 } 412 413 public Event setTriggerRecurrenceNone(RequestContext context) throws Exception { 414 ReportJob job = getReportJob(context); 415 ReportJobSimpleTrigger trigger = new ReportJobSimpleTrigger(); 416 copyCommonTriggerAttributes(trigger, job.getTrigger()); 417 trigger.setOccurrenceCount(1); 418 job.setTrigger(trigger); 419 return success(); 420 } 421 422 public Event setTriggerRecurrenceSimple(RequestContext context) throws Exception { 423 ReportJob job = getReportJob(context); 424 ReportJobSimpleTrigger trigger = new ReportJobSimpleTrigger(); 425 copyCommonTriggerAttributes(trigger, job.getTrigger()); 426 trigger.setOccurrenceCount(ReportJobSimpleTrigger.RECUR_INDEFINITELY); 427 trigger.setRecurrenceInterval(1); 428 trigger.setRecurrenceIntervalUnit(ReportJobSimpleTrigger.INTERVAL_MINUTE); 429 job.setTrigger(trigger); 430 return success(); 431 } 432 433 public Event setTriggerRecurrenceCalendar(RequestContext context) throws Exception { 434 ReportJob job = getReportJob(context); 435 ReportJobCalendarTrigger trigger = new ReportJobCalendarTrigger(); 436 copyCommonTriggerAttributes(trigger, job.getTrigger()); 437 trigger.setMinutes("0"); 438 trigger.setHours("0"); 439 trigger.setDaysType(ReportJobCalendarTrigger.DAYS_TYPE_ALL); 440 441 TreeSet selectedMonths = new TreeSet (); 442 for (Iterator it = months.iterator(); it.hasNext();) { 443 ByteEnum month = (ByteEnum) it.next(); 444 selectedMonths.add(new Byte (month.getCode())); 445 } 446 trigger.setMonths(selectedMonths); 447 448 job.setTrigger(trigger); 449 return success(); 450 } 451 452 protected void copyCommonTriggerAttributes(ReportJobTrigger newTrigger, ReportJobTrigger trigger) { 453 newTrigger.setStartType(trigger.getStartType()); 454 newTrigger.setStartDate(trigger.getStartDate()); 455 newTrigger.setEndDate(trigger.getEndDate()); 456 } 457 458 public Event saveJob(RequestContext context) throws Exception { 459 ReportJob job = getReportJob(context); 460 461 if (job.getMailNotification().isEmpty()) { 462 job.setMailNotification(null); 463 } 464 465 if (isNewMode(context)) { 466 schedulingService.scheduleJob(JasperServerUtil.getExecutionContext(context), job); 467 } else { 468 schedulingService.updateScheduledJob(JasperServerUtil.getExecutionContext(context), job); 469 } 470 return success(); 471 } 472 473 protected static class MailAddressesEditor extends PropertyEditorSupport { 474 475 public String getAsText() { 476 StringBuffer sb = new StringBuffer (); 477 List addresses = (List ) getValue(); 478 if (addresses != null && !addresses.isEmpty()) { 479 Iterator it = addresses.iterator(); 480 String address = (String ) it.next(); 481 sb.append(address); 482 while (it.hasNext()) { 483 sb.append(", "); 484 address = (String ) it.next(); 485 sb.append(address); 486 } 487 } 488 return sb.toString(); 489 } 490 491 public void setAsText(String text) throws IllegalArgumentException { 492 List addressList = new ArrayList (); 493 if (text != null && text.length() > 0) { 494 String [] addresses = text.split("\\,"); 495 for (int i = 0; i < addresses.length; i++) { 496 addressList.add(addresses[i].trim()); 497 } 498 } 499 setValue(addressList); 500 } 501 502 } 503 504 protected static class ByteCollectionEditor extends CustomCollectionEditor { 505 506 public ByteCollectionEditor(Class collectionClass) { 507 super(collectionClass); 508 } 509 510 protected Object convertElement(Object val) { 511 if (val == null || val instanceof Byte ) { 512 return val; 513 } 514 515 try { 516 return Byte.valueOf(val.toString()); 517 } catch (NumberFormatException e) { 518 log.error("error parsing byte value", e); 519 throw new JSExceptionWrapper(e); 520 } 521 } 522 523 } 524 } 525 | Popular Tags |