commit - 606c7aeff77ed85d0c8374e5ef56a9fc92549687
commit + de6ddb74522969f7a13e7a09c05b9406d30b5ad6
blob - 366af8a561343bd5d1b259929b35c50840a49bae
blob + 1582d815464b5a6997af06d36a8f835f6544238a
--- pom.xml
+++ pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.thinkberg.moxo</groupId>
- <artifactId>moxo</artifactId>
- <packaging>jar</packaging>
- <version>1.0-SNAPSHOT</version>
- <name>Moxo S3 DAV Proxy</name>
- <url>http://thinkberg.com</url>
- <repositories>
- <repository>
- <id>codehaus-m2-repository</id>
- <name>Codehaus Maven 2.x Repository</name>
- <url>http://repository.codehaus.org</url>
- </repository>
- </repositories>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>jets3t</groupId>
- <artifactId>jets3t</artifactId>
- <version>0.5.0</version>
- </dependency>
- <dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- <version>3.0.1</version>
- </dependency>
- <dependency>
- <groupId>commons-vfs</groupId>
- <artifactId>commons-vfs</artifactId>
- <version>1.0</version>
- </dependency>
- <dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>jetty</artifactId>
- <version>6.1.1</version>
- </dependency>
- <dependency>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- <version>1.6.1</version>
- </dependency>
- <dependency>
- <groupId>jaxen</groupId>
- <artifactId>jaxen</artifactId>
- <version>1.1</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>com.thinkberg.moxo.MoxoJettyRunner</mainClass>
- <addClasspath>true</addClasspath>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.thinkberg.moxo</groupId>
+ <artifactId>moxo</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>Moxo S3 DAV Proxy</name>
+ <url>http://thinkberg.com</url>
+ <repositories>
+ <repository>
+ <id>codehaus-m2-repository</id>
+ <name>Codehaus Maven 2.x Repository</name>
+ <url>http://repository.codehaus.org</url>
+ </repository>
+ <repository>
+ <name>jets3t</name>
+ <id>jets3t</id>
+ <url>http://jets3t.s3.amazonaws.com/maven2</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.java.dev.jets3t</groupId>
+ <artifactId>jets3t</artifactId>
+ <version>0.6.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-vfs</groupId>
+ <artifactId>commons-vfs</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty</artifactId>
+ <version>6.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ <version>1.6.1</version>
+ </dependency>
+ <dependency>
+ <groupId>jaxen</groupId>
+ <artifactId>jaxen</artifactId>
+ <version>1.1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>com.thinkberg.moxo.MoxoJettyRunner</mainClass>
+ <addClasspath>true</addClasspath>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
blob - 81f9dc3075c006734e4d4a76f76f86d0023776df
blob + 834ca79e40db93587eb89c07798c51befb4cdbe8
--- src/main/java/com/thinkberg/moxo/Main.java
+++ src/main/java/com/thinkberg/moxo/Main.java
package com.thinkberg.moxo;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
public class Main {
private final static URL location = Main.class.getProtectionDomain().getCodeSource().getLocation();
- @SuppressWarnings({"RedundantArrayCreation"})
public static void main(String args[])
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
}
Class mainClass = classLoader.loadClass("com.thinkberg.moxo.MoxoJettyRunner");
+ @SuppressWarnings({"RedundantArrayCreation"})
final Method main = mainClass.getDeclaredMethod("main", new Class[]{String[].class});
main.invoke(null, new Object[]{args});
}
*
* @return the classpath
*/
+ @SuppressWarnings({"ConstantConditions"})
private static URL[] initClassPath() {
List<URL> urlArray = new ArrayList<URL>();
InputStream manifestIn = null;
// ignore errors
}
}
- return urlArray.toArray(new URL[0]);
+ return urlArray.toArray(new URL[urlArray.size()]);
}
/**
blob - e1d96cf755ad2bafbd99a230101d870629bf7423
blob + fad5566e89f5e3a1e30cdf358aff899558c340ff
--- src/main/java/com/thinkberg/moxo/MoxoJettyRunner.java
+++ src/main/java/com/thinkberg/moxo/MoxoJettyRunner.java
try {
Server server = new Server();
- XmlConfiguration xmlConfiguration = new XmlConfiguration(getResource(CONF_JETTY_XML));
+ XmlConfiguration xmlConfiguration = new XmlConfiguration(getXmlConfigurationUrl());
xmlConfiguration.configure(server);
server.start();
server.join();
}
}
- @SuppressWarnings({"SameParameterValue"})
- private static URL getResource(String resource) {
- URL url = MoxoJettyRunner.class.getResource("/" + resource);
+ private static URL getXmlConfigurationUrl() {
+ URL url = MoxoJettyRunner.class.getResource("/" + MoxoJettyRunner.CONF_JETTY_XML);
if (null == url) {
try {
- url = new File(resource).toURL();
+ url = new File(MoxoJettyRunner.CONF_JETTY_XML).toURL();
System.err.println("Loading configuration from file: " + url.toExternalForm());
} catch (MalformedURLException e) {
// ignore ...
blob - 15364b45c9595d79770be30f05df170501a74e69 (mode 644)
blob + /dev/null
--- src/main/java/com/thinkberg/moxo/ResourceManager.java
+++ /dev/null
-/*
- * Copyright 2007 Matthias L. Jugel.
- *
- * 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 com.thinkberg.moxo;
-
-import org.apache.commons.vfs.FileObject;
-import org.apache.commons.vfs.FileSystemException;
-import org.apache.commons.vfs.FileSystemManager;
-import org.apache.commons.vfs.VFS;
-import org.jets3t.service.Jets3tProperties;
-
-/**
- * The resource manager is responsible for providing a virtual file system root.
- *
- * @author Matthias L. Jugel
- */
-public class ResourceManager {
- private static FileObject root;
-
- static {
- try {
- String propertiesFileName = System.getProperty("moxo.properties", "moxo.properties");
- Jets3tProperties properties = Jets3tProperties.getInstance(propertiesFileName);
- FileSystemManager fsm = VFS.getManager();
- FileObject rootObject = fsm.resolveFile("s3://" + properties.getStringProperty("bucket", null));
- root = fsm.createVirtualFileSystem(rootObject);
- System.err.println("Created virtual file system: " + rootObject);
- } catch (FileSystemException e) {
- System.err.println("Can't create virtual file system: " + e.getMessage());
- e.printStackTrace();
- }
- }
-
- public static FileObject getFileObject(String path) throws FileSystemException {
- return root.resolveFile(path);
- }
-}
blob - b6e185d27e3e58d31107a6a92117d79beee64682
blob + 12c455d7b8e0da5274b892269a2919198c3cace9
--- src/main/java/com/thinkberg/moxo/dav/CopyMoveBase.java
+++ src/main/java/com/thinkberg/moxo/dav/CopyMoveBase.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.lock.LockException;
import com.thinkberg.moxo.dav.lock.LockManager;
import org.apache.commons.vfs.FileObject;
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
boolean overwrite = getOverwrite(request);
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
FileObject targetObject = getDestination(request);
try {
blob - 3533537d1b03790bb012ae0befe0c5539f1330a5
blob + bd7f9830c75e3fb90449db9a7f2685aeeff2e237
--- src/main/java/com/thinkberg/moxo/dav/DeleteHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/DeleteHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.lock.LockException;
import com.thinkberg.moxo.dav.lock.LockManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSelectInfo;
import org.apache.commons.vfs.FileSelector;
* @version $Id$
*/
public class DeleteHandler extends WebdavHandler {
+ private static final Log LOG = LogFactory.getLog(DeleteHandler.class);
private final static FileSelector ALL_FILES_SELECTOR = new FileSelector() {
public boolean includeFile(FileSelectInfo fileSelectInfo) throws Exception {
};
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
if (request instanceof Request) {
String fragment = ((Request) request).getUri().getFragment();
if (fragment != null) {
}
if (object.exists()) {
- if (object.delete(ALL_FILES_SELECTOR) > 0) {
+ int deletedObjects = object.delete(ALL_FILES_SELECTOR);
+ LOG.debug("deleted " + deletedObjects + " objects");
+ if (deletedObjects > 0) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
blob - bcfd04dc1bfcf5fd118934e8a0108b8e9f592b13
blob + 2d54a47a9b4dc425e1300cefea568d7718c7f90f
--- src/main/java/com/thinkberg/moxo/dav/GetHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/GetHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import org.apache.commons.vfs.FileContent;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
public class GetHandler extends WebdavHandler {
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
if (object.exists()) {
if (FileType.FOLDER.equals(object.getType())) {
blob - 51fd09bff59cddb5c4212b9d20ddb56a28d8c5d3
blob + 214793924ede616c96a919382f76715c89613a58
--- src/main/java/com/thinkberg/moxo/dav/HeadHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/HeadHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileType;
public class HeadHandler extends GetHandler {
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
if (object.exists()) {
if (FileType.FOLDER.equals(object.getType())) {
blob - 8e7e95dc2594e7ce20d4a8e2afd6b1d6729fb992
blob + d4223a80e73f36560895ea20948921ce11bb8739
--- src/main/java/com/thinkberg/moxo/dav/LockHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/LockHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.lock.Lock;
import com.thinkberg.moxo.dav.lock.LockConflictException;
import com.thinkberg.moxo.dav.lock.LockException;
import com.thinkberg.moxo.dav.lock.LockManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.DocumentHelper;
-import org.dom4j.Element;
-import org.dom4j.Node;
+import org.dom4j.*;
+import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
* @version $Id$
*/
public class LockHandler extends WebdavHandler {
+ private static final Log LOG = LogFactory.getLog(LockHandler.class);
+
private static final String TAG_LOCKSCOPE = "lockscope";
private static final String TAG_LOCKTYPE = "locktype";
private static final String TAG_OWNER = "owner";
private static final String HEADER_LOCK_TOKEN = "Lock-Token";
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
try {
Lock lock = LockManager.getInstance().checkCondition(object, getIf(request));
}
}
- log("LOCK(" + lockType + ", " + lockScope + ", " + owner + ")");
+ LOG.debug("LOCK(" + lockType + ", " + lockScope + ", " + owner + ")");
Lock requestedLock = new Lock(object, lockType, lockScope, owner, getDepth(request), getTimeout(request));
try {
}
private void sendLockAcquiredResponse(HttpServletResponse response, Lock lock) throws IOException {
+ if (!lock.getObject().exists()) {
+ response.setStatus(SC_CREATED);
+ }
response.setContentType("text/xml");
response.setCharacterEncoding("UTF-8");
response.setHeader(HEADER_LOCK_TOKEN, "<" + lock.getToken() + ">");
XMLWriter xmlWriter = new XMLWriter(response.getWriter());
xmlWriter.write(propDoc);
- log(propDoc);
+
+ logXml(propDoc);
}
+
+ private void logXml(Node element) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try {
+ XMLWriter xmlWriter = new XMLWriter(bos, OutputFormat.createPrettyPrint());
+ xmlWriter.write(element);
+ LOG.debug(bos.toString());
+ } catch (IOException e) {
+ LOG.debug("ERROR writing XML log: " + e.getMessage());
+ }
+ }
}
blob - c7bd42b7da7d33d12157b1d0f6dac1a96b20dfbb
blob + 26c2f2d817fea565d73ce19efee0bf802f26c328
--- src/main/java/com/thinkberg/moxo/dav/MkColHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/MkColHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.lock.LockException;
import com.thinkberg.moxo.dav.lock.LockManager;
import org.apache.commons.vfs.FileObject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
import java.io.IOException;
/**
public class MkColHandler extends WebdavHandler {
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- if (request.getReader().readLine() != null) {
+ BufferedReader bufferedReader = request.getReader();
+ String line = bufferedReader.readLine();
+ if (line != null) {
response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
try {
LockManager.getInstance().checkCondition(object, getIf(request));
blob - fb5876098ccd381b67aa1aa2065a55e2ee93d7af
blob + 105b947a18e598dc34be32c8564a80e80f7fa409
--- src/main/java/com/thinkberg/moxo/dav/OptionsHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/OptionsHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileType;
String path = request.getPathInfo();
StringBuffer options = new StringBuffer();
- FileObject object = ResourceManager.getFileObject(path);
+ FileObject object = getVFSObject(path);
if (object.exists()) {
options.append("OPTIONS, GET, HEAD, POST, DELETE, TRACE, COPY, MOVE, LOCK, UNLOCK, PROPFIND");
if (FileType.FOLDER.equals(object.getType())) {
blob - 169c09204e05f26f192ab23f7ad567443352bb55
blob + 9f8b33f2d2f8c952a1dba98b56c888dad88670b3
--- src/main/java/com/thinkberg/moxo/dav/PropFindHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/PropFindHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.data.DavResource;
import com.thinkberg.moxo.dav.data.DavResourceFactory;
import com.thinkberg.moxo.vfs.DepthFileSelector;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.DocumentHelper;
-import org.dom4j.Element;
+import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
private static final String TAG_MULTISTATUS = "multistatus";
private static final String TAG_HREF = "href";
private static final String TAG_RESPONSE = "response";
+ private static final Log LOG = LogFactory.getLog(PropFindHandler.class);
+ void logXml(Node element) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try {
+ XMLWriter xmlWriter = new XMLWriter(bos, OutputFormat.createPrettyPrint());
+ xmlWriter.write(element);
+ LOG.debug(bos.toString());
+ } catch (IOException e) {
+ LOG.error(e.getMessage());
+ }
+ }
+
+
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
SAXReader saxReader = new SAXReader();
try {
Document propDoc = saxReader.read(request.getInputStream());
- // log(propDoc);
+ logXml(propDoc);
+
Element propFindEl = propDoc.getRootElement();
Element propEl = (Element) propFindEl.elementIterator().next();
String propElName = propEl.getName();
ignoreValues = true;
}
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
if (object.exists()) {
// respond as XML encoded multi status
response.setContentType("text/xml");
getBaseUrl(request),
getDepth(request),
ignoreValues);
- //log(multiStatusResponse);
+ logXml(multiStatusResponse);
// write the actual response
XMLWriter writer = new XMLWriter(response.getWriter(), OutputFormat.createCompactFormat());
writer.close();
} else {
- log("!! " + object.getName().getPath() + " NOT FOUND");
+ LOG.error(object.getName().getPath() + " NOT FOUND");
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
} catch (DocumentException e) {
- log("!! inavlid request: " + e.getMessage());
+ LOG.error("invalid request: " + e.getMessage());
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
}
+ @SuppressWarnings({"ConstantConditions"})
private Document getMultiStatusRespons(FileObject object,
List<String> requestedProperties,
URL baseUrl,
Element responseEl = multiStatus.addElement(TAG_RESPONSE);
try {
URL url = new URL(baseUrl, URLEncoder.encode(child.getName().getPath(), "UTF-8"));
- log("!! " + url);
+ LOG.debug(url);
responseEl.addElement(TAG_HREF).addText(url.toExternalForm());
} catch (Exception e) {
e.printStackTrace();
blob - 9848117271155f8ff4227471f202c991479dffba
blob + 47200c23bde07c62df6a59cebb06f1d458fe4661
--- src/main/java/com/thinkberg/moxo/dav/PropPatchHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/PropPatchHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.data.DavResource;
import com.thinkberg.moxo.dav.lock.LockException;
import com.thinkberg.moxo.dav.lock.LockManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.dom4j.Document;
import org.dom4j.DocumentException;
* @author Matthias L. Jugel
*/
public class PropPatchHandler extends WebdavHandler {
+ private static final Log LOG = LogFactory.getLog(PropPatchHandler.class);
+
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
try {
LockManager.getInstance().checkCondition(object, getIf(request));
Element responseEl = multiStatusResponse.addElement("response");
try {
URL url = new URL(getBaseUrl(request), URLEncoder.encode(object.getName().getPath(), "UTF-8"));
- log("!! " + url);
+ LOG.debug(url);
responseEl.addElement("href").addText(url.toExternalForm());
} catch (Exception e) {
e.printStackTrace();
writer.flush();
writer.close();
} else {
- log("!! " + object.getName().getPath() + " NOT FOUND");
+ LOG.error(object.getName().getPath() + " NOT FOUND");
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
} catch (DocumentException e) {
- log("!! inavlid request: " + e.getMessage());
+ LOG.error("invalid request: " + e.getMessage());
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
}
blob - 7a8e901869c402cbbb6c27b78bb16ebe5cec3292
blob + fc92a3d6e348a399694d0d684681d25c85f99d27
--- src/main/java/com/thinkberg/moxo/dav/PutHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/PutHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.lock.LockException;
import com.thinkberg.moxo.dav.lock.LockManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileType;
* @version $Id$
*/
public class PutHandler extends WebdavHandler {
+ private static final Log LOG = LogFactory.getLog(PutHandler.class);
+
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
try {
LockManager.getInstance().checkCondition(object, getIf(request));
InputStream is = request.getInputStream();
OutputStream os = object.getContent().getOutputStream();
- log("PUT sends " + request.getHeader("Content-length") + " bytes");
- log("PUT copied " + Util.copyStream(is, os) + " bytes");
+ int bytesCopied = Util.copyStream(is, os);
+ LOG.debug("sending " + bytesCopied + "/" + request.getHeader("Content-length") + " bytes");
os.flush();
object.close();
blob - 7e66661da892e8d3514f76702c740496e62ced5d
blob + cdf9f6df05dd32310e05a5e0ab104c03779b15ea
--- src/main/java/com/thinkberg/moxo/dav/URLEncoder.java
+++ src/main/java/com/thinkberg/moxo/dav/URLEncoder.java
*/
class URLEncoder {
- private static BitSet keepPlain;
+ private static final BitSet keepPlain;
static {
keepPlain = new BitSet(256);
}
- @SuppressWarnings({"SameParameterValue"})
public static String encode(String s, String enc) throws UnsupportedEncodingException {
byte[] buf = s.getBytes(enc);
StringBuffer result = new StringBuffer();
blob - c9b1dbfa79cede571c23e5fbce3af2951df4c49e
blob + e9810818ac9e79873202dae184ec9ad09b813804
--- src/main/java/com/thinkberg/moxo/dav/UnlockHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/UnlockHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
import com.thinkberg.moxo.dav.lock.LockManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import javax.servlet.http.HttpServletRequest;
* @version $Id$
*/
public class UnlockHandler extends WebdavHandler {
+ private static final Log LOG = LogFactory.getLog(UnlockHandler.class);
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
- FileObject object = ResourceManager.getFileObject(request.getPathInfo());
+ FileObject object = getVFSObject(request.getPathInfo());
String lockTokenHeader = request.getHeader("Lock-Token");
String lockToken = lockTokenHeader.substring(1, lockTokenHeader.length() - 1);
- log("UNLOCK(" + lockToken + ")");
+ LOG.debug("UNLOCK(" + lockToken + ")");
if (LockManager.getInstance().releaseLock(object, lockToken)) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
blob - 635e944e7bab4630c048790a9115f02f07481a7c
blob + 6cc9911ce6b996e0c0610c4987c090772f356817
--- src/main/java/com/thinkberg/moxo/dav/Util.java
+++ src/main/java/com/thinkberg/moxo/dav/Util.java
}
// public static String getISODateString(long time) {
-// return "";
+// return ""; 4
// }
blob - a74e1a9ff4bbc10d2647532ca2252c2a48acd7c8
blob + bb559777fd0928f6c9ee3f7bb12b897d76ffc0d7
--- src/main/java/com/thinkberg/moxo/dav/WebdavHandler.java
+++ src/main/java/com/thinkberg/moxo/dav/WebdavHandler.java
package com.thinkberg.moxo.dav;
-import com.thinkberg.moxo.ResourceManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
-import org.dom4j.Node;
-import org.dom4j.io.OutputFormat;
-import org.dom4j.io.XMLWriter;
+import org.apache.commons.vfs.FileSystemManager;
+import org.apache.commons.vfs.VFS;
+import org.jets3t.service.Jets3tProperties;
-import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
* @version $Id$
*/
public abstract class WebdavHandler {
+ private static final Log LOG = LogFactory.getLog(WebdavHandler.class);
+
+ static final int SC_CREATED = 201;
static final int SC_LOCKED = 423;
static final int SC_MULTI_STATUS = 207;
- private HttpServlet servlet;
+ private static FileObject fileSystemRoot;
- public void setServlet(HttpServlet servlet) {
- this.servlet = servlet;
- }
-
- public abstract void service(HttpServletRequest request, HttpServletResponse response) throws IOException;
-
- void log(Node element) {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ static {
try {
- XMLWriter xmlWriter = new XMLWriter(bos, OutputFormat.createPrettyPrint());
- xmlWriter.write(element);
- System.out.print(bos.toString());
- } catch (IOException e) {
- servlet.log("!! " + e.getMessage());
+ String propertiesFileName = System.getProperty("moxo.properties", "moxo.properties");
+ Jets3tProperties properties = Jets3tProperties.getInstance(propertiesFileName);
+ FileSystemManager fsm = VFS.getManager();
+
+ // create a virtual filesystemusing the url provided or fall back to RAM
+ fileSystemRoot = fsm.resolveFile(properties.getStringProperty("vfs.url", "ram:/"));
+
+ LOG.info("created virtual file system: " + fileSystemRoot);
+ } catch (FileSystemException e) {
+ LOG.error("can't create virtual file system: " + e.getMessage());
+ e.printStackTrace();
}
}
- void log(String message) {
- servlet.log("## " + message);
+ protected static FileObject getVFSObject(String path) throws FileSystemException {
+ return fileSystemRoot.resolveFile(path);
}
-
- static URL getBaseUrl(HttpServletRequest request) {
+ protected static URL getBaseUrl(HttpServletRequest request) {
try {
String requestUrl = request.getRequestURL().toString();
String requestUri = request.getRequestURI();
return null;
}
+ public abstract void service(HttpServletRequest request, HttpServletResponse response) throws IOException;
/**
* Get the depth header value. This value defines how operations
depthValue = Integer.parseInt(depth);
}
- log("Depth: " + depthValue);
+ LOG.debug("request header: Depth: " + (depthValue == Integer.MAX_VALUE ? "infinity" : depthValue));
return depthValue;
}
boolean getOverwrite(HttpServletRequest request) {
String overwrite = request.getHeader("Overwrite");
boolean overwriteValue = overwrite == null || "T".equals(overwrite);
- log("Overwrite: " + overwriteValue);
+
+ LOG.debug("request header: Overwrite: " + overwriteValue);
return overwriteValue;
}
FileObject targetObject = null;
if (null != targetUrlStr) {
URL target = new URL(targetUrlStr);
- targetObject = ResourceManager.getFileObject(target.getPath());
- log("Destination: " + targetObject.getName().getPath());
+ targetObject = getVFSObject(target.getPath());
+ LOG.debug("request header: Destination: " + targetObject.getName().getPath());
}
return targetObject;
* @return the value if the If: header.
*/
String getIf(HttpServletRequest request) {
- return request.getHeader("If");
+ String getIfHeader = request.getHeader("If");
+
+ if (null != getIfHeader) {
+ LOG.debug("request header: If: " + getIfHeader);
+ }
+ return getIfHeader;
}
/**
String timeout = request.getHeader("Timeout");
if (null != timeout) {
String[] timeoutValues = timeout.split(",[ ]*");
- log(Arrays.asList(timeoutValues).toString());
+ LOG.debug("request header: Timeout: " + Arrays.asList(timeoutValues).toString());
if ("infinity".equalsIgnoreCase(timeoutValues[0])) {
return -1;
} else {
blob - 4356ce41848ea62de23b8a036e7aea950df89046
blob + 82ec809f38ec9a22f32b81ba769787173ef5df2d
--- src/main/java/com/thinkberg/moxo/dav/data/AbstractDavResource.java
+++ src/main/java/com/thinkberg/moxo/dav/data/AbstractDavResource.java
private static final String TAG_PROP = "prop";
private static final String TAG_STATUS = "status";
- @SuppressWarnings({"UnusedReturnValue"})
public Element serializeToXml(Element root, List<String> requestedProperties) {
Element propStatEl = root.addElement(TAG_PROPSTAT);
Element propEl = propStatEl.addElement(TAG_PROP);
return root;
}
+ @SuppressWarnings({"BooleanMethodIsAlwaysInverted"})
protected abstract boolean addPropertyValue(Element root, String propertyName);
}
blob - 918da1c04a6de60ad3be17615e2e920da8a2975b
blob + fcd185c553c3e877a601f195e39e4d1687e16c32
--- src/main/java/com/thinkberg/moxo/dav/data/DavCollection.java
+++ src/main/java/com/thinkberg/moxo/dav/data/DavCollection.java
}
protected boolean addQuotaProperty(Element root) {
- root.addElement(PROP_QUOTA).addText("1000000");
+ root.addElement(PROP_QUOTA).addText("" + Long.MAX_VALUE);
return true;
}
}
protected boolean addQuotaAvailableBytesProperty(Element root) {
- root.addElement(PROP_QUOTA_AVAILABLE_BYTES).addText("1000000");
+ root.addElement(PROP_QUOTA_AVAILABLE_BYTES).addText("" + Long.MAX_VALUE);
return true;
}
blob - 220a25349e7c8e941c9ae4944459052216833000
blob + 60ddbc7d9240cdb82e2d97eba5c93761a077ca9d
--- src/main/java/com/thinkberg/moxo/dav/data/DavResource.java
+++ src/main/java/com/thinkberg/moxo/dav/data/DavResource.java
* @author Matthias L. Jugel
* @version $Id$
*/
-@SuppressWarnings({"SameReturnValue"})
public class DavResource extends AbstractDavResource {
// @see http://www.webdav.org/specs/rfc2518.html#dav.properties
PROP_LOCK_DISCOVERY,
PROP_RESOURCETYPE,
PROP_SOURCE,
- PROP_SUPPORTED_LOCK
+ PROP_SUPPORTED_LOCK,
+ PROP_QUOTA_AVAILABLE_BYTES
);
- private final FileObject object;
- private boolean ignoreValues = false;
+ protected final FileObject object;
+ protected boolean ignoreValues = false;
public DavResource(FileObject object) {
this(object, false);
return false;
}
- @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
protected boolean addCreationDateProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addGetDisplayNameProperty(Element root) {
Element el = root.addElement(PROP_DISPLAY_NAME);
if (!ignoreValues) {
return true;
}
- @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
protected boolean addGetContentLanguageProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addGetContentLengthProperty(Element root) {
try {
Element el = root.addElement(PROP_GET_CONTENT_LENGTH);
}
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addGetContentTypeProperty(Element root) {
try {
String contentType = object.getContent().getContentInfo().getContentType();
}
}
- @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
protected boolean addGetETagProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addGetLastModifiedProperty(Element root) {
try {
Element el = root.addElement(PROP_GET_LAST_MODIFIED);
}
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addLockDiscoveryProperty(Element root) {
Element lockdiscoveryEl = root.addElement(PROP_LOCK_DISCOVERY);
try {
}
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addResourceTypeProperty(Element root) {
root.addElement(PROP_RESOURCETYPE);
return true;
}
- @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
protected boolean addSourceProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addSupportedLockProperty(Element root) {
Element supportedlockEl = root.addElement(PROP_SUPPORTED_LOCK);
if (!ignoreValues) {
return true;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addQuotaProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addQuotaUsedProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addQuotaAvailableBytesProperty(Element root) {
return false;
}
- @SuppressWarnings({"WeakerAccess"})
protected boolean addQuotaUsedBytesProperty(Element root) {
return false;
}
blob - 44f4c9aaa4abefb4b0565650ccaa2960ed875225
blob + 28d71a7844d3ecca4d5bc448fb9e7c6e47913291
--- src/main/java/com/thinkberg/moxo/dav/lock/Lock.java
+++ src/main/java/com/thinkberg/moxo/dav/lock/Lock.java
return depth;
}
- @SuppressWarnings({"WeakerAccess"})
public String getDepthValue() {
switch (depth) {
case 0:
}
}
- @SuppressWarnings({"WeakerAccess"})
public String getTimeout() {
if (timeout == -1) {
return "Infinity";
* @param root the root element to add the activelock to
* @return the root element
*/
- @SuppressWarnings({"UnusedReturnValue"})
public Element serializeToXml(Element root) {
Element activelockEl = root.addElement("activelock");
activelockEl.addElement("locktype").addElement(getType());
* @return whether this lock is for the same file object
*/
public boolean equals(Object other) {
- return object.equals(((Lock) other).object);
+ return other instanceof Lock && object.equals(((Lock) other).object);
}
blob - ee85960287fcb8693e420e89092915792c5c13e3 (mode 644)
blob + /dev/null
--- src/main/java/com/thinkberg/moxo/servlet/MoxoS3WebdavServlet.java
+++ /dev/null
-/*
- * Copyright 2007 Matthias L. Jugel.
- *
- * 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 com.thinkberg.moxo.servlet;
-
-import com.thinkberg.moxo.dav.CopyHandler;
-import com.thinkberg.moxo.dav.DeleteHandler;
-import com.thinkberg.moxo.dav.GetHandler;
-import com.thinkberg.moxo.dav.HeadHandler;
-import com.thinkberg.moxo.dav.LockHandler;
-import com.thinkberg.moxo.dav.MkColHandler;
-import com.thinkberg.moxo.dav.MoveHandler;
-import com.thinkberg.moxo.dav.OptionsHandler;
-import com.thinkberg.moxo.dav.PostHandler;
-import com.thinkberg.moxo.dav.PropFindHandler;
-import com.thinkberg.moxo.dav.PropPatchHandler;
-import com.thinkberg.moxo.dav.PutHandler;
-import com.thinkberg.moxo.dav.UnlockHandler;
-import com.thinkberg.moxo.dav.WebdavHandler;
-import org.mortbay.jetty.Response;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Matthias L. Jugel
- * @version $Id$
- */
-public class MoxoS3WebdavServlet extends HttpServlet {
- private final Map<String, WebdavHandler> handlers = new HashMap<String, WebdavHandler>();
-
- public MoxoS3WebdavServlet() {
- handlers.put("COPY", new CopyHandler());
- handlers.put("DELETE", new DeleteHandler());
- handlers.put("GET", new GetHandler());
- handlers.put("HEAD", new HeadHandler());
- handlers.put("LOCK", new LockHandler());
- handlers.put("MKCOL", new MkColHandler());
- handlers.put("MOVE", new MoveHandler());
- handlers.put("OPTIONS", new OptionsHandler());
- handlers.put("POST", new PostHandler());
- handlers.put("PROPFIND", new PropFindHandler());
- handlers.put("PROPPATCH", new PropPatchHandler());
- handlers.put("PUT", new PutHandler());
- handlers.put("UNLOCK", new UnlockHandler());
-
- for (WebdavHandler handler : handlers.values()) {
- handler.setServlet(this);
- }
- }
-
- public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String method = request.getMethod();
- log(">> " + request.getMethod() + " " + request.getPathInfo());
- if (request.getHeader("X-Litmus") != null) {
- log("!! " + request.getHeader("X-Litmus"));
- }
- if (handlers.containsKey(method)) {
- handlers.get(method).service(request, response);
- } else {
- response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
- }
- Response jettyResponse = ((Response) response);
- String reason = jettyResponse.getReason();
- log("<< " + jettyResponse.getStatus() + (reason != null ? ": " + reason : ""));
- }
-}
blob - /dev/null
blob + c8a306a053d53a8a29bdcfae8a10e3c852f7f3b0 (mode 644)
--- /dev/null
+++ src/main/java/com/thinkberg/moxo/servlet/MoxoWebDAVServlet.java
+/*
+ * Copyright 2007 Matthias L. Jugel.
+ *
+ * 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 com.thinkberg.moxo.servlet;
+
+import com.thinkberg.moxo.dav.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs.FileObject;
+import org.mortbay.jetty.Response;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Matthias L. Jugel
+ * @version $Id$
+ */
+public class MoxoWebDAVServlet extends HttpServlet {
+ private static final Log LOG = LogFactory.getLog(MoxoWebDAVServlet.class);
+
+ private final Map<String, WebdavHandler> handlers = new HashMap<String, WebdavHandler>();
+ private FileObject fileSystemRoot = null;
+
+ public MoxoWebDAVServlet() {
+ handlers.put("COPY", new CopyHandler());
+ handlers.put("DELETE", new DeleteHandler());
+ handlers.put("GET", new GetHandler());
+ handlers.put("HEAD", new HeadHandler());
+ handlers.put("LOCK", new LockHandler());
+ handlers.put("MKCOL", new MkColHandler());
+ handlers.put("MOVE", new MoveHandler());
+ handlers.put("OPTIONS", new OptionsHandler());
+ handlers.put("POST", new PostHandler());
+ handlers.put("PROPFIND", new PropFindHandler());
+ handlers.put("PROPPATCH", new PropPatchHandler());
+ handlers.put("PUT", new PutHandler());
+ handlers.put("UNLOCK", new UnlockHandler());
+ }
+
+ protected FileObject getFileSystemRoot() {
+ return fileSystemRoot;
+ }
+
+ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+// String auth = request.getHeader("Authorization");
+// String login = "", password = "";
+//
+// if (auth != null) {
+// auth = new String(Base64.decodeBase64(auth.substring(auth.indexOf(' ') + 1).getBytes()));
+// login = auth.substring(0, auth.indexOf(':'));
+// password = auth.substring(auth.indexOf(':') + 1);
+// }
+//
+// AWSCredentials credentials = AWSCredentials.load(password, ))
+// if (user == null) {
+// response.setHeader("WWW-Authenticate", "Basic realm=\"Moxo\"");
+// response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+// return;
+// }
+
+
+ String method = request.getMethod();
+ if (request.getHeader("X-Litmus") != null) {
+ LOG.info(String.format("WebDAV Litmus Test: %s", request.getHeader("X-Litmus")));
+ }
+ LOG.debug(String.format(">> %s %s", request.getMethod(), request.getPathInfo()));
+ if (handlers.containsKey(method)) {
+ handlers.get(method).service(request, response);
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
+ }
+ Response jettyResponse = ((Response) response);
+ String reason = jettyResponse.getReason();
+ LOG.debug(String.format("<< %s (%b%s)", request.getMethod(), jettyResponse.getStatus(), reason != null ? ": " + reason : ""));
+ }
+}
blob - c955d451826291a42e1b6aac6197ae8efee01db4
blob + 6e622e49ceb530d686040b60ba8b310b252b7d62
--- src/main/java/com/thinkberg/moxo/vfs/DepthFileSelector.java
+++ src/main/java/com/thinkberg/moxo/vfs/DepthFileSelector.java
this(0, depth);
}
- @SuppressWarnings({"SameParameterValue"})
public DepthFileSelector(int min, int max) {
minDepth = min;
maxDepth = max;
blob - 5768fc6965485ff468abf9e84001279acbb70358
blob + 1dd702d68b6fbe36e2acde95debb98faa1b29a0f
--- src/main/java/com/thinkberg/moxo/vfs/S3FileName.java
+++ src/main/java/com/thinkberg/moxo/vfs/S3FileName.java
* @author Matthias L. Jugel
*/
public class S3FileName extends LocalFileName {
- @SuppressWarnings({"WeakerAccess"})
protected S3FileName(final String scheme, final String rootFile, final String path, final FileType type) {
super(scheme, rootFile, path, type);
}
blob - 9c5d272ffd3f18b369af876efa3fa7762060d730
blob + 34a5d56d0239c568932ce009f30c10cda2b451c7
--- src/main/java/com/thinkberg/moxo/vfs/S3FileNameParser.java
+++ src/main/java/com/thinkberg/moxo/vfs/S3FileNameParser.java
}
-
public FileName parseUri(final VfsComponentContext context, final FileName base, final String filename) throws FileSystemException {
StringBuffer name = new StringBuffer();
blob - 1f34a86342e7cb4329618df20eb9bd5c024e96ca
blob + 8caafbfd75cd2ba1fa4dbd73d893b8cd3df66fd1
--- src/main/java/com/thinkberg/moxo/vfs/S3FileProvider.java
+++ src/main/java/com/thinkberg/moxo/vfs/S3FileProvider.java
package com.thinkberg.moxo.vfs;
-import org.apache.commons.vfs.Capability;
-import org.apache.commons.vfs.FileName;
-import org.apache.commons.vfs.FileSystem;
-import org.apache.commons.vfs.FileSystemException;
-import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.*;
import org.apache.commons.vfs.provider.AbstractOriginatingFileProvider;
import java.util.Arrays;
*/
public class S3FileProvider extends AbstractOriginatingFileProvider {
- public final static Collection capabilities = Collections.unmodifiableCollection(Arrays.asList(
+ public final static Collection<Capability> capabilities = Collections.unmodifiableCollection(Arrays.asList(
Capability.CREATE,
Capability.DELETE,
Capability.RENAME,
));
-
public S3FileProvider() {
super();
setFileNameParser(S3FileNameParser.getInstance());
blob - 8352c585cb21de0f0c73b65170f9e14120ae23b0
blob + 1f080072887e8f54191f85b14ae1e3d922de11bc
--- src/main/java/com/thinkberg/moxo/vfs/jets3t/Jets3tConnector.java
+++ src/main/java/com/thinkberg/moxo/vfs/jets3t/Jets3tConnector.java
package com.thinkberg.moxo.vfs.jets3t;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jets3t.service.Jets3tProperties;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
* @author Matthias L. Jugel
*/
public class Jets3tConnector {
+ private static final Log LOG = LogFactory.getLog(Jets3tConnector.class);
+
private static final String APPLICATION_DESCRIPTION = "S3 VFS Connector/1.0";
private static Jets3tConnector instance;
* if the service cannot be accessed
*/
private Jets3tConnector() throws S3ServiceException {
- System.err.print("Authenticated to Amazon S3: ");
String propertiesFileName = System.getProperty("moxo.properties", "moxo.properties");
Jets3tProperties properties = Jets3tProperties.getInstance(propertiesFileName);
throw new S3ServiceException("can't find S3 configuration: " + propertiesFileName);
}
+
AWSCredentials awsCredentials = new AWSCredentials(
properties.getStringProperty("accesskey", null),
properties.getStringProperty("secretkey", null));
service = new RestS3Service(awsCredentials, APPLICATION_DESCRIPTION, null);
- System.err.println("OK");
+ LOG.info("S3 authentication succeeded");
}
public S3Service getService() {
blob - f5fd3a29646ca8af31028d47e7e86e0dec740e6d
blob + e5e4ff824521e982ee015ee38c6ab14d746cbc0a
--- src/main/java/com/thinkberg/moxo/vfs/jets3t/Jets3tFileObject.java
+++ src/main/java/com/thinkberg/moxo/vfs/jets3t/Jets3tFileObject.java
package com.thinkberg.moxo.vfs.jets3t;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
-import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.provider.AbstractFileObject;
+import org.apache.commons.vfs.util.MonitorOutputStream;
+import org.jets3t.service.Constants;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3Object;
import org.jets3t.service.utils.Mimetypes;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
+import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.Date;
+
/**
* Implementation of the virtual S3 file system object using the Jets3t library.
*
* @author Matthias L. Jugel
*/
public class Jets3tFileObject extends AbstractFileObject {
+ private static final Log LOG = LogFactory.getLog(Jets3tFileObject.class);
+
+ private static final String VFS_LAST_MODIFIED_TIME = "vfs-last-modified-time";
+
private final S3Service service;
private final S3Bucket bucket;
private boolean attached = false;
- private boolean changed = false;
+ private boolean dirty = false;
+ private boolean contentCached = false;
+
private S3Object object;
private File cacheFile;
public Jets3tFileObject(FileName fileName,
Jets3tFileSystem fileSystem,
- S3Service service, S3Bucket bucket)
- throws FileSystemException {
+ S3Service service, S3Bucket bucket) {
super(fileName, fileSystem);
this.service = service;
this.bucket = bucket;
}
+ /**
+ * Attach S3 Object to VFS object.
+ * This method only downloads the meta-data without the actual content.
+ * If the object does not exist, it will be created locally.
+ *
+ * @throws Exception if the S3 access fails for some reason
+ */
protected void doAttach() throws Exception {
if (!attached) {
try {
- object = service.getObject(bucket, getS3Key());
- System.err.println("Attached file to S3 Object: " + object);
- InputStream is = object.getDataInputStream();
- if (object.getContentLength() > 0) {
- ReadableByteChannel rbc = Channels.newChannel(is);
- FileChannel cacheFc = getCacheFileChannel();
- cacheFc.transferFrom(rbc, 0, object.getContentLength());
- cacheFc.close();
- rbc.close();
- } else {
- is.close();
+ object = service.getObjectDetails(bucket, getS3Key());
+ if (object.getMetadata(VFS_LAST_MODIFIED_TIME) == null) {
+ // it is possible the bucket has no last-modified data, use the S3 data then
+ object.addMetadata(Constants.REST_METADATA_PREFIX + VFS_LAST_MODIFIED_TIME, "" + object.getLastModifiedDate().getTime());
}
+ contentCached = false;
+ dirty = false;
+
+ LOG.debug(String.format("attaching (existing) '%s'", object.getKey()));
} catch (S3ServiceException e) {
object = new S3Object(bucket, getS3Key());
- object.setLastModifiedDate(new Date());
- System.err.println("Attached file to new S3 Object: " + object);
+ object.addMetadata(Constants.REST_METADATA_PREFIX + VFS_LAST_MODIFIED_TIME, "" + new Date().getTime());
+ contentCached = true;
+ dirty = true;
+
+ LOG.debug(String.format("attaching (new) '%s'", object.getKey()));
}
+
attached = true;
}
}
protected void doDetach() throws Exception {
- // TODO do not send immediately but put in some kind of upload queue
- if (attached && changed) {
- System.err.println("Detaching changed object: " + object);
+ if (attached) {
+ LOG.debug(String.format("detaching '%s' (dirty=%b, cached=%b)", object.getKey(), dirty, (cacheFile != null)));
+ object = null;
if (cacheFile != null) {
- FileChannel cacheFc = getCacheFileChannel();
- object.setContentLength(cacheFc.size());
- object.setDataInputStream(getInputStream());
+ cacheFile.delete();
+ cacheFile = null;
+ contentCached = false;
}
- System.err.println(object);
- service.putObject(bucket, object);
+ dirty = false;
attached = false;
}
}
protected void doDelete() throws Exception {
+ // do not delete the root folder
+ if ("".equals(object.getKey())) {
+ LOG.warn(String.format("ignored attempt to delete root folder '%s' ", bucket.getName()));
+ return;
+ }
+ LOG.debug(String.format("deleting '%s'", object.getKey()));
service.deleteObject(bucket, object.getKey());
+ if (cacheFile != null) {
+ cacheFile.delete();
+ cacheFile = null;
+ contentCached = false;
+ }
+ dirty = false;
+ attached = false;
}
protected void doRename(FileObject newfile) throws Exception {
protected void doCreateFolder() throws Exception {
if (!Mimetypes.MIMETYPE_JETS3T_DIRECTORY.equals(object.getContentType())) {
object.setContentType(Mimetypes.MIMETYPE_JETS3T_DIRECTORY);
+
+ LOG.debug(String.format("creating folder '%s'", object.getKey()));
service.putObject(bucket, object);
- changed = false;
}
}
protected long doGetLastModifiedTime() throws Exception {
- return object.getLastModifiedDate().getTime();
+ String timeStamp = (String) object.getMetadata(VFS_LAST_MODIFIED_TIME);
+ if (null != timeStamp) {
+ return Long.parseLong(timeStamp);
+ }
+ return 0;
}
protected void doSetLastModifiedTime(final long modtime) throws Exception {
- changed = true;
- object.setLastModifiedDate(new Date(modtime));
+ object.addMetadata(Constants.REST_METADATA_PREFIX + VFS_LAST_MODIFIED_TIME, modtime);
+ dirty = true;
}
protected InputStream doGetInputStream() throws Exception {
- return Channels.newInputStream(getCacheFileChannel());
+ if (!contentCached) {
+ object = service.getObject(bucket, getS3Key());
+ LOG.debug(String.format("caching content of '%s'", object.getKey()));
+
+ InputStream objectInputStream = object.getDataInputStream();
+ if (object.getContentLength() > 0) {
+ ReadableByteChannel rbc = Channels.newChannel(objectInputStream);
+ FileChannel cacheFc = getCacheFile().getChannel();
+ cacheFc.transferFrom(rbc, 0, object.getContentLength());
+ cacheFc.close();
+ rbc.close();
+ } else {
+ objectInputStream.close();
+ }
+ contentCached = true;
+ }
+
+ return Channels.newInputStream(getCacheFile().getChannel());
}
protected OutputStream doGetOutputStream(boolean bAppend) throws Exception {
- changed = true;
- return Channels.newOutputStream(getCacheFileChannel());
+ dirty = true;
+ return new MonitorOutputStream(Channels.newOutputStream(getCacheFile().getChannel())) {
+ protected void onClose() throws IOException {
+ try {
+ LOG.debug(String.format("sending '%s' to storage (dirty=%b, cached=%b)", object.getKey(), dirty, cacheFile));
+ if (cacheFile != null) {
+ FileChannel cacheFc = getCacheFile().getChannel();
+ object.setContentLength(cacheFc.size());
+ object.setDataInputStream(Channels.newInputStream(cacheFc));
+ }
+ service.putObject(bucket, object);
+ } catch (S3ServiceException e) {
+ LOG.error(String.format("can't send object '%s' to storage", object.getKey()), e);
+ }
+ }
+ };
}
protected FileType doGetType() throws Exception {
childrenNames[i] = children[i].getKey().replaceAll("[^/]*//*", "");
}
}
+
return childrenNames;
}
}
}
- private FileChannel getCacheFileChannel() throws IOException {
+ private RandomAccessFile getCacheFile() throws IOException, S3ServiceException {
if (cacheFile == null) {
cacheFile = File.createTempFile("moxo.", ".s3");
}
- return new RandomAccessFile(cacheFile, "rw").getChannel();
+ return new RandomAccessFile(cacheFile, "rw");
}
}
blob - e78aada5f0071545a49f52fb1f86aa003f038a87
blob + 5c2181514077735de9eaee6f6f59f9db52ebc405
--- src/main/java/com/thinkberg/moxo/vfs/jets3t/Jets3tFileSystem.java
+++ src/main/java/com/thinkberg/moxo/vfs/jets3t/Jets3tFileSystem.java
import com.thinkberg.moxo.vfs.S3FileName;
import com.thinkberg.moxo.vfs.S3FileProvider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
* @author Matthias L. Jugel
*/
public class Jets3tFileSystem extends AbstractFileSystem {
+ private static final Log LOG = LogFactory.getLog(Jets3tFileSystem.class);
+
private S3Service service;
private S3Bucket bucket;
String bucketId = fileName.getRootFile();
try {
service = Jets3tConnector.getInstance().getService();
- bucket = new S3Bucket(bucketId);
if (!service.isBucketAccessible(bucketId)) {
+ LOG.info("creating new S3 bucket (" + bucketId + ") for file system");
bucket = service.createBucket(bucketId);
+ } else {
+ LOG.info("using existing S3 bucket: " + bucketId);
+ bucket = new S3Bucket(bucketId);
}
- System.err.println("Created new S3 FileSystem: " + bucketId);
} catch (S3ServiceException e) {
throw new FileSystemException(e);
}
blob - ae39e881510681e8eb8b08d6c28510f4eec11b1d
blob + 3067e4fa327fbd14e218e7adccae96656857cc6b
--- src/main/resources/jetty.xml
+++ src/main/resources/jetty.xml
<Configure id="Server" class="org.mortbay.jetty.Server">
- <!-- =========================================================== -->
- <!-- Server Thread Pool -->
- <!-- =========================================================== -->
- <Set name="ThreadPool">
- <!-- Default bounded blocking threadpool
- -->
- <New class="org.mortbay.thread.BoundedThreadPool">
- <Set name="minThreads">10</Set>
- <Set name="lowThreads">50</Set>
- <Set name="maxThreads">250</Set>
- </New>
+ <!-- =========================================================== -->
+ <!-- Server Thread Pool -->
+ <!-- =========================================================== -->
+ <Set name="ThreadPool">
+ <!-- Default bounded blocking threadpool
+ -->
+ <New class="org.mortbay.thread.BoundedThreadPool">
+ <Set name="minThreads">10</Set>
+ <Set name="lowThreads">50</Set>
+ <Set name="maxThreads">250</Set>
+ </New>
- <!-- Optional Java 5 bounded threadpool with job queue
- <New class="org.mortbay.thread.concurrent.ThreadPool">
- <Arg type="int">0</Arg>
- <Set name="corePoolSize">10</Set>
- <Set name="maximumPoolSize">250</Set>
- </New>
+ <!-- Optional Java 5 bounded threadpool with job queue
+ <New class="org.mortbay.thread.concurrent.ThreadPool">
+ <Arg type="int">0</Arg>
+ <Set name="corePoolSize">10</Set>
+ <Set name="maximumPoolSize">250</Set>
+ </New>
+ -->
+ </Set>
+
+
+ <!-- =========================================================== -->
+ <!-- Set connectors -->
+ <!-- =========================================================== -->
+ <!-- One of each type! -->
+ <!-- =========================================================== -->
+
+ <!-- Use this connector for many frequently idle connections
+ and for threadless continuations.
-->
- </Set>
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.mortbay.jetty.nio.SelectChannelConnector">
+ <Set name="port">
+ <SystemProperty name="jetty.port" default="8080"/>
+ </Set>
+ <Set name="maxIdleTime">30000</Set>
+ <Set name="Acceptors">2</Set>
+ <Set name="confidentialPort">8443</Set>
+ </New>
+ </Arg>
+ </Call>
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.mortbay.jetty.security.SslSocketConnector">
+ <Set name="Port">8443</Set>
+ <Set name="maxIdleTime">30000</Set>
+ <Set name="keystore"><SystemProperty name="user.home" default="."/>/.keystore
+ </Set>
+ <Set name="password">OBF:1fvu20731x191vul1vup1x1d20731ftg</Set>
+ <Set name="keyPassword">OBF:1fvu20731x191vul1vup1x1d20731ftg</Set>
+ <Set name="truststore"><SystemProperty name="user.home" default="."/>/.keystore
+ </Set>
+ <Set name="trustPassword">OBF:1fvu20731x191vul1vup1x1d20731ftg</Set>
+ </New>
+ </Arg>
+ </Call>
- <!-- =========================================================== -->
- <!-- Set connectors -->
- <!-- =========================================================== -->
- <!-- One of each type! -->
- <!-- =========================================================== -->
+ <!-- Use this connector if NIO is not available.
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.mortbay.jetty.bio.SocketConnector">
+ <Set name="port">8081</Set>
+ <Set name="maxIdleTime">50000</Set>
+ <Set name="lowResourceMaxIdleTime">1500</Set>
+ </New>
+ </Arg>
+ </Call>
+ -->
- <!-- Use this connector for many frequently idle connections
- and for threadless continuations.
- -->
- <Call name="addConnector">
- <Arg>
- <New class="org.mortbay.jetty.nio.SelectChannelConnector">
- <Set name="port">
- <SystemProperty name="jetty.port" default="8080"/>
- </Set>
- <Set name="maxIdleTime">30000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="confidentialPort">8443</Set>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <!-- To add a HTTPS SSL listener -->
+ <!-- see jetty-ssl.xml to add an ssl connector. use -->
+ <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <!-- =========================================================== -->
+ <!-- Set up global session ID manager -->
+ <!-- =========================================================== -->
+ <!--
+ <Set name="sessionIdManager">
+ <New class="org.mortbay.jetty.servlet.HashSessionIdManager">
+ <Set name="workerName">node1</Set>
</New>
- </Arg>
- </Call>
+ </Set>
+ -->
+ <!-- =========================================================== -->
+ <!-- Set handler Collection Structure -->
+ <!-- =========================================================== -->
+ <Set name="handler">
+ <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
+ <Set name="handlers">
+ <Array type="org.mortbay.jetty.Handler">
+ <Item>
+ <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
+ </Item>
+ <Item>
+ <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
+ </Item>
+ <Item>
+ <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
+ </Item>
+ </Array>
+ </Set>
+ </New>
+ </Set>
- <!-- Use this connector if NIO is not available.
- <Call name="addConnector">
- <Arg>
- <New class="org.mortbay.jetty.bio.SocketConnector">
- <Set name="port">8081</Set>
- <Set name="maxIdleTime">50000</Set>
- <Set name="lowResourceMaxIdleTime">1500</Set>
+ <!-- Set the handler for our web dav servlet -->
+ <Set name="handler">
+ <New id="WebDAVServletContext" class="org.mortbay.jetty.servlet.Context">
+ <Set name="contextPath">/</Set>
+ <Set name="resourceBase">
+ <SystemProperty name="jetty.docroot" default="."/>
+ </Set>
+ <Call name="addServlet">
+ <Arg>com.thinkberg.moxo.servlet.MoxoWebDAVServlet</Arg>
+ <Arg>/*</Arg>
+ </Call>
</New>
- </Arg>
- </Call>
- -->
+ </Set>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTPS SSL listener -->
- <!-- see jetty-ssl.xml to add an ssl connector. use -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- =========================================================== -->
- <!-- Set up global session ID manager -->
- <!-- =========================================================== -->
- <!--
- <Set name="sessionIdManager">
- <New class="org.mortbay.jetty.servlet.HashSessionIdManager">
- <Set name="workerName">node1</Set>
- </New>
- </Set>
- -->
-
- <!-- =========================================================== -->
- <!-- Set handler Collection Structure -->
- <!-- =========================================================== -->
- <Set name="handler">
- <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
- <Set name="handlers">
- <Array type="org.mortbay.jetty.Handler">
- <Item>
- <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
- </Item>
- <Item>
- <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
- </Item>
- <Item>
- <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
- </Item>
+ <!-- =========================================================== -->
+ <!-- Configure Authentication Realms -->
+ <!-- Realms may be configured for the entire server here, or -->
+ <!-- they can be configured for a specific web app in a context -->
+ <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
+ <!-- example). -->
+ <!-- =========================================================== -->
+ <Set name="UserRealms">
+ <Array type="org.mortbay.jetty.security.UserRealm">
+ <!--
+ <Item>
+ <New class="org.mortbay.jetty.security.HashUserRealm">
+ <Set name="name">Test Realm</Set>
+ <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
+ </New>
+ </Item>
+ -->
</Array>
- </Set>
- </New>
- </Set>
-
- <!-- Set the handler for our web dav servlet -->
- <Set name="handler">
- <New id="WebDAVServletContext" class="org.mortbay.jetty.servlet.Context">
- <Set name="contextPath">/</Set>
- <Set name="resourceBase">
- <SystemProperty name="jetty.docroot" default="."/>
- </Set>
- <Call name="addServlet">
- <Arg>com.thinkberg.moxo.servlet.MoxoS3WebdavServlet</Arg>
- <Arg>/*</Arg>
- </Call>
- </New>
- </Set>
-
-
- <!-- =========================================================== -->
- <!-- Configure Authentication Realms -->
- <!-- Realms may be configured for the entire server here, or -->
- <!-- they can be configured for a specific web app in a context -->
- <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
- <!-- example). -->
- <!-- =========================================================== -->
- <Set name="UserRealms">
- <Array type="org.mortbay.jetty.security.UserRealm">
- <!--
- <Item>
- <New class="org.mortbay.jetty.security.HashUserRealm">
- <Set name="name">Test Realm</Set>
- <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
- </New>
- </Item>
- -->
- </Array>
- </Set>
-
- <!-- =========================================================== -->
- <!-- Configure Request Log -->
- <!-- Request logs may be configured for the entire server here, -->
- <!-- or they can be configured for a specific web app in a -->
- <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
- <!-- for an example). -->
- <!-- =========================================================== -->
- <Ref id="RequestLog">
- <Set name="requestLog">
- <New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
- <Arg>
- <SystemProperty name="jetty.logs" default="./logs"/>
- /yyyy_mm_dd.request.log
- </Arg>
- <Set name="retainDays">90</Set>
- <Set name="append">true</Set>
- <Set name="extended">false</Set>
- <Set name="LogTimeZone">GMT</Set>
- </New>
</Set>
- </Ref>
- <!-- =========================================================== -->
- <!-- extra options -->
- <!-- =========================================================== -->
- <Set name="stopAtShutdown">true</Set>
- <!-- ensure/prevent Server: header being sent to browsers -->
- <Set name="sendServerVersion">true</Set>
+ <!-- =========================================================== -->
+ <!-- Configure Request Log -->
+ <!-- Request logs may be configured for the entire server here, -->
+ <!-- or they can be configured for a specific web app in a -->
+ <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
+ <!-- for an example). -->
+ <!-- =========================================================== -->
+ <Ref id="RequestLog">
+ <Set name="requestLog">
+ <New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
+ <Arg>
+ <SystemProperty name="jetty.logs" default="./logs"/>
+ /yyyy_mm_dd.request.log
+ </Arg>
+ <Set name="retainDays">90</Set>
+ <Set name="append">true</Set>
+ <Set name="extended">false</Set>
+ <Set name="LogTimeZone">GMT</Set>
+ </New>
+ </Set>
+ </Ref>
+ <!-- =========================================================== -->
+ <!-- extra options -->
+ <!-- =========================================================== -->
+ <Set name="stopAtShutdown">true</Set>
+ <!-- ensure/prevent Server: header being sent to browsers -->
+ <Set name="sendServerVersion">true</Set>
+
</Configure>
blob - cf3d423ee160e82b17ab56a44e55faddac0f384d
blob + 2431b8fe9d36132a3fa0f91baef89bc9df06ccc6
--- src/main/resources/moxo.template.properties
+++ src/main/resources/moxo.template.properties
password=<some encryption password here>
# the bucket that contains the file system
-bucket=<the file system bucket>
\ No newline at end of file
+s3.url=s3://TESTBUCKET/
+#s3.url=ram:/
\ No newline at end of file
blob - 253190f1ea5939f131d17688ef3a6e947791f8eb
blob + 5b43b0aee4de7daf1be61d57c1bd4be286fef0fd
--- src/main/resources/simplelog.properties
+++ src/main/resources/simplelog.properties
# limitations under the License.
#
-org.apache.commons.logging.simplelog.defaultlog=info
\ No newline at end of file
+org.apache.commons.logging.simplelog.defaultlog=error
+org.apache.commons.logging.simplelog.log.com.thinkberg.moxo=debug
\ No newline at end of file
blob - 75d3440d7341f1159ea710440ef5a4d9ab1c7e4a
blob + 9ac36182f7b6d695e49901c76968ce5efc0a39bf
--- src/test/java/com/thinkberg/moxo/MoxoTest.java
+++ src/test/java/com/thinkberg/moxo/MoxoTest.java
String propertiesFileName = System.getProperty("moxo.properties", "moxo.properties");
Jets3tProperties properties = Jets3tProperties.getInstance(propertiesFileName);
- String bucketId = properties.getStringProperty("bucket", null);
- if (null != bucketId) {
+ String vfsUrl = properties.getStringProperty("vfs.url", null);
+ if (null != vfsUrl && vfsUrl.startsWith("s3:")) {
s.addTestSuite(S3FileNameTest.class);
s.addTestSuite(S3FileProviderTest.class);
}
blob - 111a1dbd66bf028541af96c6cc04d9feef45c600 (mode 644)
blob + /dev/null
--- src/test/java/com/thinkberg/moxo/S3TestCase.java
+++ /dev/null
-/*
- * Copyright 2007 Matthias L. Jugel.
- *
- * 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 com.thinkberg.moxo;
-
-import junit.framework.TestCase;
-import org.jets3t.service.Jets3tProperties;
-
-/**
- * @author Matthias L. Jugel
- */
-public class S3TestCase extends TestCase {
- protected final static String BUCKETID;
- protected static final String ROOT;
-
- static {
- String propertiesFileName = System.getProperty("moxo.properties", "moxo.properties");
- Jets3tProperties properties = Jets3tProperties.getInstance(propertiesFileName);
-
- BUCKETID = properties.getStringProperty("bucket", null);
- ROOT = "s3://" + BUCKETID;
-
- }
-}
blob - 0a640610fa6e6e3de857f625d04981a4eaa3f1d3
blob + c348a78e06fa4feda0222993ce6a971a7d0994fa
--- src/test/java/com/thinkberg/moxo/dav/DavTestCase.java
+++ src/test/java/com/thinkberg/moxo/dav/DavTestCase.java
aDirectory.createFolder();
}
- @SuppressWarnings({"SameParameterValue"})
protected void testPropertyValue(FileObject object, String propertyName, String propertyValue) throws FileSystemException {
Element root = serializeDavResource(object, propertyName);
assertEquals(propertyValue, selectExistingPropertyValue(root, propertyName));
return root.selectSingleNode(PROP_MISSING + propertyName);
}
- @SuppressWarnings({"SameParameterValue"})
String selectMissingPropertyName(Element root, String propertyName) {
return selectMissingProperty(root, propertyName).getName();
}
blob - 91cc77a793bd5a99291d9625ec74622b90b9102d
blob + cad1af21c05c18a65efeb78b403be26e71fca272
--- src/test/java/com/thinkberg/moxo/vfs/S3FileNameTest.java
+++ src/test/java/com/thinkberg/moxo/vfs/S3FileNameTest.java
package com.thinkberg.moxo.vfs;
-import junit.framework.TestCase;
-import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileName;
-import org.jets3t.service.Jets3tProperties;
-import com.thinkberg.moxo.S3TestCase;
+import org.apache.commons.vfs.FileSystemException;
+import java.net.URI;
+
/**
* @author Matthias L. Jugel
*/
public class S3FileNameTest extends S3TestCase {
public void testGetBucketFromUri() throws FileSystemException {
- String uri = ROOT + "/junk.txt";
- FileName fileName = S3FileNameParser.getInstance().parseUri(null, null, uri);
- assertEquals(BUCKETID, ((S3FileName)fileName).getRootFile());
+ String uriString = ROOT + "/junk.txt";
+ String bucketId = URI.create(uriString).getHost();
+ FileName fileName = S3FileNameParser.getInstance().parseUri(null, null, uriString);
+ assertEquals(bucketId, ((S3FileName) fileName).getRootFile());
}
public void testGetRootFolderFromUri() throws FileSystemException {
blob - 9f9b360ec733337b7a07da2071e596cd97c791fb
blob + 38485aeefa013dff633c31b5e00104bd1efcdd46
--- src/test/java/com/thinkberg/moxo/vfs/S3FileProviderTest.java
+++ src/test/java/com/thinkberg/moxo/vfs/S3FileProviderTest.java
package com.thinkberg.moxo.vfs;
-import com.thinkberg.moxo.S3TestCase;
-import org.apache.commons.vfs.FileObject;
-import org.apache.commons.vfs.FileSelectInfo;
-import org.apache.commons.vfs.FileSelector;
-import org.apache.commons.vfs.FileSystem;
-import org.apache.commons.vfs.FileSystemException;
-import org.apache.commons.vfs.FileType;
-import org.apache.commons.vfs.VFS;
+import org.apache.commons.vfs.*;
import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Arrays;
/**
* @author Matthias L. Jugel
*/
public class S3FileProviderTest extends S3TestCase {
+ private static final FileSelector ALL_FILE_SELECTOR = new FileSelector() {
+
+ public boolean includeFile(FileSelectInfo fileInfo) throws Exception {
+ return true;
+ }
+
+ public boolean traverseDescendents(FileSelectInfo fileInfo) throws Exception {
+ return true;
+ }
+ };
+ private static final String FOLDER = "/directory";
+ private static final String FILE = FOLDER + "/newfile.txt";
+
+ static {
+ try {
+ FileObject rootFs = VFS.getManager().resolveFile(ROOT);
+ rootFs.delete(ALL_FILE_SELECTOR);
+ } catch (FileSystemException e) {
+ // just delete, ignore the rest
+ }
+ }
+
public void testDoCreateFileSystem() throws FileSystemException {
FileObject object = VFS.getManager().resolveFile(ROOT);
- assertEquals(BUCKETID, ((S3FileName) object.getName()).getRootFile());
+ String bucketId = URI.create(ROOT).getHost();
+ assertEquals(bucketId, ((S3FileName) object.getName()).getRootFile());
}
+
+ public void testFileSystemIsEmpty() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT);
+ assertEquals(1, object.findFiles(ALL_FILE_SELECTOR).length);
+ }
+
public void testRootDirectoryIsFolder() throws FileSystemException {
FileObject object = VFS.getManager().resolveFile(ROOT);
assertEquals(FileType.FOLDER, object.getType());
}
- public void testGetDirectory() throws FileSystemException {
- FileObject object = VFS.getManager().resolveFile(ROOT + "/Sites");
+ public void testCreateFolder() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FOLDER);
+ assertFalse(object.exists());
+ object.createFolder();
+ assertTrue(object.exists());
assertEquals(FileType.FOLDER, object.getType());
}
- public void testGetDirectoryListing() throws FileSystemException {
- FileObject object = VFS.getManager().resolveFile(ROOT + "/Sites/Sites/images");
+ public void testGetFolder() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FOLDER);
+ assertTrue(object.exists());
+ assertEquals(FileType.FOLDER, object.getType());
+ }
+
+ public void testCreateFile() throws IOException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FILE);
+ assertFalse(object.exists());
+ OutputStream os = object.getContent().getOutputStream();
+ os.write(0xfc);
+ os.close();
+ assertTrue(object.exists());
+ assertEquals(FileType.FILE, object.getType());
+ }
+
+ public void testCreateEmptyFile() throws IOException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FILE + ".empty");
+ assertFalse(object.exists());
+ object.createFile();
+ assertTrue(object.exists());
+ assertEquals(FileType.FILE, object.getType());
+ }
+
+ public void testFileHasLastModifiedTimestamp() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FILE);
+ object.getContent().getLastModifiedTime();
+ }
+
+ public void testGetFolderListing() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FOLDER);
FileObject[] files = object.findFiles(new DepthFileSelector(1));
- for (FileObject file : files) {
- System.out.println("Found file: " + file.getName().getPath());
- }
- assertEquals(4, files.length);
+ assertEquals(3, files.length);
}
public void testMissingFile() throws FileSystemException {
assertFalse(object.exists());
}
+ public void testGetLastModifiedTimeFolder() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FOLDER);
+ object.getContent().getLastModifiedTime();
+ }
+
+ public void testGetLastModifiedTimeFile() throws FileSystemException {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FILE);
+ object.getContent().getLastModifiedTime();
+ }
+
public void testDeleteFile() throws FileSystemException {
- FileObject object = VFS.getManager().resolveFile(ROOT + "/newfile.txt");
+ FileObject object = VFS.getManager().resolveFile(ROOT + FILE);
object.delete();
+ assertFalse(object.exists());
}
public void testDeleteFolder() throws FileSystemException {
- FileObject object = VFS.getManager().resolveFile(ROOT + "/newfolder");
- object.delete(new FileSelector() {
+ FileObject object = VFS.getManager().resolveFile(ROOT + FOLDER);
+ object.delete(ALL_FILE_SELECTOR);
+ assertFalse(object.exists());
+ }
- public boolean includeFile(FileSelectInfo fileInfo) throws Exception {
- return true;
- }
+ public void testCopyFolder() throws FileSystemException {
+ FileObject origFolder = VFS.getManager().resolveFile(ROOT + FOLDER);
+ origFolder.createFolder();
- public boolean traverseDescendents(FileSelectInfo fileInfo) throws Exception {
- return true;
- }
- });
- }
+ origFolder.resolveFile("file.0").createFile();
+ origFolder.resolveFile("file.1").createFile();
+ origFolder.resolveFile("file.2").createFile();
- public void testCreateFolder() throws FileSystemException {
- FileObject object = VFS.getManager().resolveFile(ROOT + "/newfolder");
- object.createFolder();
+ FileObject[] origFiles = origFolder.findFiles(new DepthFileSelector(1));
+ assertEquals(4, origFiles.length);
+
+ FileObject destFolder = VFS.getManager().resolveFile(ROOT + FOLDER + "_dest");
+ assertFalse(destFolder.exists());
+ destFolder.copyFrom(origFolder, new DepthFileSelector(1));
+ assertTrue(destFolder.exists());
+
+ FileObject[] destFiles = destFolder.findFiles(new DepthFileSelector(1));
+ System.err.println(Arrays.asList(destFiles));
+ assertEquals(4, destFiles.length);
+
+ for (int i = 0; i < origFiles.length; i++) {
+ assertEquals(origFiles[i].getName().getRelativeName(origFolder.getName()),
+ destFiles[i].getName().getRelativeName(destFolder.getName()));
+ }
+
+ origFolder.delete(ALL_FILE_SELECTOR);
+ destFolder.delete(ALL_FILE_SELECTOR);
+
+ assertFalse(origFolder.exists());
+ assertFalse(destFolder.exists());
}
- public void testCreateFile() throws IOException {
- FileObject object = VFS.getManager().resolveFile(ROOT + "/newfile.txt");
- object.getContent().getOutputStream().write(0xfc);
- object.close();
+ public void testMoveFolder() throws FileSystemException {
+
}
public void testCloseFileSystem() throws FileSystemException {
FileSystem fs = VFS.getManager().resolveFile(ROOT).getFileSystem();
VFS.getManager().closeFileSystem(fs);
}
+
}
blob - /dev/null
blob + 790d3007daff25069746237120ced9b14239a05a (mode 644)
--- /dev/null
+++ src/test/java/com/thinkberg/moxo/vfs/S3TestCase.java
+/*
+ * Copyright 2007 Matthias L. Jugel.
+ *
+ * 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 com.thinkberg.moxo.vfs;
+
+import junit.framework.TestCase;
+import org.jets3t.service.Jets3tProperties;
+
+/**
+ * @author Matthias L. Jugel
+ */
+public class S3TestCase extends TestCase {
+ protected static final String ROOT;
+
+ static {
+ String propertiesFileName = System.getProperty("moxo.properties", "moxo.properties");
+ Jets3tProperties properties = Jets3tProperties.getInstance(propertiesFileName);
+ ROOT = properties.getStringProperty("vfs.url", "ram:/");
+ }
+}