package org.osaf.caldav4j.methods; import static org.osaf.caldav4j.CalDAVConstants.NS_CALDAV; import static org.osaf.caldav4j.CalDAVConstants.NS_DAV; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Vector; import org.apache.webdav.lib.methods.XMLResponseMethodBase; import org.apache.webdav.lib.util.DOMUtils; import org.apache.webdav.lib.util.QName; import org.osaf.caldav4j.exceptions.CalDAV4JException; import org.osaf.caldav4j.model.response.CalDAVResponse; import org.osaf.caldav4j.util.CaldavStatus; import org.osaf.caldav4j.util.MethodUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Provide methods to parse caldav xml responsethat * XXX uses CalDAVResponse, so applies only to "calendar-data" response * @author rpolli * */ public abstract class CalDAVXMLResponseMethodBase extends XMLResponseMethodBase{ private Vector<CalDAVResponse> responseHashtable = null; private static Map<QName, Error> errorMap = null; private Error error = null; //private Collection<?> responseURLs = null; public enum ErrorType{PRECONDITION, POSTCONDITON} /** * Precondtions and Postconditions * @author bobbyrullo * */ public enum Error { SUPPORTED_CALENDAR_DATA(ErrorType.PRECONDITION, NS_CALDAV, "supported-calendar-data"), VALID_FILTER(ErrorType.PRECONDITION, NS_CALDAV, "valid-filter"), NUMBER_OF_MATCHES_WITHIN_LIMITS(ErrorType.POSTCONDITON, NS_DAV, "number-of-matches-within-limits"); private final ErrorType errorType; private final String namespaceURI; private final String elementName; Error(ErrorType errorType, String namespaceURI, String elementName){ this.errorType = errorType; this.namespaceURI = namespaceURI; this.elementName = elementName; } public ErrorType errorType() { return errorType; } public String namespaceURI() { return namespaceURI; } public String elementName(){ return elementName; } } static { errorMap = new HashMap<QName, Error>(); for (Error error : Error.values()) { errorMap.put(new QName(error.namespaceURI(), error.elementName()), error); } } public static final String ELEMENT_ERROR ="error"; /** * Return an enumeration containing the responses. * * @return An enumeration containing objects implementing the * ResponseEntity interface */ public Enumeration<CalDAVResponse> getResponses() { return getResponseVector().elements(); } public Error getError(){ return error; } protected Vector<CalDAVResponse> getResponseVector() { checkUsed(); if (responseHashtable == null) { initHashtable(); } return responseHashtable; } protected Hashtable<String, CalDAVResponse> getResponseHashtable() { throw new RuntimeException("Unimplemented method"); } protected Vector<String> getResponseURLs() { checkUsed(); if (responseHashtable == null) { initHashtable(); } return responseURLs; } /** * A lot of this code had to be copied from the parent XMLResponseMethodBase, since it's * initHashtable doesn't allow for new types of Responses. * * Of course, the same mistake is being made here, so it is a TODO to fix that * */ @SuppressWarnings("unchecked") private void initHashtable(){ responseHashtable = new Vector<CalDAVResponse>(); responseURLs = new Vector<String>(); Document rdoc = null; // Also accept OK sent by buggy servers in reply to a PROPFIND // or REPORT (Xythos, Catacomb, ...?). int statusCode = getStatusCode(); switch(statusCode) { case CaldavStatus.SC_MULTI_STATUS: rdoc = getResponseDocument(); NodeList list = null; if (rdoc != null) { Element multistatus = getResponseDocument().getDocumentElement(); list = multistatus.getChildNodes(); } if (list != null) { for (int i = 0; i < list.getLength(); i++) { try { Element child = (Element) list.item(i); String name = DOMUtils.getElementLocalName(child); String namespace = DOMUtils.getElementNamespaceURI(child); if (Response.TAG_NAME.equals(name) && "DAV:".equals(namespace)) { CalDAVResponse response = new CalDAVResponse(child); String href = response.getHref() ; // FIXME this hashTable won't support expanded events responseHashtable.add(response); responseURLs.add(href); } } catch (ClassCastException e) { } } } break; case CaldavStatus.SC_CONFLICT: case CaldavStatus.SC_FORBIDDEN: rdoc = getResponseDocument(); Element errorElement = rdoc.getDocumentElement(); // first make sure that the element is actually an error. if (!errorElement.getNamespaceURI().equals(NS_DAV) || !errorElement.getLocalName().equals(ELEMENT_ERROR)) { Node condition = errorElement.getChildNodes().item(0); error = errorMap.get(new QName(condition.getNamespaceURI(), condition.getLocalName())); } break; default: try { MethodUtil.StatusToExceptions(this); } catch (CalDAV4JException e) {} break; } } }