Java tutorial
/* * $Header$ * $Revision: 207563 $ * $Date: 2004-08-02 23:45:51 +0800 (Mon, 02 Aug 2004) $ * * ==================================================================== * * Copyright 1999-2002 The Apache Software Foundation * * Licensed 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.apache.webdav.lib.methods; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpConnection; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpState; import org.apache.webdav.lib.util.WebdavStatus; import org.apache.webdav.lib.util.XMLPrinter; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * OPTIONS Method. * */ public class OptionsMethod extends XMLResponseMethodBase { // -------------------------------------------------------------- Constants /** * DAV level 1. Mandatory. */ public static final String DAV_LEVEL1 = "1"; /** * DAV level 2. */ public static final String DAV_LEVEL2 = "2"; /** * Advanced collections. */ public static final String ADVANCED_COLLECTIONS = "3"; /** * Delta V. */ public static final String DELTAV = "4"; /** * ACL. */ public static final String ACL = "5"; /** * DASL. */ public static final String DASL = "6"; /** * */ public static final int OPTIONS_WORKSPACE = 8; /** * */ public static final int OPTIONS_VERSION_HISTORY = 9; // ----------------------------------------------------------- Constructors /** * Method constructor. */ public OptionsMethod() { } /** * Method constructor. */ public OptionsMethod(String path) { super(path); } /** * Method constructor. */ public OptionsMethod(String path, int type) { super(path); this.type = type; } // ----------------------------------------------------- Instance Variables /** * DAV Capabilities. */ private Vector davCapabilities = new Vector(); /** * Methods allowed. */ private Vector methodsAllowed = new Vector(); private int type = 0; private boolean hasXMLBody = false; // --------------------------------------------------------- Public Methods /** * Is the specified method allowed ? */ public boolean isAllowed(String method) { checkUsed(); return methodsAllowed.contains(method); } /** * Get a list of allowed methods. */ public Enumeration getAllowedMethods() { checkUsed(); return methodsAllowed.elements(); } /** * Is DAV capability supported ? */ public boolean isSupported(String capability) { checkUsed(); return davCapabilities.contains(capability); } /** * Get a list of supported DAV capabilities. */ public Enumeration getDavCapabilities() { checkUsed(); return davCapabilities.elements(); } /** * Parse response. * * @param input Input stream */ public void parseResponse(InputStream input, HttpState state, HttpConnection conn) throws IOException, HttpException { try { if (getStatusLine().getStatusCode() == WebdavStatus.SC_OK && hasXMLBody) { parseXMLResponse(input); } } catch (IOException e) { // FIX ME: provide a way to deliver non xml data } } // --------------------------------------------------- WebdavMethod Methods /** * Process response headers. The contract of this method is that it only * parses the response headers. * * @param state the state * @param conn the connection */ public void processResponseHeaders(HttpState state, HttpConnection conn) { Header davHeader = getResponseHeader("dav"); if (davHeader != null) { String davHeaderValue = davHeader.getValue(); StringTokenizer tokenizer = new StringTokenizer(davHeaderValue, ","); while (tokenizer.hasMoreElements()) { String davCapability = tokenizer.nextToken().trim(); davCapabilities.addElement(davCapability); } } Header allowHeader = getResponseHeader("allow"); if (allowHeader != null) { String allowHeaderValue = allowHeader.getValue(); StringTokenizer tokenizer = new StringTokenizer(allowHeaderValue, ","); while (tokenizer.hasMoreElements()) { String methodAllowed = tokenizer.nextToken().trim().toUpperCase(); methodsAllowed.addElement(methodAllowed); } } Header lengthHeader = getResponseHeader("content-length"); Header typeHeader = getResponseHeader("content-type"); if ((lengthHeader != null && Integer.parseInt(lengthHeader.getValue()) > 0) || (typeHeader != null && typeHeader.getValue().startsWith("text/xml"))) hasXMLBody = true; super.processResponseHeaders(state, conn); } /** * DAV requests that contain a body must override this function to * generate that body. * * <p>The default behavior simply returns an empty body.</p> */ protected String generateRequestBody() { if (type != 0) { XMLPrinter printer = new XMLPrinter(); printer.writeXMLHeader(); //System.out.println(printer.toString()); printer.writeElement("D", "DAV:", "options", XMLPrinter.OPENING); if (type == OPTIONS_VERSION_HISTORY) printer.writeElement("D", "version-history-collection-set", XMLPrinter.NO_CONTENT); if (type == OPTIONS_WORKSPACE) printer.writeElement("D", "workspace-collection-set", XMLPrinter.NO_CONTENT); printer.writeElement("D", "options", XMLPrinter.CLOSING); return printer.toString(); } return null; } public String getName() { return "OPTIONS"; } //get and set header public void addRequestHeaders(HttpState state, HttpConnection conn) throws IOException, HttpException { if (type != 0) { // set the default utf-8 encoding, if not already present if (getRequestHeader("Content-Type") == null) super.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); } super.addRequestHeaders(state, conn); } /** * This method returns an enumeration of URL paths. If the PropFindMethod * was sent to the URL of a collection, then there will be multiple URLs. * The URLs are picked out of the <code><D:href></code> elements * of the response. * * @return an enumeration of URL paths as Strings */ public Enumeration getAllResponseURLs() { checkUsed(); return getResponseURLs().elements(); } public Enumeration getResponseProperties() { Vector result = new Vector(); return (Enumeration) result; } protected Document parseResponseContent(InputStream is) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); byte[] chunk; byte[] all; int chunkLen; int allLen; List chunks; int i; int max; int ofs; allLen = 0; chunk = new byte[1024 * 4]; chunkLen = is.read(chunk); chunks = new ArrayList(); while (chunkLen != -1) { chunks.add(new Integer(chunkLen)); chunks.add(chunk); allLen += chunkLen; chunk = new byte[1024 * 4]; chunkLen = is.read(chunk); } all = new byte[allLen]; ofs = 0; max = chunks.size(); for (i = 0; i < max; i += 2) { chunkLen = ((Integer) chunks.get(i)).intValue(); chunk = (byte[]) chunks.get(i + 1); System.arraycopy(chunk, 0, all, ofs, chunkLen); ofs += chunkLen; } if (all.length == 0) return null; return builder.parse(new InputSource(new ByteArrayInputStream(all))); } }