Package org.openfaces.renderkit.timetable

Source Code of org.openfaces.renderkit.timetable.TimetableViewRenderer

/*
* OpenFaces - JSF Component Library 2.0
* Copyright (C) 2007-2012, TeamDev Ltd.
* licensing@openfaces.org
* Unless agreed in writing the contents of this file are subject to
* the GNU Lesser General Public License Version 2.1 (the "LGPL" License).
* This library 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.
* Please visit http://openfaces.org/licensing/ for more details.
*/
package org.openfaces.renderkit.timetable;

import org.openfaces.component.timetable.*;
import org.openfaces.org.json.JSONArray;
import org.openfaces.org.json.JSONException;
import org.openfaces.org.json.JSONObject;
import org.openfaces.renderkit.AjaxPortionRenderer;
import org.openfaces.renderkit.cssparser.CSSUtil;
import org.openfaces.util.Components;
import org.openfaces.util.DataUtil;
import org.openfaces.util.Rendering;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

/**
* @author Dmitry Pikhulya
* @author Roman Porotnikov
*/
public abstract class TimetableViewRenderer extends TimetableRendererBase implements AjaxPortionRenderer {
    public static final String USE_RESOURCE_SEPARATION_MODE_ATTR = "_of_useResourceSeparationMode";
    public static final String EVENTEDITOR_RESOURCES_ATTR = "_resources";

    protected void encodeActionBar(FacesContext context, TimetableView timetableView) throws IOException {
        EventActionBar bar = timetableView.getEventActionBar();
        if (bar != null) {
            String barClientId = bar.getClientId(context);
            Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
            String alreadyRenderedBarsKey = TimetableViewRenderer.class + ".encodeActionBar().alreadyRenderedBars";
            Set<String> alreadyRenderedBars = (Set<String>) requestMap.get(alreadyRenderedBarsKey);
            if (alreadyRenderedBars == null) {
                alreadyRenderedBars = new HashSet<String>();
                requestMap.put(alreadyRenderedBarsKey, alreadyRenderedBars);
            }
            if (!alreadyRenderedBars.contains(barClientId)) {
                bar.encodeAll(context);
                alreadyRenderedBars.add(barClientId);
            }
        }
    }

    protected void encodeEventPreview(FacesContext context, TimetableView timetableView) throws IOException {
        EventPreview preview = timetableView.getEventPreview();
        if (preview != null) {
            preview.encodeAll(context);
        }
    }

    protected void encodeEventEditor(FacesContext context, TimetableView timetableView, List<TimetableResource> resources) throws IOException {
        UIComponent eventEditor = timetableView.getEventEditor();
        if (eventEditor == null) {
            eventEditor = Components.getOrCreateFacet(context, timetableView,
                    EventEditorDialog.COMPONENT_TYPE, "eventEditor", "_eventEditor", EventEditorDialog.class);
        }
        if (eventEditor instanceof EventEditorDialog)
            ((EventEditorDialog) eventEditor).setVisible(false);
        eventEditor.getAttributes().put(EVENTEDITOR_RESOURCES_ATTR, resources);
        eventEditor.encodeAll(context);
        eventEditor.getAttributes().remove(EVENTEDITOR_RESOURCES_ATTR);
    }

    protected void decodeTimetableChanges(FacesContext context, TimetableView timetableView) {
        Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();

        String changesKey = timetableView.getClientId(context) + Rendering.CLIENT_ID_SUFFIX_SEPARATOR + "timetableChanges";
        String timetableChangesStr = requestParams.get(changesKey);
        if (timetableChangesStr == null)
            return;

        TimetableEvent[] addedEvents;
        TimetableEvent[] editedEvents;
        String[] removedEventIds;
        try {
            JSONObject timetableChanges = new JSONObject(timetableChangesStr);
            Object addedEventsArray = timetableChanges.get("addedEvents");
            Object editedEventsObj = timetableChanges.get("editedEvents");
            Object removedEventIdsObj = timetableChanges.get("removedEventIds");

            TimeZone timeZone = (timetableView.getTimeZone() != null)
                    ? timetableView.getTimeZone()
                    : TimeZone.getDefault();

            addedEvents = eventsFromJSONArray(timeZone, addedEventsArray);
            editedEvents = eventsFromJSONArray(timeZone, editedEventsObj);
            JSONArray removedEventIdsArray = JSONObject.NULL.equals(removedEventIdsObj) ? null : (JSONArray) removedEventIdsObj;
            int removedEventCount = removedEventIdsArray != null ? removedEventIdsArray.length() : 0;
            removedEventIds = new String[removedEventCount];
            for (int i = 0; i < removedEventCount; i++) {
                removedEventIds[i] = removedEventIdsArray.getString(i);
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

        TimetableChangeEvent event = new TimetableChangeEvent(timetableView, addedEvents, editedEvents, removedEventIds);
        event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
        if (addedEvents.length > 0 || editedEvents.length > 0 || removedEventIds.length > 0)
            timetableView.queueEvent(event);
        context.getExternalContext().getRequestMap().put(getTimetableChangeEventKey(context, timetableView), event);
    }

    protected String getTimetableChangeEventKey(FacesContext context, TimetableView timetableView) {
        return "OF__TimetableChangeEvent for " + timetableView.getClientId(context);
    }

    protected TimetableEvent[] eventsFromJSONArray(TimeZone timeZone, Object arrayObj) throws JSONException {
        JSONArray array = JSONObject.NULL.equals(arrayObj) ? null : (JSONArray) arrayObj;
        int arrayLength = array != null ? array.length() : 0;
        TimetableEvent[] targetArray = new TimetableEvent[arrayLength];
        for (int i = 0; i < arrayLength; i++) {
            JSONObject eventObj = (JSONObject) array.get(i);

            TimetableEvent event = new TimetableEvent();
            event.setId((String) eventObj.opt("id"));
            event.setName(eventObj.getString("name"));
            event.setDescription(eventObj.getString("description"));
            if (!eventObj.isNull("resourceId"))
                event.setResourceId(eventObj.getString("resourceId"));
            String startStr = eventObj.getString("startStr");
            event.setStart(DataUtil.parseDateTimeFromJs(startStr, timeZone));
            String endStr = eventObj.getString("endStr");
            event.setEnd(DataUtil.parseDateTimeFromJs(endStr, timeZone));
            Object colorObj = eventObj.opt("color");
            String colorStr = JSONObject.NULL != colorObj ? (String) colorObj : null;
            event.setColor(CSSUtil.parseColor(colorStr));
            JSONObject customPropertiesObj = eventObj.optJSONObject("customProperties");
            if (customPropertiesObj != null) {
                for (Iterator<String> keys = customPropertiesObj.keys(); keys.hasNext();) {
                    String key = keys.next();
                    event.setCustomProperty(key, customPropertiesObj.getString(key));
                }
            }

            targetArray[i] = event;
        }
        return targetArray;
    }

    protected void encodeLoadEventsPortion(
            FacesContext context,
            TimetableView timetableView,
            JSONObject responseData,
            JSONObject jsonParam) throws JSONException, IOException {
        Map<String, AbstractTimetableEvent> loadedEvents = timetableView.getLoadedEvents();
        JSONArray eventsJsArray = encodeRequestedEventsArray(context, timetableView, jsonParam, loadedEvents);
        responseData.put("events", eventsJsArray);
    }

    protected abstract JSONArray encodeRequestedEventsArray(
            FacesContext context,
            TimetableView timetableView,
            JSONObject jsonParam,
            Map<String, AbstractTimetableEvent> putLoadedEventsHere) throws JSONException, IOException;


    protected JSONArray encodeEventAreas(FacesContext context, TimetableView timetableView, List<AbstractTimetableEvent> events) throws IOException {
        List<EventArea> eventAreas = timetableView.getEventAreas();
        if (eventAreas.size() > 0) {
            String eventVarName = timetableView.getEventVar();
            Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
            Object prevEventVarValue = requestMap.get(eventVarName);
            for (AbstractTimetableEvent event : events) {
                timetableView.setEvent(event);
                for (EventArea eventArea : eventAreas) {
                    if (okToRenderEventArea(context, eventArea))
                        eventArea.encodeAll(context);
                }

            }
            timetableView.setEvent(null);
            requestMap.put(eventVarName, prevEventVarValue);
        }

        JSONArray areaSettings = new JSONArray();
        try {
            for (int i = 0; i < eventAreas.size(); i++) {
                EventArea eventArea = eventAreas.get(i);
                JSONObject thisAreaSettings = new JSONObject();
                thisAreaSettings.put("id", eventArea.getId());
                thisAreaSettings.put("horizontalAlignment", eventArea.getHorizontalAlignment());
                thisAreaSettings.put("verticalAlignment", eventArea.getVerticalAlignment());
                areaSettings.put(i, thisAreaSettings);
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        return areaSettings;
    }

    protected boolean okToRenderEventArea(FacesContext context, EventArea eventArea) {
        String eventAreaClientId = eventArea.getClientId(context);
        Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
        String areaIdsKey =
                TimetableViewRenderer.class + ".isEventAreaAlreadyRenderedForOtherView().areaIds";
        Set<String> areaIds = (Set<String>) requestMap.get(areaIdsKey);
        if (areaIds == null) {
            areaIds = new HashSet<String>();
            requestMap.put(areaIdsKey, areaIds);
        }
        if (areaIds.contains(eventAreaClientId)) {
            // this view must be located in a timetable, and this area must have already been rendered for another view,
            // so we should just avoid rendering it twice here
            return false;
        }
        areaIds.add(eventAreaClientId);
        return true;
    }

    protected Map<String, TimeZone> getTimeZoneParamForJSONConverter(TimetableView timetableView) {
        TimeZone timeZone = (timetableView.getTimeZone() != null)
                ? timetableView.getTimeZone()
                : TimeZone.getDefault();
        Map<String, TimeZone> timeZoneParam = new HashMap<String, TimeZone>();
        timeZoneParam.put("timeZone", timeZone);
        return timeZoneParam;
    }

    public JSONObject encodeAjaxPortion(FacesContext context,
                                        UIComponent component,
                                        String portionName,
                                        JSONObject jsonParam) throws IOException, JSONException {
        TimetableView timetableView = (TimetableView) component;
        JSONObject responseData = new JSONObject();
        if (portionName.equals("saveEventChanges")) {
            encodeSaveEventChangesPortion(context, timetableView, responseData, jsonParam);
        } else if (portionName.equals("loadEvents")) {
            encodeLoadEventsPortion(context, timetableView, responseData, jsonParam);
        } else {
            throw new IllegalArgumentException("Unknown portion name: " + portionName);
        }
        return responseData;
    }

    private void encodeSaveEventChangesPortion(
            FacesContext context,
            TimetableView timetableView,
            JSONObject responseData,
            JSONObject jsonParam) throws JSONException, IOException {
        boolean reloadAllEvents = jsonParam.getBoolean("reloadAllEvents");
        Map<String, TimeZone> timeZoneParam = getTimeZoneParamForJSONConverter(timetableView);

        TimetableChangeEvent changeEvent = (TimetableChangeEvent) context.getExternalContext().getRequestMap().get(
                getTimetableChangeEventKey(context, timetableView));
        reloadAllEvents |= changeEvent.getReloadAllEvents();

        Map<String, AbstractTimetableEvent> loadedEvents = timetableView.getLoadedEvents();
        if (!reloadAllEvents) {
            TimetableEvent[] addedEvents = changeEvent.getAddedEvents();
            TimetableEvent[] changedEvents = changeEvent.getChangedEvents();
            String[] removedEventIds = changeEvent.getRemovedEventIds();
            responseData.put("addedEvents", DataUtil.arrayToJSONArray(addedEvents, timeZoneParam));
            responseData.put("editedEvents", DataUtil.arrayToJSONArray(changedEvents, timeZoneParam));
            List<AbstractTimetableEvent> events = new ArrayList<AbstractTimetableEvent>();
            events.addAll(Arrays.asList(addedEvents));
            events.addAll(Arrays.asList(changedEvents));
            encodeEventAreas(context, timetableView, events);
            for (TimetableEvent event : addedEvents) {
                String eventId = event.getId();
                if (eventId == null)
                    throw new IllegalStateException("You must assign id field for all added events inside of TimetableChangeEvent. See \"timetableChangeListener\" attribute description in " + getComponentName() + " reference.");
                loadedEvents.put(eventId, event);
            }
            for (TimetableEvent event : changedEvents) {
                loadedEvents.put(event.getId(), event);
            }
            for (String eventId : removedEventIds) {
                loadedEvents.remove(eventId);
            }

        } else {
            loadedEvents.clear();
            JSONArray requestedEvents = encodeRequestedEventsArray(context, timetableView, jsonParam, loadedEvents);
            responseData.put("reloadedEvents", requestedEvents);
        }

    }

    protected JSONObject getEditingOptionsObj(TimetableView timetableView) {
        JSONObject editingOptionsObj = new JSONObject();
        TimetableEditingOptions editingOptions = timetableView.getEditingOptions();
        Rendering.addJsonParam(editingOptionsObj, "autoSaveChanges", editingOptions.getAutoSaveChanges(), true);
        Rendering.addJsonParam(editingOptionsObj, "overlappedEventsAllowed", editingOptions.getOverlappedEventsAllowed(), true);
        Rendering.addJsonParam(editingOptionsObj, "eventResourceEditable", editingOptions.isEventResourceEditable(), true);
        Rendering.addJsonParam(editingOptionsObj, "eventDurationEditable", editingOptions.isEventDurationEditable(), true);
        Rendering.addJsonParam(editingOptionsObj, "defaultEventDuration", editingOptions.getDefaultEventDuration(), 30);
        return editingOptionsObj;
    }

    protected abstract String getComponentName();

    protected abstract String getTagName();

}
TOP

Related Classes of org.openfaces.renderkit.timetable.TimetableViewRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.