org.bedework.synch.cnctrs.orgSyncV2.OrgSyncV2ConnectorInstance.java Source code

Java tutorial

Introduction

Here is the source code for org.bedework.synch.cnctrs.orgSyncV2.OrgSyncV2ConnectorInstance.java

Source

/* ********************************************************************
Licensed to Jasig under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Jasig licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a
copy of the License at:
    
http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package org.bedework.synch.cnctrs.orgSyncV2;

import org.bedework.synch.shared.Subscription;
import org.bedework.synch.shared.cnctrs.BaseConnectorInstance;
import org.bedework.synch.shared.exception.SynchException;
import org.bedework.synch.wsmessages.SynchEndType;
import org.bedework.util.calendar.XcalUtil;
import org.bedework.util.misc.Util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import ietf.params.xml.ns.icalendar_2.ArrayOfComponents;
import ietf.params.xml.ns.icalendar_2.ArrayOfParameters;
import ietf.params.xml.ns.icalendar_2.ArrayOfProperties;
import ietf.params.xml.ns.icalendar_2.BasePropertyType;
import ietf.params.xml.ns.icalendar_2.CategoriesPropType;
import ietf.params.xml.ns.icalendar_2.CreatedPropType;
import ietf.params.xml.ns.icalendar_2.DateDatetimePropertyType;
import ietf.params.xml.ns.icalendar_2.DescriptionPropType;
import ietf.params.xml.ns.icalendar_2.DtendPropType;
import ietf.params.xml.ns.icalendar_2.DtstampPropType;
import ietf.params.xml.ns.icalendar_2.DtstartPropType;
import ietf.params.xml.ns.icalendar_2.IcalendarType;
import ietf.params.xml.ns.icalendar_2.LocationPropType;
import ietf.params.xml.ns.icalendar_2.ProdidPropType;
import ietf.params.xml.ns.icalendar_2.RdatePropType;
import ietf.params.xml.ns.icalendar_2.SummaryPropType;
import ietf.params.xml.ns.icalendar_2.UidPropType;
import ietf.params.xml.ns.icalendar_2.VcalendarType;
import ietf.params.xml.ns.icalendar_2.VersionPropType;
import ietf.params.xml.ns.icalendar_2.VeventType;
import ietf.params.xml.ns.icalendar_2.XBedeworkLocKeyParamType;
import org.apache.http.client.utils.URIBuilder;

import java.io.InputStream;
import java.net.URI;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;

import javax.xml.bind.JAXBElement;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

/** Handles orgsync v2 synch interactions.
 *
 * @author Mike Douglass
 */
public class OrgSyncV2ConnectorInstance
        extends BaseConnectorInstance<OrgSyncV2Connector, OrgSyncV2SubscriptionInfo, OrgSyncV2ConnectorConfig> {
    private final ObjectMapper om = new ObjectMapper();

    OrgSyncV2ConnectorInstance(final OrgSyncV2ConnectorConfig config, final OrgSyncV2Connector cnctr,
            final Subscription sub, final SynchEndType end, final OrgSyncV2SubscriptionInfo info) {
        super(sub, end, info, cnctr, config);
    }

    @Override
    public boolean changed() throws SynchException {
        /*
           OrgSync doesn't support HEAD - we get a 500 error back. We'll
           just do a GET and throw the result away. We'll be back soon
           for the content.
         */
        return changed(false, "application/json");
    }

    /* ====================================================================
     *                   BaseConnectorInstance methods
     * ==================================================================== */

    @Override
    public URI getUri() throws SynchException {
        try {
            //Get yesterdays date
            final LocalDate yesterday = LocalDate.now().minus(1, ChronoUnit.DAYS);
            final String yesterdayStr = yesterday.format(DateTimeFormatter.ISO_LOCAL_DATE);

            final URI infoUri = new URI(info.getUri());
            return new URIBuilder().setScheme(infoUri.getScheme()).setHost(infoUri.getHost())
                    .setPort(infoUri.getPort()).setPath(infoUri.getPath())
                    .setParameter("key", cnctr.getSyncher().decrypt(info.getPassword()))
                    .setParameter("start_date", yesterdayStr).build();
        } catch (final SynchException se) {
            throw se;
        } catch (final Throwable t) {
            throw new SynchException(t);
        }
    }

    @Override
    public IcalendarType makeXcal(final InputStream is) throws SynchException {
        try {
            final List<OrgSyncV2Event> osEvents = om.readValue(is, new TypeReference<List<OrgSyncV2Event>>() {
            });

            /* Convert each entity to XML */

            return toXcal(osEvents, info.getOrgSyncPublicOnly());
        } catch (final SynchException se) {
            throw se;
        } catch (final Throwable t) {
            throw new SynchException(t);
        }
    }

    @Override
    public boolean getIcal() throws SynchException {
        return getIcal("application/json");
    }

    /* ====================================================================
     *                   Private methods
     * ==================================================================== */

    private IcalendarType toXcal(final List<OrgSyncV2Event> osEvents, final boolean onlyPublic) {
        final IcalendarType ical = new IcalendarType();
        final VcalendarType vcal = new VcalendarType();

        ical.getVcalendar().add(vcal);

        vcal.setProperties(new ArrayOfProperties());
        final List<JAXBElement<? extends BasePropertyType>> vcalProps = vcal.getProperties()
                .getBasePropertyOrTzid();

        final VersionPropType vers = new VersionPropType();
        vers.setText("2.0");
        vcalProps.add(of.createVersion(vers));

        final ProdidPropType prod = new ProdidPropType();
        prod.setText("//Bedework.org//BedeWork V3.11.1//EN");
        vcalProps.add(of.createProdid(prod));

        final ArrayOfComponents aoc = new ArrayOfComponents();
        vcal.setComponents(aoc);

        for (final OrgSyncV2Event osev : osEvents) {
            if (onlyPublic && !osev.getIsPublic()) {
                continue;
            }

            final VeventType ev = new VeventType();

            aoc.getBaseComponent().add(of.createVevent(ev));

            ev.setProperties(new ArrayOfProperties());
            final List<JAXBElement<? extends BasePropertyType>> evProps = ev.getProperties()
                    .getBasePropertyOrTzid();

            final UidPropType uid = new UidPropType();
            uid.setText(config.getUidPrefix() + "-" + osev.getId());
            evProps.add(of.createUid(uid));

            final DtstampPropType dtstamp = new DtstampPropType();
            try {
                //Get todays date
                final ZonedDateTime today = ZonedDateTime.now(ZoneOffset.UTC);
                final String todayStr = today.format(DateTimeFormatter.ISO_INSTANT);

                dtstamp.setUtcDateTime(XcalUtil.getXMlUTCCal(todayStr));
                evProps.add(of.createDtstamp(dtstamp));

                final CreatedPropType created = new CreatedPropType();
                created.setUtcDateTime(XcalUtil.getXMlUTCCal(todayStr));
                evProps.add(of.createCreated(created));

                final SummaryPropType sum = new SummaryPropType();
                sum.setText(osev.getName());
                evProps.add(of.createSummary(sum));

                final DescriptionPropType desc = new DescriptionPropType();
                desc.setText(osev.getDescription());
                evProps.add(of.createDescription(desc));

                final LocationPropType l = new LocationPropType();
                l.setText(osev.getLocation());
                evProps.add(of.createLocation(l));

                if (info.getLocationKey() != null) {
                    final XBedeworkLocKeyParamType par = of.createXBedeworkLocKeyParamType();

                    par.setText(info.getLocationKey());
                    l.setParameters(new ArrayOfParameters());
                    l.getParameters().getBaseParameter().add(of.createXBedeworkLocKey(par));
                }
            } catch (final Throwable t) {
                error(t);
                continue;
            }

            if (osev.getCategory() != null) {
                final CategoriesPropType cat = new CategoriesPropType();
                cat.getText().add(osev.getCategory().getName());
                evProps.add(of.createCategories(cat));
            }

            /* The first (only) element of occurrences is the start/end of the
               event or master.
                
               If there are more occurrences these become rdates and the event is
               recurring.
             */

            if (Util.isEmpty(osev.getOccurrences())) {
                // warn?
                continue;
            }

            boolean first = true;
            for (final OrgSyncV2Occurrence occ : osev.getOccurrences()) {
                if (first) {
                    final DtstartPropType dtstart = (DtstartPropType) makeDt(new DtstartPropType(),
                            occ.getStartsAt());
                    evProps.add(of.createDtstart(dtstart));

                    final DtendPropType dtend = (DtendPropType) makeDt(new DtendPropType(), occ.getEndsAt());
                    evProps.add(of.createDtend(dtend));

                    first = false;
                    continue;
                }

                // Add an rdate
                // TODO - add duration if different from the master
                final RdatePropType rdate = (RdatePropType) makeDt(new RdatePropType(), occ.getStartsAt());
                evProps.add(of.createRdate(rdate));
            }
        }

        return ical;
    }

    private DateDatetimePropertyType makeDt(final DateDatetimePropertyType dt, final String val) {
        try {
            final DatatypeFactory dtf = DatatypeFactory.newInstance();

            final XMLGregorianCalendar xgc = dtf.newXMLGregorianCalendar(val);
            if (val.length() == 10) {
                dt.setDate(xgc);
                return dt;
            }

            dt.setDateTime(xgc);
            return dt;
        } catch (final DatatypeConfigurationException dce) {
            error(dce);
            return null;
        }
    }
}