Java tutorial
/** * Copyright (C) 2000 - 2013 Silverpeas * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * As a special exception to the terms and conditions of version 3.0 of the GPL, you may * redistribute this Program in connection with Free/Libre Open Source Software ("FLOSS") * applications as described in Silverpeas's FLOSS exception. You should have recieved a copy of the * text describing the FLOSS exception, and it is also available here: * "http://www.silverpeas.org/docs/core/legal/floss_exception.html" * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see <http://www.gnu.org/licenses/>. */ package com.stratelia.webactiv.almanach.control; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.silverpeas.attachment.AttachmentServiceFactory; import org.silverpeas.attachment.model.SimpleDocument; import org.silverpeas.calendar.CalendarViewType; import org.silverpeas.date.Period; import org.silverpeas.date.PeriodType; import org.silverpeas.upload.UploadedFile; import org.silverpeas.wysiwyg.WysiwygException; import org.silverpeas.wysiwyg.control.WysiwygController; import com.silverpeas.calendar.CalendarEvent; import com.silverpeas.export.ExportException; import com.silverpeas.export.Exporter; import com.silverpeas.export.ExporterFactory; import com.silverpeas.export.ical.ExportableCalendar; import com.silverpeas.pdc.model.PdcClassification; import com.silverpeas.pdc.model.PdcPosition; import com.silverpeas.pdc.web.PdcClassificationEntity; import com.silverpeas.util.StringUtil; import com.stratelia.silverpeas.alertUser.AlertUser; import com.stratelia.silverpeas.notificationManager.NotificationMetaData; import com.stratelia.silverpeas.notificationManager.NotificationParameters; import com.stratelia.silverpeas.peasCore.AbstractComponentSessionController; import com.stratelia.silverpeas.peasCore.ComponentContext; import com.stratelia.silverpeas.peasCore.MainSessionController; import com.stratelia.silverpeas.peasCore.URLManager; import com.stratelia.silverpeas.silvertrace.SilverTrace; import com.stratelia.silverpeas.util.PairObject; import com.stratelia.webactiv.almanach.control.ejb.AlmanachBadParamException; import com.stratelia.webactiv.almanach.control.ejb.AlmanachBm; import com.stratelia.webactiv.almanach.control.ejb.AlmanachException; import com.stratelia.webactiv.almanach.control.ejb.AlmanachNoSuchFindEventException; import com.stratelia.webactiv.almanach.control.ejb.AlmanachRuntimeException; import com.stratelia.webactiv.almanach.model.EventDetail; import com.stratelia.webactiv.almanach.model.EventOccurrence; import com.stratelia.webactiv.almanach.model.EventPK; import com.stratelia.webactiv.almanach.model.PeriodicityException; import com.stratelia.webactiv.beans.admin.ComponentInstLight; import com.stratelia.webactiv.beans.admin.OrganizationController; import com.stratelia.webactiv.beans.admin.SpaceInstLight; import com.stratelia.webactiv.util.EJBUtilitaire; import com.stratelia.webactiv.util.FileRepositoryManager; import com.stratelia.webactiv.util.FileServerUtils; import com.stratelia.webactiv.util.JNDINames; import com.stratelia.webactiv.util.ResourceLocator; import com.stratelia.webactiv.util.exception.SilverpeasException; import com.stratelia.webactiv.util.exception.UtilException; import org.apache.commons.io.FileUtils; import static com.silverpeas.export.ExportDescriptor.withWriter; import static com.silverpeas.pdc.model.PdcClassification.NONE_CLASSIFICATION; import static com.silverpeas.pdc.model.PdcClassification.aPdcClassificationOfContent; import static com.silverpeas.util.StringUtil.isDefined; import static com.stratelia.webactiv.util.DateUtil.parse; import static org.silverpeas.calendar.CalendarViewType.*; /** * The AlmanachSessionController provides features to handle almanachs and theirs events. A such * object wraps in fact the current almanach in the user session; in others words, the almanach on * which the user works currently. As the almanach is displayed in a given window time, the * AlmanachSessionController instance maintains the current opened window time and provides a way to * move this window front or back in the time. The window time depends on the view mode choosen by * the user: it can be a monthly view, a weekly view, and so on. */ public class AlmanachSessionController extends AbstractComponentSessionController { private AlmanachBm almanachBm = null; private Calendar currentDay = Calendar.getInstance(); private EventDetail currentEvent; private static final String AE_MSG1 = "almanach.ASC_NoSuchFindEvent"; // Almanach Agregation private List<String> agregateAlmanachsIds = new ArrayList<String>(); private static final String ALMANACHS_IN_SUBSPACES = "0"; private static final String ALMANACHS_IN_SPACE_AND_SUBSPACES = "1"; private static final String ALL_ALMANACHS = "2"; private static final String ACCESS_ALL = "0"; private static final String ACCESS_SPACE = "1"; private static final String ACCESS_NONE = "3"; private static final String ICS_PREFIX = "almanach"; private static final String DEFAULT_VIEW_PARAMETER = "defaultView"; private Map<String, String> colors = null; private CalendarViewType viewMode; private OrganizationController organizationController = new OrganizationController(); /** * Constructs a new AlmanachSessionController instance. * * @param mainSessionCtrl the main session controller of the user. * @param context the context of the almanach component. */ public AlmanachSessionController(MainSessionController mainSessionCtrl, ComponentContext context) { super(mainSessionCtrl, context, "org.silverpeas.almanach.multilang.almanach", "org.silverpeas.almanach.settings.almanachIcons", "org.silverpeas.almanach.settings.almanachSettings"); String defaultView = getComponentParameterValue(DEFAULT_VIEW_PARAMETER); if (defaultView.isEmpty()) { viewMode = MONTHLY; // backward compatibility with previous versions of the Almanach } else { viewMode = CalendarViewType.valueOf(defaultView); } } /** * Gets the current day in the current window in time. * * @return the current day. */ public Date getCurrentDay() { return currentDay.getTime(); } /** * Sets explicitly the new current day. * * @param date the date of the new current day. */ public void setCurrentDay(Date date) { currentDay.setTime(date); } /** * Gets the current event, selected by the user. * * @return the detail about the current selected event or null if no event is selected. */ public EventDetail getCurrentEvent() { return currentEvent; } /** * Sets the current event the user has selected. * * @param event the detail of the current selected event. */ public void setCurrentEvent(EventDetail event) { this.currentEvent = event; } /** * Moves the window in time to the next calendar view according to the current view mode. */ public void nextView() { switch (viewMode) { case MONTHLY: currentDay.add(Calendar.MONTH, 1); break; case WEEKLY: currentDay.add(Calendar.WEEK_OF_MONTH, 1); break; } } /** * Moves the window in time to the previous calendar view according to the current view mode. */ public void previousView() { switch (viewMode) { case MONTHLY: currentDay.add(Calendar.MONTH, -1); break; case WEEKLY: currentDay.add(Calendar.WEEK_OF_MONTH, -1); break; } } /** * Moves the window in time in a such way the current day is now today. */ public void today() { currentDay = Calendar.getInstance(); } /** * Sets the current view mode of the almanach rendering. * * @param viewMode the view mode (monthly, weekly, ...). */ public void setViewMode(final CalendarViewType viewMode) { this.viewMode = viewMode; } /** * Gets all events of the underlying almanach. * * @return a list with the details of the events registered in the almanach. * @throws AlmanachException if an error occurs while getting the list of events. */ public List<EventDetail> getAllEvents() throws AlmanachException { EventPK pk = new EventPK("", getSpaceId(), getComponentId()); return new ArrayList<EventDetail>(getAlmanachBm().getAllEvents(pk)); } /** * Gets all events resulting of the agregation of the current almanach with others'. * * @return a list with the details of the all events in the agregation of several almanachs. If * the agregation for the current almanach isn't activated, then only the events of the almanach * are returned. * @throws AlmanachException if an error occurs while getting the list of events. */ protected List<EventDetail> getAllAgregationEvents() throws AlmanachException { if (isAgregationUsed()) { return getAllEvents(getAgregateAlmanachIds()); } return getAllEvents(); } /** * Gets the count of almanachs agregated with the undermying one. * * @return the number of agregated almanachs. */ public int getAgregatedAlmanachsCount() { return getAgregateAlmanachIds().size(); } /** * Gets the events of the specified almanachs. * * @param instanceIds the identifiers of the almanachs. * @return a list with the details of the events in the specified almanachs. * @throws AlmanachException if an error occurs while getting the list of events. */ private List<EventDetail> getAllEvents(final List<String> instanceIds) throws AlmanachException { EventPK pk = new EventPK("", getSpaceId(), getComponentId()); return new ArrayList<EventDetail>( getAlmanachBm().getAllEvents(pk, instanceIds.toArray(new String[instanceIds.size()]))); } /** * Gets the detail of the event identified by the specified identifier. * * @param id the unique identifier of the event to get. * @return the detail of the event. * @throws AlmanachException if an error occurs while getting the detail of the event. * @throws AlmanachNoSuchFindEventException if no event exists with a such identifier. */ public EventDetail getEventDetail(final String id) throws AlmanachException, AlmanachNoSuchFindEventException { EventDetail detail = getAlmanachBm().getEventDetail(new EventPK(id, getSpaceId(), getComponentId())); if (detail != null) { return detail; } throw new AlmanachNoSuchFindEventException(AE_MSG1); } /** * Removes the event identified by the specified identifier. * * @param id the identifier of the event to remove. * @throws AlmanachException if an error occurs while removing the event. * @throws UtilException if an error occurs while getting the WYSIWYG content of the event. */ public void removeEvent(final String id) throws AlmanachException, UtilException, WysiwygException { SilverTrace.info("almanach", "AlmanachSessionController.removeEvent()", "root.MSG_GEN_ENTER_METHOD"); EventPK pk = new EventPK(id, getSpaceId(), getComponentId()); // remove event from DB EventDetail event = getAlmanachBm().getEventDetail(pk); getAlmanachBm().removeEvent(pk); // remove attachments from filesystem List<SimpleDocument> documents = AttachmentServiceFactory.getAttachmentService() .listDocumentsByForeignKey(pk, null); for (SimpleDocument document : documents) { AttachmentServiceFactory.getAttachmentService().deleteAttachment(document); } // Delete the Wysiwyg if exists if (WysiwygController.haveGotWysiwyg(getComponentId(), id, event.getLanguage())) { WysiwygController.deleteWysiwygAttachments(getComponentId(), id); } SilverTrace.info("almanach", "AlmanachSessionController.removeEvent()", "root.MSG_GEN_EXIT_METHOD"); } /** * Removes just an occurrence of the specified event. The occurrence is identified by its start * date. * * @param eventDetail the detail of the event to which the occurrence belongs. * @param startDate the start date of the event occurrence. * @throws ParseException if an error occurs while parsing date infomation. * @throws AlmanachException if an error occurs while removing the occurrence of the event. */ public void removeOccurenceEvent(EventDetail eventDetail, String startDate) throws ParseException, AlmanachException { SilverTrace.info("almanach", "AlmanachSessionController.removeOccurenceEvent()", "root.MSG_GEN_ENTER_METHOD"); PeriodicityException periodicityException = new PeriodicityException(); periodicityException.setPeriodicityId(Integer.parseInt(eventDetail.getPeriodicity().getPK().getId())); periodicityException.setBeginDateException(parse(startDate)); periodicityException.setEndDateException(parse(startDate)); // add exception periodicity in DB getAlmanachBm().addPeriodicityException(periodicityException); SilverTrace.info("almanach", "AlmanachSessionController.removeOccurenceEvent()", "root.MSG_GEN_EXIT_METHOD"); } /** * Adds the specified event into the underlying almanach. * * @param eventDetail the detail of the event to add. * @param uploadedFiles the files uploaded in the aim to be attached to the event. * @throws AlmanachBadParamException if the event detail isn't well defined. * @throws AlmanachException if an error occurs while adding the event. * @throws WysiwygException if an error occurs while parsing the WYSIWYG content of the event. */ public EventPK addEvent(EventDetail eventDetail, Collection<UploadedFile> uploadedFiles) throws AlmanachBadParamException, AlmanachException, WysiwygException { return addEvent(eventDetail, uploadedFiles, PdcClassificationEntity.undefinedClassification()); } /** * Adds the specified event into the underlying almanach. * * @param eventDetail the detail of the event to add. * @param uploadedFiles the files uploaded in the aim to be attached to the event. * @throws AlmanachBadParamException if the event detail isn't well defined. * @throws AlmanachException if an error occurs while adding the event. * @throws WysiwygException if an error occurs while parsing the WYSIWYG content of the event. */ public EventPK addEvent(EventDetail eventDetail, Collection<UploadedFile> uploadedFiles, PdcClassificationEntity classification) throws AlmanachBadParamException, AlmanachException, WysiwygException { SilverTrace.info("almanach", "AlmanachSessionController.addEvent()", "root.MSG_GEN_ENTER_METHOD"); EventPK eventPK = new EventPK("", "useless", getComponentId()); eventDetail.setPK(eventPK); eventDetail.setDelegatorId(getUserId()); PdcClassification withClassification = NONE_CLASSIFICATION; if (!classification.isUndefined()) { List<PdcPosition> pdcPositions = classification.getPdcPositions(); withClassification = aPdcClassificationOfContent(eventDetail.getId(), eventDetail.getInstanceId()) .withPositions(pdcPositions); } // Add the event String eventId = getAlmanachBm().addEvent(eventDetail, uploadedFiles, withClassification); eventPK.setId(eventId); Date startDate = eventDetail.getStartDate(); // currentDay if (startDate != null) { setCurrentDay(startDate); } // Add the wysiwyg content SilverTrace.info("almanach", "AlmanachSessionController.addEvent()", "root.MSG_GEN_EXIT_METHOD"); return eventPK; } /** * Updates the specified event into the underlying almanach. * * @param eventDetail the detail of the event to update. * @throws AlmanachBadParamException if the event detail isn't well defined. * @throws AlmanachException if an error occurs while updating the event. * @throws WysiwygException if an error occurs while parsing the WYSIWYG content of the event. */ public void updateEvent(EventDetail eventDetail) throws AlmanachBadParamException, AlmanachException, WysiwygException { SilverTrace.info("almanach", "AlmanachSessionController.updateEvent()", "root.MSG_GEN_ENTER_METHOD"); eventDetail.getPK().setSpace(getSpaceId()); eventDetail.getPK().setComponentName(getComponentId()); // Update event getAlmanachBm().updateEvent(eventDetail); Date startDate = eventDetail.getStartDate(); // currentDay if (startDate != null) { setCurrentDay(startDate); } // Update the Wysiwyg if exists, create one otherwise if (isDefined(eventDetail.getWysiwyg())) { WysiwygController.updateFileAndAttachment(eventDetail.getDescription(getLanguage()), getComponentId(), eventDetail.getId(), getUserId(), getLanguage()); } else { WysiwygController.createFileAndAttachment(eventDetail.getDescription(getLanguage()), eventDetail.getPK(), getUserId(), getLanguage()); } SilverTrace.info("almanach", "AlmanachSessionController.updateEvent()", "root.MSG_GEN_EXIT_METHOD"); } /** * Indexes the specified event for the Silverpeas search engine. * * @param event the detail of the event to index. * @throws AlmanachException if an error occurs while indexing the event. */ public void indexEvent(EventDetail event) throws AlmanachException { getAlmanachBm().createIndex(event); } /** * Gets the remote business object for handling almanachs and events. * * @return the remote business object. * @throws AlmanachException if an error occurs while getting the remote object. */ protected AlmanachBm getAlmanachBm() throws AlmanachException { if (almanachBm == null) { try { almanachBm = EJBUtilitaire.getEJBObjectRef(JNDINames.ALMANACHBM_EJBHOME, AlmanachBm.class); } catch (Exception e) { throw new AlmanachException("AlmanachSessionControl.getAlmanachBm()", SilverpeasException.ERROR, "almanach.EX_EJB_CREATION_FAIL", e); } } return almanachBm; } /** * Sets a specific reference to a remote Almanach business object * * @param anAlmanachBm the reference to a remote business object. */ protected void setAlmanachBm(final AlmanachBm anAlmanachBm) { this.almanachBm = anAlmanachBm; } /** * Builds a PDF document with the events of the underlying almanach and that satisfy the specified * criteria key. * * @param mode the criteria key. * @return the content of the PDF document as a String. */ public String buildPdf(final String mode) { String name = "almanach" + System.currentTimeMillis() + ".pdf"; try { AlmanachPdfGenerator.buildPdf(name, this, mode); } catch (AlmanachRuntimeException ex) { SilverTrace.warn("almanach", "AlmanachSessionController.buildPdf()", "almanach.MSG_BUILD_PDF_FAIL", ex); return null; } return FileServerUtils.getUrlToTempDir(name); } /** * Is this almanach instance is parameterized to use the classification plan (PdC) to classify the * events on it. */ public boolean isPdcUsed() { return StringUtil.getBooleanValue(getComponentParameterValue("usepdc")); } /** * Is the weekend is taken in charge by the current underlying almanach? * * @return true if the weekend should be displayed for the current almanach, false otherwise. */ public boolean isWeekendNotVisible() { return StringUtil.getBooleanValue(getComponentParameterValue("weekendNotVisible")); } /** * Is RSS information exists for the events in the current underlying almanach? * * @return true if the RSS stream is supported for the current almanach, false otherwise. */ private boolean isUseRss() { return StringUtil.getBooleanValue(getComponentParameterValue("rss")); } /* * (non-Javadoc) @see * com.stratelia.silverpeas.peasCore.AbstractComponentSessionController#getRSSUrl () */ @Override public String getRSSUrl() { if (isUseRss()) { return super.getRSSUrl(); } return null; } /** * Is the agregation is activated for the current underlying almanach? * * @return true if the agregation is used for the current almanach, false otherwise. */ public boolean isAgregationUsed() { return StringUtil.getBooleanValue(getComponentParameterValue("useAgregation")); } /** * Gets policy currently in use to access to the data of the current almanach. * * @return the policy identifier. */ private String getAccessPolicy() { String param = getComponentParameterValue("directAccess"); if (!isDefined(param)) { return ACCESS_ALL; } return param; } /** * Gets the others almanach instances that are accessible from the current underlying almanach * instance. * * @return a list of DTO carrying information about the others almanach instances. */ public List<AlmanachDTO> getAccessibleInstances() { List<AlmanachDTO> accessibleInstances = new ArrayList<AlmanachDTO>(); if (ACCESS_NONE.equals(getAccessPolicy())) { return null; } boolean inCurrentSpace = true; boolean inAllSpaces = ACCESS_ALL.equals(getAccessPolicy()); // Get almanachIds String[] instanceIds = organizationController.getAllComponentIdsRecur(getSpaceId(), getUserId(), getComponentRootName(), inCurrentSpace, inAllSpaces); SilverTrace.info("almanach", "AlmanachSessionController.getAccessibleInstances()", "root.MSG_GEN_PARAM_VALUE", "instanceIds=" + instanceIds + " spaceId=" + getSpaceId()); if (instanceIds.length > 1) { for (String instanceId : instanceIds) { SilverTrace.info("almanach", "AlmanachSessionController.getAccessibleInstances()", "root.MSG_GEN_PARAM_VALUE", "instanceId=" + instanceId); ComponentInstLight almanachInst = organizationController.getComponentInstLight(instanceId); boolean keepIt; if (ACCESS_SPACE.equals(getAccessPolicy())) { keepIt = almanachInst.getDomainFatherId().equals(getSpaceId()); } else { keepIt = true; } if (keepIt) { SpaceInstLight si = organizationController .getSpaceInstLightById(almanachInst.getDomainFatherId()); String url = URLManager.getApplicationURL() + URLManager.getURL(null, instanceId); AlmanachDTO almanach = new AlmanachDTO().setInstanceId(instanceId) .setLabel(almanachInst.getLabel()).setSpaceId(si.getName()).setUrl(url); accessibleInstances.add(almanach); } } } return accessibleInstances; } /** * Gets the identifier of the specified event as a Silverpeas object (an object that have a * content that can be managed in Silverpeas). * * @param eventId the identifier of the event. * @return the identifier of the Silverpeas object that represents the specified event. * @throws AlmanachBadParamException if parameter is invalid; it doesn't represent an event * identifier. * @throws AlmanachException if the operation fail. */ public int getSilverObjectId(final String eventId) throws AlmanachBadParamException, AlmanachException { return getAlmanachBm().getSilverObjectId(new EventPK(eventId, getSpaceId(), getComponentId())); } /** * Get the color of the almanach * * @author dlesimple * @param instanceId * @return color of almanach */ public String getAlmanachColor(final String instanceId) { //if (colors == null) { colors = new HashMap<String, String>(); colors.put(getComponentId(), getAlmanachColor(0)); List<AlmanachDTO> almanachs = getAggregatedAlmanachs(); if (almanachs != null) { for (AlmanachDTO almanach : almanachs) { colors.put(almanach.getInstanceId(), almanach.getColor()); } } //} return colors.get(instanceId); } /** * Gets the almanachs that can be aggregated with the curren t underlying one. * * @return a list of AlmanachDTO instances, each of them carrying some data about an almanach. */ public List<AlmanachDTO> getAggregatedAlmanachs() { List<AlmanachDTO> aggregatedAlmanachs = new ArrayList<AlmanachDTO>(); String agregationMode = getSettings().getString("almanachAgregationMode", ALMANACHS_IN_SUBSPACES); String[] instanceIds; boolean inCurrentSpace = false; boolean inAllSpaces = false; if (agregationMode.equals(ALMANACHS_IN_SPACE_AND_SUBSPACES)) { inCurrentSpace = true; } else if (agregationMode.equals(ALL_ALMANACHS)) { inCurrentSpace = true; inAllSpaces = true; } instanceIds = organizationController.getAllComponentIdsRecur(getSpaceId(), getUserId(), getComponentRootName(), inCurrentSpace, inAllSpaces); SilverTrace.debug("almanach", "AlmanachSessionController.getOthersAlmanachs()", "root.MSG_GEN_PARAM_VALUE", "instanceIds=" + instanceIds + " spaceId=" + getSpaceId()); for (int i = 0; i < instanceIds.length; i++) { String instanceId = instanceIds[i]; if (!instanceId.equals(getComponentId())) { ComponentInstLight almanachInst = organizationController.getComponentInstLight(instanceId); AlmanachDTO almanach = new AlmanachDTO().setInstanceId(instanceId) .setAggregated(isAlmanachAgregated(instanceId)).setColor(getAlmanachColor(i + 1)) .setLabel(almanachInst.getLabel()); aggregatedAlmanachs.add(almanach); } } return aggregatedAlmanachs; } /** * Is the specified almanach is agregated with the current underlying one. * * @param almanachId the unique identifier of the almanach instance. * @return boolean true if the almanach is currently agregated with the current one. */ public boolean isAlmanachAgregated(final String almanachId) { for (String anAlmanachId : getAgregateAlmanachIds()) { if (anAlmanachId.equals(almanachId)) { return true; } } return false; } /** * Clears the list of the agregated almanachs. */ private void clearAgregatedAlmanachs() { getAgregateAlmanachIds().clear(); } /** * Updates the list of the agregated almanachs with the specified ones. * * @param instanceIds the identifier of the new agregated almanachs. */ public void updateAgregatedAlmanachs(final String[] instanceIds) { clearAgregatedAlmanachs(); if (instanceIds != null && instanceIds.length > 0) { getAgregateAlmanachIds().addAll(Arrays.asList(instanceIds)); } } /** * Gets the color with which the events in an almanach should be rendered. * * @author dlesimple * @param position in the array of supported colors. 0 is for the current almanach, other * positions are for the agregated almanachs. * @return the HTML/CSS code of the color. */ private String getAlmanachColor(int position) { String almanachColor = getSettings().getString("almanachColor" + position, ""); return almanachColor; } /** * @param eventId * @return * @throws * @throws AlmanachException * @throws AlmanachNoSuchFindEventException */ public String initAlertUser(final String eventId) throws AlmanachException, AlmanachNoSuchFindEventException { AlertUser sel = getAlertUser(); sel.resetAll(); sel.setHostSpaceName(getSpaceLabel()); sel.setHostComponentId(getComponentId()); PairObject hostComponentName = new PairObject(getComponentLabel(), null); sel.setHostComponentName(hostComponentName); SilverTrace.debug("almanach", "AlmanachSessionController.initAlertUser()", "root.MSG_GEN_PARAM_VALUE", "name = " + hostComponentName + " componentId=" + getComponentId()); sel.setNotificationMetaData(getAlertNotificationEvent(eventId)); // l'url de nav vers alertUserPeas et demande AlertUser et retourne return AlertUser.getAlertUserURL(); } private synchronized NotificationMetaData getAlertNotificationEvent(final String eventId) throws AlmanachException { // cration des donnes ... EventPK eventPK = new EventPK(eventId, getSpaceId(), getComponentId()); String senderName = getUserDetail().getDisplayedName(); EventDetail eventDetail = getAlmanachBm().getEventDetail(eventPK); SilverTrace.debug("alamanch", "AlamanachSessionController.getAlertNotificationEvent()", "root.MSG_GEN_PARAM_VALUE", "event = " + eventDetail.toString()); // recherche de lemplacement de lvnement String htmlPath = getAlmanachBm().getHTMLPath(eventPK); // cration des messages ... ResourceLocator message = new ResourceLocator("org.silverpeas.almanach.multilang.almanach", "fr"); ResourceLocator message_en = new ResourceLocator("org.silverpeas.almanach.multilang.almanach", "en"); // notifications en franais String subject = getNotificationSubject(message); String body = getNotificationBody(eventDetail, htmlPath, message, senderName); SilverTrace.debug("almanach", "AlamanachSessionController.getAlertNotificationEvent()", "root.MSG_GEN_PARAM_VALUE", "message = " + message.toString() + " message_en = " + message_en.toString()); SilverTrace.debug("almanach", "AlamanachSessionController.getAlertNotificationEvent()", "root.MSG_GEN_PARAM_VALUE", "sujet = " + subject + " corps = " + body); // english notifications String subject_en = getNotificationSubject(message_en); String body_en = getNotificationBody(eventDetail, htmlPath, message_en, senderName); SilverTrace.debug("almanach", "AlmanachSessionController.getAlertNotificationEvent()", "root.MSG_GEN_PARAM_VALUE", "sujet_en = " + subject_en + " corps_en = " + body_en); // cration des notifications NotificationMetaData notifMetaData = new NotificationMetaData(NotificationParameters.NORMAL, subject, body); notifMetaData.addLanguage("en", subject_en, body_en); notifMetaData.setLink(getObjectUrl(eventDetail)); notifMetaData.setComponentId(eventPK.getInstanceId()); notifMetaData.setSender(getUserId()); return notifMetaData; } private String getNotificationSubject(final ResourceLocator message) { return message.getString("notifSubject"); } private String getNotificationBody(final EventDetail eventDetail, final String htmlPath, final ResourceLocator message, final String senderName) { StringBuilder messageText = new StringBuilder(); messageText.append(senderName).append(" "); messageText.append(message.getString("notifInfo")).append(" "); messageText.append(eventDetail.getName()).append(" "); messageText.append(message.getString("notifInfo2")).append("\n\n"); messageText.append(message.getString("path")).append(" : ").append(htmlPath); return messageText.toString(); } private String getObjectUrl(EventDetail eventDetail) { return URLManager.getURL(null, getComponentId()) + eventDetail.getURL(); } @Override public void close() { if (almanachBm != null) { almanachBm = null; } } /** * Update event occurence (cas particulier de modification d'une occurence d'vnement priodique) * * @param event * @param dateDebutIteration * @param dateFinIteration * @throws AlmanachBadParamException * @throws AlmanachException * @throws WysiwygException * @throws ParseException */ public void updateEventOccurence(final EventDetail event, final String dateDebutIteration, final String dateFinIteration) throws AlmanachBadParamException, AlmanachException, WysiwygException, ParseException { SilverTrace.info("almanach", "AlmanachSessionController.updateEventOccurence()", "root.MSG_GEN_ENTER_METHOD"); // Supprime l'occurence : exception dans la srie removeOccurenceEvent(event, dateDebutIteration); // Ajoute un nouvel vnement indpendant event.setPeriodicity(null); addEvent(event, null); SilverTrace.info("almanach", "AlmanachSessionController.updateEventOccurence()", "root.MSG_GEN_EXIT_METHOD"); } /** * Gets a view in time of the current underlying almanach. The view depends on the current * selected view mode and the current selected window in time. * * @return an AlmanachCalendarView instance. * @throws AlmanachException if an error occurs while getting the calendar view. * @throws AlmanachNoSuchFindEventException if a detail about an event in the almanach cannot be * found. */ public AlmanachCalendarView getAlmanachCalendarView() throws AlmanachException, AlmanachNoSuchFindEventException { AlmanachCalendarView view = null; switch (viewMode) { case YEARLY: view = getYearlyAlmanachCalendarView(); break; case MONTHLY: view = getMonthlyAlmanachCalendarView(); break; case WEEKLY: view = getWeekyAlmanachCalendarView(); break; case NEXT_EVENTS: view = getAlmanachCalendarViewOnTheNextEvents(isAgregationUsed()); break; default: throw new UnsupportedOperationException( "The calendar view mode " + viewMode + " isn't yet supported by the almanach"); } return view; } /** * Gets a view in the current year of the current underlying almanach. * * @return an AlmanachCalendarView instance. * @throws AlmanachException if an error occurs while getting the calendar view. * @throws AlmanachNoSuchFindEventException if a detail about an event in the almanach cannot be * found. */ public AlmanachCalendarView getYearlyAlmanachCalendarView() throws AlmanachException, AlmanachNoSuchFindEventException { AlmanachDTO almanachDTO = getAlmanachDTO(isAgregationUsed()); AlmanachCalendarView view = new AlmanachCalendarView(almanachDTO, currentDay.getTime(), YEARLY, getLanguage()); if (isWeekendNotVisible()) { view.unsetWeekendVisible(); } view.setEvents(listCurrentYearEvents(getAggregationAlmanachIds())); return view; } /** * Gets a view in the current month of the current underlying almanach. * * @return an AlmanachCalendarView instance. * @throws AlmanachException if an error occurs while getting the calendar view. * @throws AlmanachNoSuchFindEventException if a detail about an event in the almanach cannot be * found. */ public AlmanachCalendarView getMonthlyAlmanachCalendarView() throws AlmanachException, AlmanachNoSuchFindEventException { AlmanachDTO almanachDTO = getAlmanachDTO(isAgregationUsed()); AlmanachCalendarView view = new AlmanachCalendarView(almanachDTO, currentDay.getTime(), MONTHLY, getLanguage()); if (isWeekendNotVisible()) { view.unsetWeekendVisible(); } view.setEvents(listCurrentMonthEvents(getAggregationAlmanachIds())); return view; } /** * Gets a view in the current week of the current underlying almanach. * * @return an AlmanachCalendarView instance. * @throws AlmanachException if an error occurs while getting the calendar view. * @throws AlmanachNoSuchFindEventException if a detail about an event in the almanach cannot be * found. */ public AlmanachCalendarView getWeekyAlmanachCalendarView() throws AlmanachException, AlmanachNoSuchFindEventException { AlmanachDTO almanachDTO = getAlmanachDTO(isAgregationUsed()); AlmanachCalendarView view = new AlmanachCalendarView(almanachDTO, currentDay.getTime(), WEEKLY, getLanguage()); if (isWeekendNotVisible()) { view.unsetWeekendVisible(); } view.setEvents(listCurrentWeekEvents(getAggregationAlmanachIds())); return view; } /** * Gets a view on the next events that will occur and that are defined in the current underlying * almanach. * * @param aggregated is the calendar view should contains also the events of aggregated almanachs? * @return an AlmanachCalendarView instance. * @throws AlmanachException if an error occurs while getting the calendar view. * @throws AlmanachNoSuchFindEventException if a detail about an event in the almanach cannot be * found. */ public AlmanachCalendarView getAlmanachCalendarViewOnTheNextEvents(boolean aggregated) throws AlmanachException, AlmanachNoSuchFindEventException { AlmanachDTO almanachDTO = getAlmanachDTO(aggregated); AlmanachCalendarView view = new AlmanachCalendarView(almanachDTO, currentDay.getTime(), NEXT_EVENTS, getLanguage()); if (isWeekendNotVisible()) { view.unsetWeekendVisible(); } if (aggregated) { view.setEvents(listNextEvents(getAggregationAlmanachIds())); } else { view.setEvents(listNextEvents(getComponentId())); } view.setLabel(getString("almanach.nextEvents")); return view; } /** * Gets the URL of the ICS representation of the current almamach. * * @return the URL of the almanach ICS. */ public String getAlmanachICSURL() { return "/services/almanach/ics/" + getComponentId() + "?userId=" + getUserId() + "&login=" + getUserDetail().getLogin() + "&password=" + organizationController.getUserFull(getUserId()).getPassword(); } /** * Exports the current almanach in iCal format. The iCal file is generated into the temporary * directory. If there is no events to export, a NoDataToExportException exception is then thrown. * * @return the iCal file name into which is generated the current alamanch. * @throws ExportException if an error occurs while exporting the almanach in iCal format. The * errors can come from a failure on getting the events to export, the fact there is no events to * export (empty almanach) or the failure of the export process itself. * @throws IOException if an error occurs while creating or opening the file into which the export * will be done. Such errors can be come from a forbidden write granting, and so on. */ public String exportToICal() throws ExportException, IOException { String icsFileName = ICS_PREFIX + "-" + getComponentId() + ".ics"; String icsFilePath = FileRepositoryManager.getTemporaryPath() + icsFileName; List<CalendarEvent> eventsToExport; try { eventsToExport = asCalendarEvents(getAllEvents()); } catch (Exception ex) { SilverTrace.error("almanach", getClass().getSimpleName() + ".exportToICal()", "almanach.EXE_GET_ALL_EVENTS_FAIL", ex); throw new ExportException(ex.getMessage(), ex); } ExporterFactory exporterFactory = ExporterFactory.getFactory(); Exporter<ExportableCalendar> iCalExporter = exporterFactory.getICalExporter(); FileWriter fileWriter = new FileWriter(icsFilePath); try { iCalExporter.export(withWriter(fileWriter), ExportableCalendar.with(eventsToExport)); } catch (ExportException ex) { File fileToDelete = new File(icsFilePath); if (fileToDelete.exists()) { FileUtils.deleteQuietly(fileToDelete); } throw ex; } return icsFileName; } /** * Gets the occurrences of the events defined in the specified almanachs and in the current * selected year. * * @param almanachIds the identifier of the almanachs the events belongs to. * @return a list of event occurrences decorated with rendering features. * @throws AlmanachException if an error occurs while getting the list of event occurrences. * @throws AlmanachNoSuchFindEventException if the detail about an event cannot be found. */ private List<DisplayableEventOccurrence> listCurrentYearEvents(String... almanachIds) throws AlmanachException { List<EventOccurrence> occurrencesInYear = getAlmanachBm().getEventOccurrencesInPeriod( Period.from(currentDay.getTime(), PeriodType.year, getLanguage()), almanachIds); return DisplayableEventOccurrence.decorate(occurrencesInYear); } /** * Gets the occurrences of the events defined in the specified almanachs and in the current * selected month. * * @param almanachIds the identifier of the almanachs the events belongs to. * @return a list of event occurrences decorated with rendering features. * @throws AlmanachException if an error occurs while getting the list of event occurrences. * @throws AlmanachNoSuchFindEventException if the detail about an event cannot be found. */ private List<DisplayableEventOccurrence> listCurrentMonthEvents(String... almanachIds) throws AlmanachException { List<EventOccurrence> occurrencesInMonth = getAlmanachBm().getEventOccurrencesInPeriod( Period.from(currentDay.getTime(), PeriodType.month, getLanguage()), almanachIds); return DisplayableEventOccurrence.decorate(occurrencesInMonth); } /** * Gets the occurrences of the events defined in the specified almanachs and in the current * selected week. * * @param almanachIds the identifier of the almanachs the events belongs to. * @return a list of event occurrences decorated with rendering features. * @throws AlmanachException if an error occurs while getting the list of event occurrences. * @throws AlmanachNoSuchFindEventException if the detail about an event cannot be found. */ private List<DisplayableEventOccurrence> listCurrentWeekEvents(String... almanachIds) throws AlmanachException { List<EventOccurrence> occurrencesInWeek = getAlmanachBm().getEventOccurrencesInPeriod( Period.from(currentDay.getTime(), PeriodType.week, getLanguage()), almanachIds); return DisplayableEventOccurrence.decorate(occurrencesInWeek); } /** * Lists the occurrences of the next events defined in the specified almanachs. * * @param almanachIds the identifier of the almanachs the events belongs to. * @return an ordered list of event occurrences decorated with rendering features. * @throws AlmanachException if an error occurs while getting the list of event occurrences. * @throws AlmanachNoSuchFindEventException if the detail about an event cannot be found. */ private List<DisplayableEventOccurrence> listNextEvents(String... almanachIds) throws AlmanachException { List<EventOccurrence> nextOccurrences = getAlmanachBm().getNextEventOccurrences(almanachIds); return DisplayableEventOccurrence.decorate(nextOccurrences); } /** * Gets a DTO of the almanach to pass to the view. * * @param aggregated is the DTO should transfer data about an aggregated almanach? * @return a DTO of the current almanach. */ private AlmanachDTO getAlmanachDTO(boolean aggregated) { return new AlmanachDTO().setColor(getAlmanachColor(getComponentId())).setInstanceId(getComponentId()) .setLabel(getComponentLabel()).setAggregated(aggregated).setUrl(getComponentUrl()); } /** * Converts the specified details on almanach events into a calendar event. * * @param eventDetails details about some events in one or several almanachs. * @return the calendar events corresponding to the almanach events. */ private List<CalendarEvent> asCalendarEvents(final List<EventDetail> eventDetails) { CalendarEventEncoder encoder = new CalendarEventEncoder(); return encoder.encode(eventDetails); } /** * Gets the identifier of the almanachs that compound the current aggregated almanach. Among them, * the identifier of the current almanach is also provided. * * @return an array of almanach identifiers. */ private String[] getAggregationAlmanachIds() { String[] almanachIds = new String[getAgregateAlmanachIds().size() + 1]; almanachIds = getAgregateAlmanachIds().toArray(almanachIds); almanachIds[almanachIds.length - 1] = getComponentId(); return almanachIds; } private List<String> getAgregateAlmanachIds() { return agregateAlmanachsIds; } }