com.celements.calendar.Event.java Source code

Java tutorial

Introduction

Here is the source code for com.celements.calendar.Event.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.celements.calendar;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xwiki.context.Execution;
import org.xwiki.model.reference.DocumentReference;

import com.celements.calendar.plugin.CelementsCalendarPlugin;
import com.celements.calendar.util.CalendarUtils;
import com.celements.common.collections.ListUtils;
import com.celements.web.plugin.cmd.EmptyCheckCommand;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.api.Element;
import com.xpn.xwiki.api.Property;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.web.Utils;

public class Event implements IEvent {

    public static final String CLASSES_SPACE = "Classes";
    public static final String CALENDAR_EVENT_CLASS_DOC = "CalendarEventClass";
    public static final String CALENDAR_EVENT_CLASS = CLASSES_SPACE + "." + CALENDAR_EVENT_CLASS_DOC;

    private static Log LOGGER = LogFactory.getFactory().getInstance(Event.class);

    private Map<String, BaseObject> eventObj;
    private DocumentReference eventDocRef;
    private String defaultLang;
    private String language;
    private ICalendar calendar;

    @Deprecated
    public Event(XWikiDocument eventDoc, XWikiContext context) {
        this(eventDoc
                .getXObjects(new DocumentReference(context.getDatabase(), CLASSES_SPACE, CALENDAR_EVENT_CLASS_DOC)),
                eventDoc.getDocumentReference().getSpaceReferences().get(0).getName(), context);
        this.eventDocRef = eventDoc.getDocumentReference();
    }

    @Deprecated
    public Event(String eventDocName, XWikiContext context) throws XWikiException {
        this(context.getWiki().getDocument(eventDocName, context), context);
    }

    @Deprecated
    public Event(DocumentReference eventDocRef, XWikiContext context) throws XWikiException {
        this(eventDocRef);
    }

    public Event(DocumentReference eventDocRef) {
        this.eventDocRef = eventDocRef;
    }

    public Event(List<BaseObject> objList, String space) {
        initObjectMap(objList, space);
        if (getEventObjMap().size() > 0) {
            BaseObject artObj = getEventObjMap().values().iterator().next();
            this.eventDocRef = artObj.getDocumentReference();
        }
    }

    /**
     * 
     * @param objList
     * @param space
     * @param context
     * 
     * @deprecated instead use Event(List<BaseObject>, String)
     */
    @Deprecated
    public Event(List<BaseObject> objList, String space, XWikiContext context) {
        this(objList, space);
    }

    private void initObjectMap(List<BaseObject> objList, String space) {
        if (objList != null) {
            for (BaseObject artObj : objList) {
                init(artObj, space);
            }
        }
    }

    Map<String, BaseObject> getEventObjMap() {
        Map<String, BaseObject> eventObjMap = getEventObjMap_internal();
        if (eventObjMap.isEmpty() && (eventDocRef != null)) {
            try {
                XWikiDocument eventDoc = getContext().getWiki().getDocument(eventDocRef, getContext());
                initObjectMap(eventDoc.getXObjects(
                        new DocumentReference(getContext().getDatabase(), CLASSES_SPACE, CALENDAR_EVENT_CLASS_DOC)),
                        eventDocRef.getLastSpaceReference().getName());
            } catch (XWikiException exp) {
                LOGGER.error("getEventObjMap failed to get event document [" + eventDocRef + "].", exp);
            }
        }
        return eventObjMap;
    }

    private Map<String, BaseObject> getEventObjMap_internal() {
        if (eventObj == null) {
            eventObj = new HashMap<String, BaseObject>();
        }
        return eventObj;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#init(BaseObject, java.lang.String)
     */
    final private void init(BaseObject artObj, String space) {
        if (artObj != null) {
            String langValue = artObj.getStringValue(CelementsCalendarPlugin.PROPERTY_LANG);
            if (langValue != null) {
                getEventObjMap_internal().put(langValue, artObj);
            } else {
                getEventObjMap_internal().put("", artObj);
            }
        }
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getTitle(java.lang.String)
     */
    public String getTitle() {
        return getStringPropertyDefaultIfEmpty(CelementsCalendarPlugin.PROPERTY_TITLE, getLanguage());
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getDescription(java.lang.String)
     */
    public String getDescription() {
        return getStringPropertyDefaultIfEmpty(CelementsCalendarPlugin.PROPERTY_DESCRIPTION, getLanguage());
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getLocation()
     */
    public String getLocation() {
        return getStringProperty(getObj(), CelementsCalendarPlugin.PROPERTY_LOCATION);
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getDateString(java.lang.String)
     */
    public String getDateString(String dateField, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format, new Locale(getLanguage()));
        Date date = getDateProperty(getObj(), dateField);
        String dateString = "";
        if (date != null) {
            dateString = sdf.format(date);
        }
        return dateString;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getEventDate()
     */
    public Date getEventDate() {
        return getDateProperty(getObj(), CelementsCalendarPlugin.PROPERTY_EVENT_DATE);
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#isSubscribable()
     */
    public Boolean isSubscribable() {
        return getBooleanProperty(getObj(), CelementsCalendarPlugin.PROPERTY_EVENT_IS_SUBSCRIBABLE);
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getEventDocument()
     */
    public XWikiDocument getEventDocument() {
        try {
            return getContext().getWiki().getDocument(this.eventDocRef, getContext());
        } catch (XWikiException exp) {
            LOGGER.error("Failed to get cal doc for [" + this.eventDocRef + "].", exp);
        }
        return null;
    }

    @Deprecated
    public String displayOverviewField(String name, String link, XWikiContext context) {
        return displayOverviewField(name, link);
    }

    public String displayOverviewField(String name, String link) {
        ICalendar cal = getCalendar(getContext());
        boolean hasLink = cal.hasDetailLink() && needsMoreLink(getContext());
        hasLink &= (!cal.getOverviewFields().contains("detaillink") || name.equals("detaillink"));
        LOGGER.debug("cal.hasDetailLink(): " + cal.hasDetailLink());
        LOGGER.debug("needsMoreLink(context): " + needsMoreLink(getContext()));
        LOGGER.debug("!cal.getOverviewFields().contains('detaillink'): "
                + !cal.getOverviewFields().contains("detaillink"));
        LOGGER.debug("name.equals('detaillink'): " + name.equals("detaillink"));
        LOGGER.debug("hasLink: " + hasLink);

        String value = "";
        if (hasLink) {
            value += "<a href='" + link + "'>";
        }
        value += displayField(name, getContext());
        if (hasLink) {
            value += "</a>";
        }

        return value;
    }

    @Deprecated
    public String displayField(String name, XWikiContext context) {
        return displayField(name);
    }

    public String displayField(String name) {
        return internalDisplayField(name, true);
    }

    String internalDisplayField(String name, boolean addSpans) {
        LOGGER.debug("display: '" + name + "'");
        String value = "";
        String[] parts = name.split("-");
        String prevPartName = null;
        for (String partName : parts) {
            boolean notDisplayIfSame = partName.endsWith(".");
            partName = partName.replaceAll("\\.", "");
            String displayPart = getDisplayPart(partName, notDisplayIfSame);
            if ((parts.length > 1) && !"".equals(displayPart)) {
                displayPart = addDateTimeDelimiter(prevPartName, partName, displayPart);
                if (addSpans) {
                    displayPart = "<span class=\"cel_cal_" + partName + "\">" + displayPart + "</span>";
                }
            }
            value += displayPart;
            prevPartName = partName;
        }
        return value;
    }

    private String addDateTimeDelimiter(String prevPartName, String partName, String displayPart) {
        if (("date_end".equals(partName) || "time_end".equals(partName))
                && ("date".equals(prevPartName) || "time".equals(prevPartName)) && !"".equals(displayPart)) {
            displayPart = getFromDictionary("cel_cal_datetime_delim") + displayPart;
        }
        return displayPart;
    }

    private String getFromDictionary(String dictKey) {
        String dictValue;
        if (getContext().get("msg") != null) {
            dictValue = getContext().getMessageTool().get(dictKey);
        } else {
            dictValue = dictKey;
        }
        return dictValue;
    }

    String getDisplayPart(String name, boolean notDisplayIfSame) {
        String value = "";
        if (name.equals("date")) {
            value = getDateString(CelementsCalendarPlugin.PROPERTY_EVENT_DATE, "dd.MM.yyyy");
        } else if (name.equals("time")) {
            value = getTimeString(CelementsCalendarPlugin.PROPERTY_EVENT_DATE, notDisplayIfSame);
        } else if (name.equals("date_end")) {
            String startDay = getDateString(CelementsCalendarPlugin.PROPERTY_EVENT_DATE, "dd.MM.yyyy");
            String endDay = getDateString(CelementsCalendarPlugin.PROPERTY_EVENT_DATE_END, "dd.MM.yyyy");
            if (!notDisplayIfSame || !startDay.equals(endDay)) {
                value = endDay;
            }
        } else if (name.equals("time_end")) {
            value = getTimeString(CelementsCalendarPlugin.PROPERTY_EVENT_DATE_END, notDisplayIfSame);
        } else if (name.equals("title")) {
            value = getTitle();
        } else if (name.equals("location")) {
            value = getLocation();
        } else if (name.equals("detaillink")) {
            if (needsMoreLink(getContext())) {
                value = getContext().getMessageTool().get("cel_cal_more_detaillink");
            }
        } else {
            value = getStringProperty(name, getLanguage());
        }
        LOGGER.debug("display part: '" + name + "'" + " = " + value);
        return value;
    }

    private String getTimeString(String fieldName, boolean notDisplayIfSame) {
        String value = "";
        String startTime = getDateString(fieldName, "HH:mm");
        if (!notDisplayIfSame || !startTime.equals("00:00")) {
            value = startTime;
        }
        return value;
    }

    @Deprecated
    public boolean needsMoreLink(XWikiContext context) {
        return needsMoreLink();
    }

    public boolean needsMoreLink() {
        boolean needsLink = false;
        List<String> additionalFields = getAdditionalPropertyNames();
        if (additionalFields != null) {
            needsLink = (getNonEmptyFields(additionalFields).size() > 0);
        }
        return needsLink;
    }

    private List<String> getAdditionalPropertyNames() {
        Set<String> detailFieldsSet = new HashSet<String>();
        detailFieldsSet.addAll(splitIntoPropertyNames(getCalendar().getDetailviewFields()));
        List<String> additionalFields = ListUtils.subtract(Arrays.asList(detailFieldsSet.toArray(new String[0])),
                splitIntoPropertyNames(getCalendar().getOverviewFields()));
        return additionalFields;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#isFromSubscribableCalendar(java.lang.String)
     */
    public boolean isFromSubscribableCalendar(String calendarSpace) {
        boolean result = true;
        if (getDocName().startsWith(calendarSpace + ".")) {
            result = false;
        }
        return result;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getDocName()
     */
    @Deprecated
    public String getDocName() {
        for (String key : getEventObjMap().keySet()) {
            return getEventObjMap().get(key).getName();
        }
        return "";
    }

    public String getDocumentName() {
        return getDocumentReference().getName();
    }

    public DocumentReference getDocumentReference() {
        return this.eventDocRef;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getStringPropertyDefaultIfEmpty(java.lang.String, java.lang.String)
     */
    public String getStringPropertyDefaultIfEmpty(String name, String lang) {
        String result = getStringProperty(getObj(lang), name);
        if ((result.trim().length() <= 0) && !lang.equals(getDefaultLang())) {
            result = getStringProperty(getObj(), name);
        }
        return result;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getStringProperty(java.lang.String, java.lang.String)
     */
    public String getStringProperty(String name, String lang) {
        return getStringProperty(getObj(lang), name);
    }

    private String getStringProperty(BaseObject obj, String name) {
        String result = "";
        if (obj != null) {
            result = obj.getStringValue(name);
        }
        return result;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getDateProperty(java.lang.String, java.lang.String)
     */
    public Date getDateProperty(String name, String lang) {
        return getDateProperty(getObj(lang), name);
    }

    private Date getDateProperty(BaseObject obj, String name) {
        Date result = null;
        if (obj != null) {
            result = obj.getDateValue(name);
        }
        return result;
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getBooleanProperty(java.lang.String, java.lang.String)
     */
    public Boolean getBooleanProperty(String name, String lang) {
        return getBooleanProperty(getObj(lang), name);
    }

    // not set = null, false = 0, true = 1
    private Boolean getBooleanProperty(BaseObject obj, String name) {
        Boolean result = null;
        if (obj != null) {
            result = obj.getIntValue(name) == 1;
        }
        return result;
    }

    //FIXME public should return an API Object and not base Object -> refactore to use 
    //      BaseObject only internally.
    public BaseObject getObj() {
        return getObj(getDefaultLang());
    }

    /* (non-Javadoc)
     * @see com.celements.calendar.IEvent#getObj(java.lang.String)
     */
    //FIXME public should return an API Object and not base Object -> refactore to use 
    //      BaseObject only internally.
    public BaseObject getObj(String lang) {
        BaseObject obj = null;
        if (getEventObjMap().containsKey(lang)) {
            LOGGER.info("'" + getDocName() + "' - Getting object for lang '" + lang + "'");
            obj = getEventObjMap().get(lang);
        } else {
            if (getEventObjMap().containsKey(getDefaultLang())) {
                LOGGER.info("'" + getDocName() + "' - Getting object for defaultLang '" + lang + "'");
                obj = getEventObjMap().get(getDefaultLang());
            } else {
                if (getEventObjMap().containsKey("")) {
                    LOGGER.info("'" + getDocName() + "' - Getting object failed for lang ''");
                    obj = getEventObjMap().get("");
                } else {
                    LOGGER.info("'" + getDocName() + "' - Getting object failed for lang '" + lang
                            + "' and defaultLang '" + getDefaultLang() + "'");
                }
            }
        }
        LOGGER.info("Object found: doc "
                + (obj != null ? "name='" + obj.getDocumentReference() + "'" : "no object found! ") + " obj='" + obj
                + "'");
        return obj;
    }

    @Deprecated
    public Element[] getProperties(String lang, XWikiContext context) {
        return getProperties(lang);
    }

    public Element[] getProperties(String lang) {
        BaseObject obj = getObj(lang);
        if (obj != null) {
            return new com.xpn.xwiki.api.Class(obj.getXClass(getContext()), getContext()).getProperties();
        } else {
            LOGGER.error("getProperties failed. No object found.");
        }
        return new Property[] {};
    }

    @Deprecated
    public ICalendar getCalendar(XWikiContext context) {
        return getCalendar();
    }

    public ICalendar getCalendar() {
        if (calendar == null) {
            try {
                XWikiDocument calDoc = CalendarUtils.getInstance()
                        .getCalendarPageByCalendarSpace(getEventPrimarySpace(), getContext());
                calendar = internal_getCalendarByDoc(calDoc);
            } catch (XWikiException e) {
                LOGGER.debug("No calendar doc found.", e);
            }
        }
        return calendar;
    }

    public String getEventPrimarySpace() {
        return getDocumentReference().getLastSpaceReference().getName();
    }

    private ICalendar internal_getCalendarByDoc(XWikiDocument calDoc) {
        if (calDoc != null) {
            return ((CalendarUtils) CalendarUtils.getInstance()).getCalendarByCalDoc(calDoc, false, getContext());
        }
        return null;
    }

    @Deprecated
    public List<List<String>> getEditableProperties(String lang, XWikiContext context) throws XWikiException {
        return getEditableProperties(lang);
    }

    public List<List<String>> getEditableProperties(String lang) throws XWikiException {
        Set<String> confIndep = new HashSet<String>();
        Set<String> confDep = new HashSet<String>();
        splitLanguageDependentFields(confIndep, confDep, splitIntoPropertyNames(getCalendar().getOverviewFields()));
        splitLanguageDependentFields(confIndep, confDep,
                splitIntoPropertyNames(getCalendar().getDetailviewFields()));
        if (getCalendar().isSubscribable()) {
            confIndep.add(CelementsCalendarPlugin.PROPERTY_EVENT_IS_SUBSCRIBABLE);
        }
        Element[] allProps = getProperties(lang);
        LOGGER.debug("getEditableProperties: allProps - " + Arrays.deepToString(allProps));
        LOGGER.debug("getEditableProperties: confIndep - " + Arrays.deepToString(confIndep.toArray()));
        LOGGER.debug("getEditableProperties: confDep - " + Arrays.deepToString(confDep.toArray()));
        List<String> lIndependantProps = getProps(allProps, confIndep);
        List<String> lDependantProps = getProps(allProps, confDep);
        List<List<String>> editProp = new ArrayList<List<String>>();
        editProp.add(lIndependantProps);
        editProp.add(lDependantProps);
        LOGGER.debug("getEditableProperties: return editProp - " + Arrays.deepToString(editProp.toArray()));
        return editProp;
    }

    private List<String> splitIntoPropertyNames(List<String> fieldList) {
        List<String> propertyNames = new ArrayList<String>();
        for (String fieldName : fieldList) {
            if (fieldName.contains("-")) {
                for (String propName : fieldName.split("-")) {
                    propertyNames.add(propName.replaceAll("\\.", ""));
                }
            } else {
                propertyNames.add(fieldName.replaceAll("\\.", ""));
            }
        }
        return propertyNames;
    }

    void splitLanguageDependentFields(Set<String> confIndep, Set<String> confDep, List<String> propertyNames) {
        ArrayList<String> propNamesCleanList = new ArrayList<String>();
        propNamesCleanList.addAll(propertyNames);
        propNamesCleanList.remove("detaillink");
        if (propNamesCleanList.contains("date") || propNamesCleanList.contains("time")) {
            propNamesCleanList.remove("date");
            propNamesCleanList.remove("time");
            propNamesCleanList.add("eventDate");
        }
        if (propNamesCleanList.contains("date_end") || propNamesCleanList.contains("time_end")) {
            propNamesCleanList.remove("date_end");
            propNamesCleanList.remove("time_end");
            propNamesCleanList.add("eventDate_end");
        }
        LOGGER.debug("splitLanguageDepFields: " + propNamesCleanList.toString());
        for (String propName : propNamesCleanList) {
            if (propName.startsWith("l_")) {
                confDep.add(propName);
            } else {
                confIndep.add(propName);
            }
        }
    }

    private List<String> getProps(Element[] allProps, Set<String> conf) {
        List<String> props = new ArrayList<String>();
        for (int i = 0; i < allProps.length; i++) {
            if ((allProps[i] != null) && ((conf.size() == 0) || (conf.contains(allProps[i].getName())))) {
                LOGGER.debug("addProp: " + allProps[i].getName());
                props.add(allProps[i].getName());
            } else {
                LOGGER.debug("NOT addProp: " + allProps[i].getName());
            }
        }
        return props;
    }

    @Deprecated
    public List<String> getNonEmptyFields(List<String> fieldList, XWikiContext context) {
        return getNonEmptyFields(fieldList);
    }

    public List<String> getNonEmptyFields(List<String> fieldList) {
        EmptyCheckCommand emptyCheckCmd = new EmptyCheckCommand();
        List<String> result = new ArrayList<String>();
        for (String fieldName : fieldList) {
            String fieldValue = internalDisplayField(getDetailConfigForField(fieldName), false);
            if ((fieldValue != null) && !emptyCheckCmd.isEmptyRTEString(fieldValue)) {
                result.add(fieldName);
            }
        }

        return result;
    }

    String getDetailConfigForField(String fieldName) {
        for (String colFields : getCalendar().getDetailviewFields()) {
            if (isIncludingFieldAsOptional(fieldName, colFields)) {
                fieldName = fieldName + ".";
            }
        }
        return fieldName;
    }

    boolean isIncludingFieldAsOptional(String fieldName, String colFields) {
        return colFields.matches("^([^-]*-)*" + fieldName + "\\.(-[^-]*)*$");
    }

    private final String getDefaultLang() {
        if (defaultLang == null) {
            defaultLang = getContext().getWiki().getWebPreference("default_language", getEventPrimarySpace(), "",
                    getContext());
        }
        return defaultLang;
    }

    public String getLanguage() {
        if (language != null) {
            return language;
        }
        return getDefaultLang();
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    /**
     * for Tests only!!!
     * @param xWikiDocument
     */
    @Deprecated
    void internal_setEventDoc(XWikiDocument testEventDoc) {
        this.eventDocRef = testEventDoc.getDocumentReference();
    }

    public void internal_setDocumentReference(DocumentReference eventDocRef) {
        this.eventDocRef = eventDocRef;
    }

    /**
     * for Tests only!!!
     * @param string
     */
    void internal_setDefaultLanguage(String defLang) {
        defaultLang = defLang;
    }

    /**
     * for Tests only!!!
     * @param string
     */
    void internal_setCalendar(ICalendar testCalendar) {
        calendar = testCalendar;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Event)) {
            return false;
        }
        Event theEvent = (Event) obj;
        return theEvent.getDocumentReference().equals(this.getDocumentReference());
    }

    @Override
    public int hashCode() {
        return this.getDocumentReference().hashCode();
    }

    private XWikiContext getContext() {
        Execution execution = Utils.getComponent(Execution.class);
        return (XWikiContext) execution.getContext().getProperty("xwikicontext");
    }

}