All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mnode.ical4j.json.JCalSerializer Maven / Gradle / Ivy

package org.mnode.ical4j.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import net.fortuna.ical4j.model.*;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.component.VTimeZone;
import net.fortuna.ical4j.model.component.VToDo;
import net.fortuna.ical4j.model.parameter.Value;

import java.io.IOException;

public class JCalSerializer extends StdSerializer {

    public JCalSerializer(Class t) {
        super(t);
    }

    @Override
    public void serialize(Calendar value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeTree(buildVCalendar(value));
    }

    private JsonNode buildVCalendar(Calendar calendar) {
        ObjectMapper mapper = new ObjectMapper();

        ArrayNode vcalendar = mapper.createArrayNode();
        vcalendar.add("vcalendar");

        ArrayNode vcalprops = mapper.createArrayNode();
        for (Property p : calendar.getProperties()) {
            vcalprops.add(buildPropertyArray(p));
        }
        vcalendar.add(vcalprops);

        ArrayNode vcalcomponents = mapper.createArrayNode();
        for (Component c : calendar.getComponents()) {
            vcalcomponents.add(buildComponentArray(c));
        }
        vcalendar.add(vcalcomponents);

        return vcalendar;
    }

    private JsonNode buildComponentArray(Component component) {
        ObjectMapper mapper = new ObjectMapper();

        ArrayNode cArray = mapper.createArrayNode();
        cArray.add(component.getName().toLowerCase());

        ArrayNode componentprops = mapper.createArrayNode();
        for (Property p : component.getProperties()) {
            componentprops.add(buildPropertyArray(p));
        }
        cArray.add(componentprops);

        ArrayNode subcomponents = mapper.createArrayNode();
        if (component instanceof VEvent) {
            for (Component c : ((VEvent) component).getAlarms()) {
                subcomponents.add(buildComponentArray(c));
            }
        } else if (component instanceof VToDo) {
            for (Component c : ((VToDo) component).getAlarms()) {
                subcomponents.add(buildComponentArray(c));
            }
        } else if (component instanceof VTimeZone) {
            for (Component c : ((VTimeZone) component).getObservances()) {
                subcomponents.add(buildComponentArray(c));
            }
        }
        cArray.add(subcomponents);

        return cArray;
    }

    private JsonNode buildPropertyArray(Property property) {
        ObjectMapper mapper = new ObjectMapper();

        ArrayNode pArray = mapper.createArrayNode();
        pArray.add(property.getName().toLowerCase());
        pArray.add(buildParamsObject(property.getParameters()));

        String propertyType = getPropertyType(property);
        pArray.add(propertyType);
        switch (propertyType) {
            case "date":
                pArray.add(JCalEncoder.DATE.encode(property.getValue()));
                break;
            case "date-time":
                pArray.add(JCalEncoder.DATE_TIME.encode(property.getValue()));
                break;
            case "time":
                pArray.add(JCalEncoder.TIME.encode(property.getValue()));
                break;
            case "utc-offset":
                pArray.add(JCalEncoder.UTCOFFSET.encode(property.getValue()));
                break;
            case "binary":
            case "duration":
            case "period":
            case "uri":
            default:
                pArray.add(property.getValue());
        }
        return pArray;
    }

    private String getPropertyType(Property property) {
        // handle property type overrides via VALUE param..
        Value value = property.getParameter(Parameter.VALUE);
        if (value != null) {
            return value.getValue().toLowerCase();
        }

        switch (property.getName()) {
            case "CALSCALE":
            case "METHOD":
            case "PRODID":
            case "VERSION":
            case "CATEGORIES":
            case "CLASS":
            case "COMMENT":
            case "DESCRIPTION":
            case "LOCATION":
            case "RESOURCES":
            case "STATUS":
            case "SUMMARY":
            case "TRANSP":
            case "TZID":
            case "TZNAME":
            case "CONTACT":
            case "RELATED-TO":
            case "UID":
            case "ACTION":
            case "REQUEST-STATUS":
            case "NAME":
                return "text";
            case "GEO":
                return "float";
            case "PERCENT-COMPLETE":
            case "PRIORITY":
            case "REPEAT":
            case "SEQUENCE":
                return "integer";
            case "COMPLETED":
            case "DTEND":
            case "DUE":
            case "DTSTAMP":
            case "DTSTART":
            case "DURATION":
            case "RECURRENCE-ID":
            case "EXDATE":
            case "RDATE":
            case "TRIGGER":
            case "CREATED":
            case "LAST-MODIFIED":
                return "date-time";
            case "FREEBUSY":
                return "period";
            case "TZOFFSETFROM":
            case "TZOFFSETTO":
                return "utc-offset";
            case "TZURL":
            case "URL":
            case "ATTACH":
            case "IMAGE":
            case "SOURCE":
                return "uri";
            case "ATTENDEE":
            case "ORGANIZER":
                return "cal-address";
            case "RRULE":
                return "recur";
            default:
                return "unknown";
        }
    }

    private JsonNode buildParamsObject(ParameterList parameterList) {
        ObjectMapper mapper = new ObjectMapper();

        ObjectNode params = mapper.createObjectNode();
        for (Parameter p : parameterList) {
            params.put(p.getName().toLowerCase(), p.getValue().toLowerCase());
        }
        return params;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy