Java tutorial
/* ========================================================================== * * Copyright (C) 2006, 2007 TAO Consulting Pte <http://www.taoconsulting.sg/> * * based on work of * * (C) 2004-2005 Pier Fumagalli <http://www.betaversion.org/~pier/> * * All rights reserved. * * ========================================================================== * * * * 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 biz.taoconsulting.dominodav.methods; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import biz.taoconsulting.dominodav.LockInfo; import biz.taoconsulting.dominodav.LockManager; import biz.taoconsulting.dominodav.exceptions.DAVNotFoundException; import biz.taoconsulting.dominodav.interfaces.IDAVRepository; import biz.taoconsulting.dominodav.interfaces.IDAVResource; /** * Writes a new / edit an existing file. Usually a HEAD and a PROPFIND request * open the PUT request to make sure if the file exists and to tell the server * about file properties of the following stream. * * @author Bastian Buch (TAO Consulting) * */ public class PUT extends AbstractDAVMethod { /** * The logger object for event logging */ private static final Log LOGGER = LogFactory.getLog(PUT.class); /** * (non-Javadoc) * * @see biz.taoconsulting.dominodav.methods.AbstractDAVMethod#action() */ public void action() throws Exception { IDAVRepository rep = this.getRepository(); // uri is the unique identifier on the host includes servlet and // repository but not server String curURI = (String) this.getHeaderValues().get("uri"); IDAVResource resource = null; InputStream instream = null; OutputStream out = null; boolean success = true; String relockToken = this.getRelockToken(this.getReq()); LockManager lm = this.getLockManager(); Long TimeOutValue = this.getTimeOutValue(this.getReq()); // String lockrequestorName = // this.getOwnerFromXMLLockRequest(this.getReq()); int status = HttpServletResponse.SC_OK; // We presume success LockInfo li = null; try { curURI = java.net.URLDecoder.decode(curURI, "UTF-8"); } catch (Exception e) { } try { // LOGGER.info("getResource"); resource = rep.getResource(curURI, true); } catch (DAVNotFoundException e) { // This exception isn't a problem since we just can create the new // URL // LOGGER.info("Exception not found resource"); } if (resource == null) { // LOGGER.info("Resource Null start create new resource"); resource = rep.createNewResource(curURI); // isNew=true; } if (resource == null) { // LOGGER.info("Error, resource is null"); // Set the return error // Unprocessable Entity (see // http://www.webdav.org/specs/rfc2518.html#status.code.extensions.to.http11) this.setHTTPStatus(422); } else { if (relockToken != null) { li = lm.relock(resource, relockToken, TimeOutValue); if (li == null) { String eString = "Relock failed for " + relockToken; LOGGER.debug(eString); this.setErrorMessage(eString, 412); // Precondition failed status = 412; } else { LOGGER.debug("successful relock for " + relockToken + ", new Token:" + li.getToken()); status = HttpServletResponse.SC_OK; } } if (status >= 400) { this.setHTTPStatus(status); HttpServletResponse resp = this.getResp(); resp.setStatus(status); return; } try { instream = this.getReq().getInputStream(); out = resource.getOutputStream(); } catch (Exception e) { LOGGER.error("Input/Output stream creation failed", e); success = false; this.setErrorMessage("Input/Output stream creation failed in PUT for " + curURI, 501); } if (success) { try { int read = 0; byte[] bytes = new byte[2 * 2048]; // TODO: are 2 KB blocks // the right size? while ((read = instream.read(bytes)) != -1) { // LOGGER.info("Read total"+ new // Integer(read).toString() +" bytes"); out.write(bytes, 0, read); // LOGGER.info("Write total"+ new // Integer(read).toString() +" bytes"); } } catch (Exception ex) { LOGGER.error(ex); } finally { try { if (instream != null) { instream.close(); // LOGGER.info("istream successfully closed"); } } catch (Exception finalE) { // Not a fatal error LOGGER.error("Put stream closing failed", finalE); } try { if (out != null) { // LOGGER.info("out closed"); out.flush(); // LOGGER.info("Output stream flushed"); out.close(); // LOGGER.info("Output stream closed"); } } catch (Exception outE) { // Success is false! LOGGER.error("closing of output stream (and saving) failed", outE); this.setErrorMessage("closing of output stream (and saving) failed for" + curURI, 501); success = false; } } } } if (this.getReq().getContentLength() == 0) { this.setHTTPStatus(HttpServletResponse.SC_CREATED); HttpServletResponse resp = this.getResp(); resp.setStatus(HttpServletResponse.SC_CREATED); return; } this.setHTTPStatus(HttpServletResponse.SC_OK); HttpServletResponse resp = this.getResp(); resp.setStatus(HttpServletResponse.SC_OK); } /** * (non-Javadoc) * * @see biz.taoconsulting.dominodav.methods.AbstractDAVMethod#writeInitialHeader() */ protected void writeInitialHeader() { // No action needed } private String getRelockToken(HttpServletRequest req) { /* * The token looks like this: If: * (<opaquelocktoken:fecc6ff70de5a701f6a52bb53fec9083>) */ String result = null; String relockToken = req.getHeader("If"); if (relockToken != null) { int start = relockToken.indexOf("<"); int end = relockToken.lastIndexOf(">"); if (start > 0 && end > start + 1) { result = relockToken.substring(start + 1, end); } } return result; } private Long getTimeOutValue(HttpServletRequest req) { String TimeOutHeader = req.getHeader("Timeout"); Long TimeOutValue = LockManager.MAX_LOCK_DURATION_SEC; if (TimeOutHeader != null) { int whereDoSecondsStart = TimeOutHeader.indexOf('-') + 1; if (whereDoSecondsStart > 0) { try { String sub = TimeOutHeader.substring(whereDoSecondsStart); TimeOutValue = new Long(sub).longValue(); if (TimeOutValue > LockManager.MAX_LOCK_DURATION_SEC) { TimeOutValue = LockManager.MAX_LOCK_DURATION_SEC; } } catch (Exception e) { // The header could not get converted TimeOutValue = LockManager.MAX_LOCK_DURATION_SEC; } } } return TimeOutValue; } }