/*==========================================================================*\ | $Id: DirectoryResource.java,v 1.3 2011/10/25 12:59:33 stedwar2 Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2011 Virginia Tech | | This file is part of Web-CAT. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU Affero General Public License as published | by the Free Software Foundation; either version 3 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU Affero General Public License | along with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package org.webcat.core.webdav; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.RefSpec; import org.webcat.core.Application; import org.webcat.core.FileUtilities; import org.webcat.core.User; import org.webcat.core.git.GitUtilities; import org.webcat.core.git.http.RepositoryRequestUtils; import org.webcat.woextensions.WCContext; import com.bradmcevoy.http.Auth; import com.bradmcevoy.http.CollectionResource; import com.bradmcevoy.http.CopyableResource; import com.bradmcevoy.http.DeletableResource; import com.bradmcevoy.http.GetableResource; import com.bradmcevoy.http.LockInfo; import com.bradmcevoy.http.LockResult; import com.bradmcevoy.http.LockTimeout; import com.bradmcevoy.http.LockToken; import com.bradmcevoy.http.LockingCollectionResource; import com.bradmcevoy.http.MakeCollectionableResource; import com.bradmcevoy.http.MoveableResource; import com.bradmcevoy.http.PropFindableResource; import com.bradmcevoy.http.PutableResource; import com.bradmcevoy.http.Range; import com.bradmcevoy.http.Request; import com.bradmcevoy.http.Resource; import com.bradmcevoy.http.XmlWriter; import com.bradmcevoy.http.exceptions.NotAuthorizedException; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WORequest; import com.webobjects.appserver.WOResponse; //------------------------------------------------------------------------- /** * A DAV resources that represents a directory. * * @author Tony Allevato * @author Last changed by $Author: stedwar2 $ * @version $Revision: 1.3 $, $Date: 2011/10/25 12:59:33 $ */ public class DirectoryResource extends AbstractFSResource implements MakeCollectionableResource, PutableResource, CopyableResource, DeletableResource, MoveableResource, PropFindableResource, LockingCollectionResource, GetableResource { //~ Constructors .......................................................... // ---------------------------------------------------------- public DirectoryResource(WorkingCopyResourceFactory factory, DAVPath path, Repository workingCopy) { this(factory, path, workingCopy, null); } // ---------------------------------------------------------- public DirectoryResource(WorkingCopyResourceFactory factory, DAVPath path, Repository workingCopy, String shadowName) { super(factory, path, workingCopy); this.shadowName = shadowName; } //~ Methods ............................................................... // ---------------------------------------------------------- public boolean canModify() { return path().path().length() > 0; } // ---------------------------------------------------------- public boolean canModifyContents() { return true; } // ---------------------------------------------------------- public CollectionResource createCollection(String name) throws NotAuthorizedException { if (!canModifyContents()) { throw new NotAuthorizedException(this); } log.debug("createCollection: " + path() + ", " + name); DAVPath fnew = new DAVPath(path(), name); boolean ok = fnew.toFile().mkdir(); if (!ok) { throw new RuntimeException("Failed to create: " + fnew); } return new DirectoryResource(factory(), fnew, workingCopy()); } // ---------------------------------------------------------- public Resource child(String name) { DAVPath fchild = new DAVPath(path(), name); return factory().resolveFile(fchild, workingCopy()); } // ---------------------------------------------------------- public List<? extends Resource> getChildren() { ArrayList<AbstractFSResource> list = new ArrayList<AbstractFSResource>(); File[] files = path().toFile().listFiles(); if (files != null) { for (File fchild : files) { DAVPath childPath = new DAVPath(path(), fchild.getName()); AbstractFSResource res = factory().resolveFile(childPath, workingCopy()); if (res != null) { list.add(res); } else { log.error("Couldnt resolve file " + childPath); } } } return list; } // ---------------------------------------------------------- /** * Will redirect if a default page has been specified on the factory * * @param request * @return a URL to redirect to, or null if no redirect should occur */ public String checkRedirect(Request request) { return null; } // ---------------------------------------------------------- public Resource createNew(String name, InputStream in, Long length, String contentType) throws IOException, NotAuthorizedException { if (!canModifyContents()) { throw new NotAuthorizedException(this); } log.debug("createNew: " + path() + ", " + name); DAVPath destPath = new DAVPath(path(), name); FileOutputStream out = null; try { out = new FileOutputStream(destPath.toFile()); FileUtilities.copyStream(in, out); } finally { FileUtilities.closeQuietly(out); } pushWorkingCopy(); return factory().resolveFile(destPath, workingCopy()); } // ---------------------------------------------------------- @Override protected void doCopy(File dest) { try { File newDir = new File(dest, path().name()); newDir.mkdir(); FileUtilities.copyDirectoryContents(path().toFile(), newDir); pushWorkingCopy(); } catch (IOException ex) { throw new RuntimeException("Failed to copy to:" + dest.getAbsolutePath(), ex); } } // ---------------------------------------------------------- public LockToken createAndLock(String name, LockTimeout timeout, LockInfo lockInfo) throws NotAuthorizedException { if (!canModifyContents()) { throw new NotAuthorizedException(this); } log.debug("createAndLock: " + path() + ", " + name); DAVPath dest = new DAVPath(path(), name); createEmptyFile(dest); FileResource newRes = new FileResource(factory(), dest, workingCopy()); LockResult res = newRes.lock(timeout, lockInfo); pushWorkingCopy(); return res.getLockToken(); } // ---------------------------------------------------------- private void createEmptyFile(DAVPath path) { FileOutputStream fout = null; try { fout = new FileOutputStream(path.toFile()); } catch (IOException e) { throw new RuntimeException(e); } finally { FileUtilities.closeQuietly(fout); } } // ---------------------------------------------------------- @Override public String getName() { return (shadowName != null) ? shadowName : super.getName(); } // ---------------------------------------------------------- /** * Will generate a listing of the contents of this directory, unless the * factory's allowDirectoryBrowsing has been set to false. * * If so it will just output a message saying that access has been disabled. * * @param out * @param range * @param params * @param contentType * @throws IOException * @throws NotAuthorizedException */ public void sendContent(OutputStream out, Range range, Map<String, String> params, String contentType) throws IOException, NotAuthorizedException { boolean endsWithSlash = MiltonRequestWrapper.currentRequest().uri().endsWith("/"); XmlWriter w = new XmlWriter(out); w.open("html"); w.open("body"); w.begin("h1").open().writeText(this.getName()).close(); w.open("table"); for (Resource r : getChildren()) { String href = (!endsWithSlash ? this.getName() + "/" : "") + r.getName(); if (r instanceof CollectionResource) { href += "/"; } w.open("tr"); w.open("td"); w.begin("a").writeAtt("href", href).open() .writeText(r.getName()).close(); w.close("td"); w.begin("td").open().writeText(r.getModifiedDate() + "").close(); w.close("tr"); } w.close("table"); w.close("body"); w.close("html"); w.flush(); /*WOContext context = Application.wcApplication().createContextForRequest( MiltonRequestWrapper.currentRequest()); DirectoryListingPage page = new DirectoryListingPage(context); page.directory = this; WOResponse response = page.generateResponse(); response.content().writeToStream(out);*/ } // ---------------------------------------------------------- public Long getMaxAgeSeconds(Auth auth) { return null; } // ---------------------------------------------------------- public String getContentType(String accepts) { return "text/html"; } // ---------------------------------------------------------- public Long getContentLength() { return null; } //~ Static/instance variables ............................................. private String shadowName; private static final Logger log = Logger.getLogger(DirectoryResource.class); }