/* (non-Javadoc) * @see org.bedework.synch.ConnectorInstance#changed() */ @Override public boolean changed() throws SynchException { /* This implementation needs to at least check the change token for the * collection and match it against the stored token. */ if (info.getChangeToken() == null) { fetchedIcal = null; // Force refetch return true; } DavClient cl = getClient(); try { int rc = cl.sendRequest("HEAD", info.getUri(), null); if (rc != HttpServletResponse.SC_OK) { info.setLastRefreshStatus(String.valueOf(rc)); if (debug) { trace("Unsuccessful response from server was " + rc); } info.setChangeToken(null); // Force refresh next time fetchedIcal = null; // Force refetch return true; } String etag = cl.getResponse().getResponseHeaderValue("Etag"); if (etag == null) { if (debug) { trace("Received null etag"); } return false; } if (debug) { trace("Received etag:" + etag + ", ours=" + info.getChangeToken()); } if (info.getChangeToken().equals(etag)) { return false; } fetchedIcal = null; // Force refetch return true; } catch (SynchException se) { throw se; } catch (Throwable t) { throw new SynchException(t); } finally { try { client.release(); } catch (Throwable t) { } } }
/* Fetch the iCalendar for the subscription. If it fails set the status and * return null. Unchanged data will return null with no status change. */ private void getIcal() throws SynchException { try { if (fetchedIcal != null) { return; } getClient(); Header[] hdrs = null; if ((uidMap != null) && (info.getChangeToken() != null) && (fetchedIcal != null)) { hdrs = new Header[] {new BasicHeader("If-None-Match", info.getChangeToken())}; } int rc = client.sendRequest("GET", info.getUri(), hdrs); info.setLastRefreshStatus(String.valueOf(rc)); if (rc == HttpServletResponse.SC_NOT_MODIFIED) { // Data unchanged. if (debug) { trace("data unchanged"); } return; } if (rc != HttpServletResponse.SC_OK) { info.setLastRefreshStatus(String.valueOf(rc)); if (debug) { trace("Unsuccessful response from server was " + rc); } info.setChangeToken(null); // Force refresh next time return; } CalendarBuilder builder = new CalendarBuilder(); InputStream is = client.getResponse().getContentStream(); Calendar ical = builder.build(is); /* Convert each entity to XML */ fetchedIcal = IcalToXcal.fromIcal(ical, null); uidMap = new HashMap<String, MapEntry>(); prodid = null; for (VcalendarType vcal : fetchedIcal.getVcalendar()) { /* Extract the prodid from the converted calendar - we use it when we * generate a new icalendar for each entity. */ if ((prodid == null) && (vcal.getProperties() != null)) { for (JAXBElement<? extends BasePropertyType> pel : vcal.getProperties().getBasePropertyOrTzid()) { if (pel.getValue() instanceof ProdidPropType) { prodid = ((ProdidPropType) pel.getValue()).getText(); break; } } } for (JAXBElement<? extends BaseComponentType> comp : vcal.getComponents().getBaseComponent()) { UidPropType uidProp = (UidPropType) XcalUtil.findProperty(comp.getValue(), XcalTags.uid); if (uidProp == null) { // Should flag as an error continue; } String uid = uidProp.getText(); MapEntry me = uidMap.get(uid); if (me == null) { me = new MapEntry(); me.uid = uid; uidMap.put(uidProp.getText(), me); } LastModifiedPropType lm = (LastModifiedPropType) XcalUtil.findProperty(comp.getValue(), XcalTags.lastModified); String lastmod = null; if (lm != null) { lastmod = lm.getUtcDateTime().toXMLFormat(); } if (Util.cmpObjval(me.lastMod, lastmod) < 0) { me.lastMod = lastmod; } me.comps.add(comp); } } /* Looks like we translated ok. Save any etag and delete everything in the * calendar. */ String etag = client.getResponse().getResponseHeaderValue("Etag"); if (etag != null) { info.setChangeToken(etag); } } catch (SynchException se) { throw se; } catch (Throwable t) { throw new SynchException(t); } finally { try { client.release(); } catch (Throwable t) { } } }