public void serve( CallContext context, CmisService service, String repositoryId, HttpServletRequest request, HttpServletResponse response) throws Exception { assert context != null; assert service != null; assert repositoryId != null; assert request != null; assert response != null; // get parameters String changeLogToken = getStringParameter(request, Constants.PARAM_CHANGE_LOG_TOKEN); Boolean includeProperties = getBooleanParameter(request, Constants.PARAM_PROPERTIES); String filter = getStringParameter(request, Constants.PARAM_FILTER); Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS); Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL); BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS); // execute if (stopBeforeService(service)) { return; } Holder<String> changeLogTokenHolder = new Holder<String>(changeLogToken); ObjectList changes = service.getContentChanges( repositoryId, changeLogTokenHolder, includeProperties, filter, includePolicyIds, includeAcl, maxItems, null); if (stopAfterService(service)) { return; } if (changes == null) { throw new CmisRuntimeException("Changes are null!"); } // set headers response.setStatus(HttpServletResponse.SC_OK); response.setContentType(Constants.MEDIATYPE_FEED); // write XML AtomFeed feed = new AtomFeed(); feed.startDocument(response.getOutputStream(), getNamespaces(service)); feed.startFeed(true); // write basic Atom feed elements GregorianCalendar now = new GregorianCalendar(); feed.writeFeedElements( "contentChanges", null, "", "Content Change", now, null, changes.getNumItems()); // write links UrlBuilder baseUrl = compileBaseUrl(request, repositoryId); feed.writeServiceLink(baseUrl.toString(), repositoryId); UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_CHANGES, null); selfLink.addParameter(Constants.PARAM_CHANGE_LOG_TOKEN, changeLogToken); selfLink.addParameter(Constants.PARAM_PROPERTIES, includeProperties); selfLink.addParameter(Constants.PARAM_FILTER, filter); selfLink.addParameter(Constants.PARAM_POLICY_IDS, includePolicyIds); selfLink.addParameter(Constants.PARAM_ACL, includeAcl); selfLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems); feed.writeSelfLink(selfLink.toString(), null); if (changeLogTokenHolder.getValue() != null) { if (Boolean.TRUE.equals(changes.hasMoreItems())) { UrlBuilder nextLink = compileUrlBuilder(baseUrl, RESOURCE_CHANGES, null); nextLink.addParameter(Constants.PARAM_CHANGE_LOG_TOKEN, changeLogTokenHolder.getValue()); nextLink.addParameter(Constants.PARAM_PROPERTIES, includeProperties); nextLink.addParameter(Constants.PARAM_FILTER, filter); nextLink.addParameter(Constants.PARAM_POLICY_IDS, includePolicyIds); nextLink.addParameter(Constants.PARAM_ACL, includeAcl); nextLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems); feed.writeNextLink(nextLink.toString()); } // The CMIS spec says that the AtomPub binding doesn't provide // the change log token. We are doing it anyway. XMLStreamWriter writer = feed.getWriter(); writer.writeStartElement( XMLConstants.PREFIX_APACHE_CHEMISTY, "changeLogToken", XMLConstants.NAMESPACE_APACHE_CHEMISTRY); writer.writeNamespace( XMLConstants.PREFIX_APACHE_CHEMISTY, XMLConstants.NAMESPACE_APACHE_CHEMISTRY); writer.writeCharacters(changeLogTokenHolder.getValue()); writer.writeEndElement(); } // write entries if (changes.getObjects() != null) { AtomEntry entry = new AtomEntry(feed.getWriter()); for (ObjectData object : changes.getObjects()) { if (object == null) { continue; } writeContentChangesObjectEntry( service, entry, object, null, repositoryId, null, null, baseUrl, false, context.getCmisVersion()); } } // write extensions feed.writeExtensions(changes); // we are done feed.endFeed(); feed.endDocument(); }