content: /*
   * Copyright 1999,2004 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 net.sf.webdav.methods;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.Arrays;
  import java.util.Locale;
  
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import net.sf.webdav.IMimeTyper;
  import net.sf.webdav.ITransaction;
  import net.sf.webdav.IWebdavStore;
  import net.sf.webdav.StoredObject;
  import net.sf.webdav.WebdavStatus;
  import net.sf.webdav.locking.ResourceLocks;
  import org.apache.tomcat.util.http.fileupload.IOUtils;
  import org.springframework.web.util.UriUtils;
  
  public class DoGet extends DoHead {
  
      private static org.slf4j.Logger LOG = org.slf4j.LoggerFactory
              .getLogger(DoGet.class);
  
      public DoGet(IWebdavStore store, String dftIndexFile, String insteadOf404,
              ResourceLocks resourceLocks, IMimeTyper mimeTyper,
              int contentLengthHeader) {
          super(store, dftIndexFile, insteadOf404, resourceLocks, mimeTyper,
                  contentLengthHeader);
  
      }
  
      protected void doBody(ITransaction transaction, HttpServletResponse resp,
              String path) {
  
          try {
              StoredObject so = _store.getStoredObject(transaction, path);
              if (so.isNullResource()) {
                  String methodsAllowed = DeterminableMethod
                          .determineMethodsAllowed(so);
                  resp.addHeader("Allow", methodsAllowed);
                  resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
                  return;
              }
              OutputStream out = resp.getOutputStream();
              InputStream in = _store.getResourceContent(transaction, path);
              try {
                  if (in != null) {
                      LOG.debug("开始 {}, ", path);
                      IOUtils.copyLarge(in, out);
                      LOG.debug("结束 {}", path);
                  }
              } finally {
                  // flushing causes a IOE if a file is opened on the webserver
                  // client disconnected before server finished sending response
                  try {
                      if (in != null) {
                          in.close();
                      }
                  } catch (Exception e) {
                      LOG.warn("{} Closing InputStream causes Exception!\n", path
                              ,e);
                  }
                  try {
                      out.flush();
                      out.close();
                  } catch (Exception e) {
                      LOG.warn("{} Flushing OutputStream causes Exception!\n", path
                              ,e);
                  }
              }
          } catch (Exception e) {
              LOG.warn("{} doBody causes Exception!\n", path
                      ,e);
              LOG.trace(e.toString());
          }
      }
  
      protected void folderBody(ITransaction transaction, String path,
              HttpServletResponse resp, HttpServletRequest req)
              throws IOException {
  
          StoredObject so = _store.getStoredObject(transaction, path);
          if (so == null) {
              resp.sendError(HttpServletResponse.SC_NOT_FOUND, req
                      .getRequestURI());
          } else {
  
              if (so.isNullResource()) {
                  String methodsAllowed = DeterminableMethod
                          .determineMethodsAllowed(so);
                  resp.addHeader("Allow", methodsAllowed);
                  resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
                  return;
              }
  
              if (so.isFolder()) {
                  // TODO some folder response (for browsers, DAV tools
                  // use propfind) in html?
                  Locale locale = req.getLocale();
                  DateFormat shortDF= getDateTimeFormat(req.getLocale());
                  resp.setContentType("text/html");
                  resp.setCharacterEncoding("UTF8");
                  OutputStream out = resp.getOutputStream();
                  String[] children = _store.getChildrenNames(transaction, path);
                  // Make sure it's not null
                  children = children == null ? new String[] {} : children;
                  // Sort by name
                  Arrays.sort(children);
                  StringBuilder childrenTemp = new StringBuilder();
                  childrenTemp.append("<html><head><title>Content of folder");
                  childrenTemp.append(path);
                  childrenTemp.append("</title><style type=\"text/css\">");
                  childrenTemp.append(getCSS());
                  childrenTemp.append("</style></head>");
                  childrenTemp.append("<body>");
                  childrenTemp.append(getHeader(transaction, path, resp, req));
                  childrenTemp.append("<table>");
                  childrenTemp.append("<tr><th>Name</th><th>Size</th><th>Created</th><th>Modified</th></tr>");
                  childrenTemp.append("<tr>");
                  childrenTemp.append("<td colspan=\"4\"><a href=\"../\">Parent</a></td></tr>");
                  boolean isEven= false;
                  for (String child : children)
                  {
                      isEven= !isEven;
                      childrenTemp.append("<tr class=\"");
                      childrenTemp.append(isEven ? "even" : "odd");
                      childrenTemp.append("\">");
                      childrenTemp.append("<td>");
                      childrenTemp.append("<a href=\"");
                      childrenTemp.append(UriUtils.encode(child, "utf-8"));
                      StoredObject obj= _store.getStoredObject(transaction, path+"/"+child);
                      if (obj == null)
                      {
                          LOG.error("Should not return null for "+path+"/"+child);
                      }
                      if (obj != null && obj.isFolder())
                      {
                          childrenTemp.append("/");
                      }
                      childrenTemp.append("\">");
                      childrenTemp.append(child);
                      childrenTemp.append("</a></td>");
                      if (obj != null && obj.isFolder())
                      {
                          childrenTemp.append("<td>Folder</td>");
                      }
                      else
                      {
                          childrenTemp.append("<td>");
                          if (obj != null )
                          {
                              childrenTemp.append(obj.getResourceLength());
                          }
                          else
                          {
                              childrenTemp.append("Unknown");
                          }
                          childrenTemp.append(" Bytes</td>");
                      }
                      if (obj != null && obj.getCreationDate() != null)
                      {
                          childrenTemp.append("<td>");
                          childrenTemp.append(shortDF.format(obj.getCreationDate()));
                          childrenTemp.append("</td>");
                      }
                      else
                      {
                          childrenTemp.append("<td></td>");
                      }
                      if (obj != null  && obj.getLastModified() != null)
                      {
                          childrenTemp.append("<td>");
                          childrenTemp.append(shortDF.format(obj.getLastModified()));
                          childrenTemp.append("</td>");
                      }
                      else
                      {
                          childrenTemp.append("<td></td>");
                      }
                      childrenTemp.append("</tr>");
                  }
                  childrenTemp.append("</table>");
                  childrenTemp.append(getFooter(transaction, path, resp, req));
                  childrenTemp.append("</body></html>");
                  out.write(childrenTemp.toString().getBytes("UTF-8"));
              }
          }
      }
  
      /**
       * Return the CSS styles used to display the HTML representation
       * of the webdav content.
       *
       * @return
       */
      protected String getCSS()
      {
          // The default styles to use
         String retVal= "body {\n"+
                  "	font-family: Arial, Helvetica, sans-serif;\n"+
                  "}\n"+
                  "h1 {\n"+
                  "	font-size: 1.5em;\n"+
                  "}\n"+
                  "th {\n"+
                  "	background-color: #9DACBF;\n"+
                  "}\n"+
                  "table {\n"+
                  "	border-top-style: solid;\n"+
                  "	border-right-style: solid;\n"+
                  "	border-bottom-style: solid;\n"+
                  "	border-left-style: solid;\n"+
                  "}\n"+
                  "td {\n"+
                  "	margin: 0px;\n"+
                  "	padding-top: 2px;\n"+
                  "	padding-right: 5px;\n"+
                  "	padding-bottom: 2px;\n"+
                  "	padding-left: 5px;\n"+
                  "}\n"+
                  "tr.even {\n"+
                  "	background-color: #CCCCCC;\n"+
                  "}\n"+
                  "tr.odd {\n"+
                  "	background-color: #FFFFFF;\n"+
                  "}\n"+
                  "";
          try
          {
              // Try loading one via class loader and use that one instead
              ClassLoader cl = getClass().getClassLoader();
              InputStream iStream = cl.getResourceAsStream("webdav.css");
              if(iStream != null)
              {
                  // Found css via class loader, use that one
                  StringBuffer out = new StringBuffer();
                  byte[] b = new byte[4096];
                  for (int n; (n = iStream.read(b)) != -1;)
                  {
                      out.append(new String(b, 0, n));
  }
                  retVal= out.toString();
              }
          }
          catch (Exception ex)
          {
              LOG.error("Error in reading webdav.css", ex);
          }
  
          return retVal;
      }
  
      /**
       * Return the header to be displayed in front of the folder content
       *
       * @param transaction
       * @param path
       * @param resp
       * @param req
       * @return
       */
      protected String getHeader(ITransaction transaction, String path,
              HttpServletResponse resp, HttpServletRequest req)
      {
          return "<h1>Content of folder "+path+"</h1>";
      }
  
      /**
       * Return the footer to be displayed after the folder content
       *
       * @param transaction
       * @param path
       * @param resp
       * @param req
       * @return
       */
      protected String getFooter(ITransaction transaction, String path,
              HttpServletResponse resp, HttpServletRequest req)
      {
          return "";
      }
  
      /**
       * Return this as the Date/Time format for displaying Creation + Modification dates
       *
       * @param browserLocale
       * @return DateFormat used to display creation and modification dates
       */
      protected DateFormat getDateTimeFormat(Locale browserLocale)
      {
          return SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.MEDIUM, browserLocale);
      }
   }
  