Merge with 2ad3c504ee5d73982c0ef23336276dc1fc9e165f
authorkoutsoub <devnull@localhost>
Mon, 28 Feb 2011 13:02:57 +0000 (15:02 +0200)
committerkoutsoub <devnull@localhost>
Mon, 28 Feb 2011 13:02:57 +0000 (15:02 +0200)
57 files changed:
.classpath
build.xml
database/recursive_query_examples.sql [new file with mode: 0644]
ear/lib/commons-io-1.1.jar [new file with mode: 0644]
ear/lib/jdom-1.1.jar [new file with mode: 0644]
ear/lib/milton-api-1.5.7-SNAPSHOT.jar [new file with mode: 0644]
ear/lib/mime-util-2.1.3.jar [new file with mode: 0644]
jboss-config/5.1.0/conf/jboss-log4j.xml
jboss-config/5.1.0/conf/login-config.xml
src/gr/ebs/gss/client/FileContextMenu.java
src/gr/ebs/gss/client/tree/FolderSubtree.java [new file with mode: 0644]
src/gr/ebs/gss/client/tree/MyShareSubtree.java [new file with mode: 0644]
src/gr/ebs/gss/client/tree/OthersSharesSubtree.java [new file with mode: 0644]
src/gr/ebs/gss/client/tree/Subtree.java [new file with mode: 0644]
src/gr/ebs/gss/client/tree/TrashSubtree.java [new file with mode: 0644]
src/gr/ebs/gss/server/Registration.java
src/gr/ebs/gss/server/domain/FileBody.java
src/gr/ebs/gss/server/domain/FileHeader.java
src/gr/ebs/gss/server/domain/FileLock.java [new file with mode: 0644]
src/gr/ebs/gss/server/domain/UserClass.java
src/gr/ebs/gss/server/domain/WebDavNonce.java [new file with mode: 0644]
src/gr/ebs/gss/server/ejb/AdminAPIBean.java
src/gr/ebs/gss/server/ejb/ExternalAPI.java
src/gr/ebs/gss/server/ejb/ExternalAPIBean.java
src/gr/ebs/gss/server/ejb/ExternalAPIRemote.java
src/gr/ebs/gss/server/ejb/GSSDAO.java
src/gr/ebs/gss/server/ejb/GSSDAOBean.java
src/gr/ebs/gss/server/rest/FilesHandler.java
src/gr/ebs/gss/server/rest/GroupsHandler.java
src/gr/ebs/gss/server/rest/OthersHandler.java
src/gr/ebs/gss/server/rest/RequestHandler.java
src/gr/ebs/gss/server/rest/SharedHandler.java
src/gr/ebs/gss/server/rest/TrashHandler.java
src/gr/ebs/gss/server/rest/UserSearchHandler.java
src/gr/ebs/gss/server/webdav/Webdav.java
src/gr/ebs/gss/server/webdav/login/GssWebDAVLoginModule.java [deleted file]
src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssFileResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssLockManager.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssMemoryLockManager.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssNonceProvider.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssOtherUserResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssOthersResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssPathResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java [new file with mode: 0644]
test/gr/ebs/gss/server/ejb/ExternalAPITest.java
test/gr/ebs/gss/server/ejb/ScenarioTest.java
webdav/WEB-INF/jboss-web.xml [deleted file]
webdav/WEB-INF/lib/commons-fileupload-1.2.1.jar [new file with mode: 0644]
webdav/WEB-INF/lib/milton-console-1.5.7-SNAPSHOT.jar [new file with mode: 0644]
webdav/WEB-INF/lib/milton-servlet-1.5.7-SNAPSHOT.jar [new file with mode: 0644]
webdav/WEB-INF/web.xml

index 0ea8fc3..15aab67 100644 (file)
@@ -26,7 +26,7 @@
                        <attribute name="javadoc_location" value="http://commons.apache.org/codec/api-release/"/>
                </attributes>
        </classpathentry>
-       <classpathentry kind="lib" path="dependencies/gwt-2.1.1/gwt-user.jar" sourcepath="/home/kman/.m2/repository/com/google/gwt/gwt-user/2.1.0/gwt-user-2.1.0-sources.jar"/>
+       <classpathentry kind="lib" path="dependencies/gwt-2.1.1/gwt-user.jar" />
        <classpathentry kind="lib" path="dependencies/junit4.8.1/junit-4.8.1.jar"/>
        <classpathentry kind="lib" path="dependencies/jboss-5.1.0.GA/lib/concurrent.jar"/>
        <classpathentry kind="lib" path="dependencies/jboss-5.1.0.GA/lib/dom4j.jar"/>
        <classpathentry kind="lib" path="dependencies/jboss-5.1.0.GA/common/lib/slf4j-jboss-logging.jar"/>
        <classpathentry kind="lib" path="dependencies/jboss-5.1.0.GA/common/lib/xnio-api.jar"/>
        <classpathentry kind="lib" path="dependencies/gwt-dnd-3.0.1.jar"/>
+       <classpathentry kind="lib" path="dependencies/gwt-incubator-20101117-r1766.jar"/>
        <classpathentry kind="lib" path="dependencies/gwt-gears-1.3.0/gwt-gears.jar"/>
        <classpathentry kind="lib" path="dependencies/gwt-visualization-1.1.0/gwt-visualization.jar"/>
        <classpathentry kind="lib" path="dependencies/apache-solr-1.4.1/dist/apache-solr-solrj-1.4.1.jar"/>
        <classpathentry kind="lib" path="lib/droppable-plugin-1.0.2.jar"/>
        <classpathentry kind="lib" path="lib/gwtquery-1.0.0-20110116.074055-7.jar"/>
        <classpathentry kind="lib" path="dependencies/selenium-server-standalone-2.0b1.jar"/>
-       <classpathentry kind="lib" path="dependencies/gwt-incubator-20101117-r1766.jar"/>
+       <classpathentry kind="lib" path="webdav/WEB-INF/lib/commons-fileupload-1.2.1.jar"/>
+       <classpathentry kind="lib" path="ear/lib/commons-io-1.1.jar"/>
+       <classpathentry kind="lib" path="ear/lib/jdom-1.1.jar"/>
+       <classpathentry kind="lib" path="ear/lib/milton-api-1.5.7-SNAPSHOT.jar"/>
+       <classpathentry kind="lib" path="webdav/WEB-INF/lib/milton-console-1.5.7-SNAPSHOT.jar"/>
+       <classpathentry kind="lib" path="webdav/WEB-INF/lib/milton-servlet-1.5.7-SNAPSHOT.jar"/>
+       <classpathentry kind="lib" path="ear/lib/mime-util-2.1.3.jar"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index ca26a77..e0734b4 100644 (file)
--- a/build.xml
+++ b/build.xml
                <pathelement location="${jboss.common.lib.dir}/jbosssx.jar"/>
                <pathelement location="${jboss.common.lib.dir}/hibernate-core.jar"/>
         <pathelement location="${jboss.common.lib.dir}/hibernate-annotations.jar"/>
+        <pathelement location="${jboss.common.lib.dir}/jboss-remoting.jar"/>
+        <pathelement location="${jboss.common.lib.dir}/slf4j-api.jar"/>
                <pathelement location="${jboss.lib.dir}/jboss-j2se.jar"/>
                <pathelement location="${jboss.lib.dir}/jboss-kernel.jar"/>
                <pathelement location="${jboss.lib.dir}/jboss-system-jmx.jar"/>
         <pathelement location="${ear.lib.dir}/commons-httpclient-3.1.jar"/>
                <pathelement location="${ear.lib.dir}/commons-lang.jar"/>
                <pathelement location="${ear.lib.dir}/ldap.jar"/>
+               <pathelement location="${ear.lib.dir}/milton-api-1.5.7-SNAPSHOT.jar"/>
+        <pathelement location="${ear.lib.dir}/commons-io-1.1.jar"/>
                <pathelement location="${junit.path}/junit.jar"/>
                <pathelement location="${deps.dir}/${gwt-dnd.filename}"/>
                <pathelement location="${gwt-gears.path}/gwt-gears.jar"/>
         <pathelement location="${solr.lib}/lucene-core-2.9.3.jar"/>
         <pathelement location="${solr.lib}/lucene-analyzers-2.9.3.jar"/>
                <pathelement location="${deps.dir}/${selenium-server.filename}"/>               
+               <pathelement location="${webdav.war.lib.dir}/milton-servlet-1.5.7-SNAPSHOT.jar"/>
+        <pathelement location="${webdav.war.lib.dir}/milton-console-1.5.7-SNAPSHOT.jar"/>
        </path>
 
        <target name="check-jboss">
diff --git a/database/recursive_query_examples.sql b/database/recursive_query_examples.sql
new file mode 100644 (file)
index 0000000..f7b925d
--- /dev/null
@@ -0,0 +1,19 @@
+// This returns all subfolders (of any depth) of folder with id 3
+with recursive subfolders(id) AS (
+    select id from folder where parent_id=3
+    UNION ALL
+    select f.id from
+    folder f, subfolders s
+    where f.parent_id=s.id
+)
+select id from subfolders;
+
+// This returns the line of ancestors of folder with id 1140
+with recursive parent(id, parent_id) AS (
+    select id, parent_id from folder where id=1140
+    UNION ALL
+    select f.id, f.parent_id from
+    folder f, parent p
+    where p.parent_id=f.id
+)
+select id from parent;
\ No newline at end of file
diff --git a/ear/lib/commons-io-1.1.jar b/ear/lib/commons-io-1.1.jar
new file mode 100644 (file)
index 0000000..624fc1a
Binary files /dev/null and b/ear/lib/commons-io-1.1.jar differ
diff --git a/ear/lib/jdom-1.1.jar b/ear/lib/jdom-1.1.jar
new file mode 100644 (file)
index 0000000..97c85f5
Binary files /dev/null and b/ear/lib/jdom-1.1.jar differ
diff --git a/ear/lib/milton-api-1.5.7-SNAPSHOT.jar b/ear/lib/milton-api-1.5.7-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..e918865
Binary files /dev/null and b/ear/lib/milton-api-1.5.7-SNAPSHOT.jar differ
diff --git a/ear/lib/mime-util-2.1.3.jar b/ear/lib/mime-util-2.1.3.jar
new file mode 100644 (file)
index 0000000..63f7776
Binary files /dev/null and b/ear/lib/mime-util-2.1.3.jar differ
index e54c285..dbc0ec2 100644 (file)
     <priority value="TRACE"/>
    </category>
    -->
+    <category name="com.bradmcevoy">
+       <priority value="WARN"/>
+    </category>
+
+    <category name="com.ettrema">
+       <priority value="WARN"/>
+    </category>
 
    <!--
       | An example of enabling the custom TRACE level priority that is used
index de97f55..804e1a6 100644 (file)
@@ -142,20 +142,5 @@ $Revision: 87078 $
         flag="required"/>
        </authentication>
     </application-policy>
-       
-       <application-policy name="gssWebDAVSecurity">
-       <authentication>
-          <login-module code="gr.ebs.gss.server.webdav.login.GssWebDAVLoginModule"
-             flag="required">
-             <module-option name="unauthenticatedIdentity">guest</module-option>
-             <module-option name="hashAlgorithm">MD5</module-option>
-           <module-option name="hashEncoding">rfc2617</module-option>
-           <module-option name="hashUserPassword">false</module-option>
-           <module-option name="hashStorePassword">true</module-option>
-           <module-option name="passwordIsA1Hash">false</module-option>
-           <module-option name="storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
 </policy>
 
index 6fe9334..81148a8 100644 (file)
@@ -221,7 +221,7 @@ public class FileContextMenu extends PopupPanel implements ClickHandler {
                        contextMenu.addItem(deleteItem);
                        
                        MenuItem refresh = new MenuItem("<span id='fileContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + "&nbsp;Refresh</span>", true, new RefreshCommand(this, images));
-//                     refresh.getElement().setId("fileContextMenu.refresh");
+                       refresh.getElement().setId("fileContextMenu.refresh");
                        contextMenu.addItem(refresh);
                        
                        contextMenu.addItem(sharingItem);
diff --git a/src/gr/ebs/gss/client/tree/FolderSubtree.java b/src/gr/ebs/gss/client/tree/FolderSubtree.java
new file mode 100644 (file)
index 0000000..d095cc7
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.client.tree;
+
+import gr.ebs.gss.client.GSS;
+import gr.ebs.gss.client.PopupTree;
+import gr.ebs.gss.client.Folders.Images;
+import gr.ebs.gss.client.dnd.DnDTreeItem;
+import gr.ebs.gss.client.rest.GetCommand;
+import gr.ebs.gss.client.rest.MultipleGetCommand;
+import gr.ebs.gss.client.rest.resource.FolderResource;
+import gr.ebs.gss.client.rest.resource.UserResource;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * @author kman
+ */
+public class FolderSubtree extends Subtree {
+
+       /**
+        * A constant that denotes the completion of an IncrementalCommand.
+        */
+       public static final boolean DONE = false;
+
+       private DnDTreeItem rootItem;
+
+       public FolderSubtree(PopupTree aTree, final Images _images) {
+               super(aTree, _images);
+               aTree.clear();
+               DeferredCommand.addCommand(new IncrementalCommand() {
+
+                       @Override
+                       public boolean execute() {
+                               return fetchRootFolder();
+                       }
+               });
+       }
+
+       public boolean fetchRootFolder() {
+               UserResource userResource = GSS.get().getCurrentUserResource();
+               if (userResource == null)
+                       return !DONE;
+
+               final String path = userResource.getFilesPath();
+               GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
+
+                       @Override
+                       public void onComplete() {
+                               FolderResource rootResource = getResult();
+                               Widget rootItemWidget = imageItemHTML(images.home(), rootResource.getName());
+                               rootItemWidget.getElement().setId("tree.homeFolder");
+                               rootItem = new DnDTreeItem(rootItemWidget, false,tree,true);
+                               rootItem.setUserObject(rootResource);
+                               tree.clear();
+                               tree.addItem(rootItem);
+                               rootItem.doDroppable();
+                               GSS.get().getFolders().select(rootItem);
+                               updateSubFoldersLazily(rootItem, rootResource.getFolders(), images.folderYellow(), images.sharedFolder());
+                               rootItem.setState(true);
+                       }
+
+                       @Override
+                       public void onError(Throwable t) {
+                               GWT.log("Error fetching root folder", t);
+                               GSS.get().displayError("Unable to fetch root folder");
+                               if(rootItem != null){
+                                       rootItem = new DnDTreeItem(imageItemHTML(images.home(), "ERROR"), false,tree);
+                                       tree.clear();
+                                       tree.addItem(rootItem);
+                               }
+                       }
+
+               };
+               DeferredCommand.addCommand(gf);
+               return DONE;
+       }
+
+       public void updateSubfolders(final DnDTreeItem folderItem) {
+               if (folderItem.getFolderResource() == null) {
+                       GWT.log("folder resource is null", null);
+                       return;
+               }
+               updateNodes(folderItem);
+       }
+
+       private void updateNodes(final DnDTreeItem folderItem) {
+               String parentName = "";
+               if (folderItem.getParentItem() != null)
+                       parentName = ((DnDTreeItem) folderItem.getParentItem()).getFolderResource().getName() + "->";
+               parentName = parentName + folderItem.getFolderResource().getName();
+               MultipleGetCommand<FolderResource> gf = new MultipleGetCommand<FolderResource>(FolderResource.class,
+                                       folderItem.getFolderResource().getSubfolderPaths().toArray(new String[] {}), folderItem.getFolderResource().getCache()) {
+
+                       @Override
+                       public void onComplete() {
+                               List<FolderResource> res = getResult();
+                               folderItem.getFolderResource().setFolders(res);
+                               updateSubFoldersLazily(folderItem, res, images.folderYellow(), images.sharedFolder());
+                               for (int i = 0; i < folderItem.getChildCount(); i++) {
+                                       DnDTreeItem anItem = (DnDTreeItem) folderItem.getChild(i);
+                                       updateSubFoldersLazily(anItem, anItem.getFolderResource().getFolders(), images.folderYellow(), images.sharedFolder());
+                                       anItem.setState(false);
+                               }
+                       }
+
+                       @Override
+                       public void onError(Throwable t) {
+                               GSS.get().displayError("Unable to fetch subfolders");
+                               GWT.log("Unable to fetch subfolders", t);
+                       }
+
+                       @Override
+                       public void onError(String p, Throwable throwable) {
+                               GWT.log("Path:"+p, throwable);
+                       }
+
+               };
+               DeferredCommand.addCommand(gf);
+       }
+
+       public void updateFolderAndSubfolders(final DnDTreeItem folderItem) {
+               final String path = folderItem.getFolderResource().getUri();
+               GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, folderItem.getFolderResource()) {
+
+                       @Override
+                       public void onComplete() {
+                               FolderResource rootResource = getResult();
+                               if (!folderItem.equals(rootItem)) {
+                                       folderItem.undoDraggable();
+                                       if(rootResource.isShared()||rootResource.isReadForAll())
+                                               folderItem.updateWidget(imageItemHTML(images.sharedFolder(), rootResource.getName()));
+                                       else
+                                               folderItem.updateWidget(imageItemHTML(images.folderYellow(), rootResource.getName()));
+                                       folderItem.setUserObject(rootResource);
+                                       folderItem.doDraggable();
+                               } else{
+                                       folderItem.undoDroppable();
+                                       folderItem.setUserObject(rootResource);
+                                       folderItem.updateWidget(imageItemHTML(images.home(), rootResource.getName()));
+                                       folderItem.doDroppable();
+                               }
+                               updateSubfolders(folderItem);
+                       }
+
+                       @Override
+                       public void onError(Throwable t) {
+                               GWT.log("Error fetching folder", t);
+                               GSS.get().displayError("Unable to fetch folder:" + folderItem.getFolderResource().getName());
+                       }
+               };
+               DeferredCommand.addCommand(gf);
+       }
+
+       /**
+        * Retrieve the rootItem.
+        *
+        * @return the rootItem
+        */
+       public TreeItem getRootItem() {
+               return rootItem;
+       }
+
+}
diff --git a/src/gr/ebs/gss/client/tree/MyShareSubtree.java b/src/gr/ebs/gss/client/tree/MyShareSubtree.java
new file mode 100644 (file)
index 0000000..19e9c81
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.client.tree;
+
+import gr.ebs.gss.client.GSS;
+import gr.ebs.gss.client.PopupTree;
+import gr.ebs.gss.client.Folders.Images;
+import gr.ebs.gss.client.dnd.DnDTreeItem;
+import gr.ebs.gss.client.rest.GetCommand;
+import gr.ebs.gss.client.rest.MultipleGetCommand;
+import gr.ebs.gss.client.rest.resource.FolderResource;
+import gr.ebs.gss.client.rest.resource.SharedResource;
+import gr.ebs.gss.client.rest.resource.UserResource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.Widget;
+/**
+ * @author kman
+ */
+public class MyShareSubtree extends Subtree {
+
+       /**
+        * A constant that denotes the completion of an IncrementalCommand.
+        */
+       public static final boolean DONE = false;
+
+       private DnDTreeItem rootItem;
+
+       public MyShareSubtree(PopupTree aTree, final Images _images) {
+               super(aTree, _images);
+
+               DeferredCommand.addCommand(new IncrementalCommand() {
+
+                       @Override
+                       public boolean execute() {
+                               return updateInit();
+                       }
+               });
+       }
+
+       public boolean updateInit() {
+               UserResource userResource = GSS.get().getCurrentUserResource();
+               if (userResource == null || GSS.get().getFolders().getRootItem() == null || GSS.get().getFolders().getTrashItem() == null)
+                       return !DONE;
+
+               GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
+
+                       @Override
+                       public void onComplete() {
+                               Widget rootItemWidget = imageItemHTML(images.myShared(), "My Shared");
+                               rootItemWidget.getElement().setId("tree.myShared");
+                               rootItem = new DnDTreeItem(rootItemWidget, false,tree,true);
+                               rootItem.setUserObject(getResult());
+                               tree.addItem(rootItem);
+                               //rootItem.removeItems();
+                               rootItem.doDroppable();
+                               //update(rootItem);
+                       }
+
+                       @Override
+                       public void onError(Throwable t) {
+                               GWT.log("Error fetching Shared Root folder", t);
+                               GSS.get().displayError("Unable to fetch Shared Root folder");
+                               if(rootItem != null){
+                                       rootItem = new DnDTreeItem(imageItemHTML(images.myShared(), "ERROR"), false,tree);
+                                       tree.addItem(rootItem);
+                               }
+                       }
+               };
+               DeferredCommand.addCommand(gs);
+               return DONE;
+       }
+
+       public void update(final DnDTreeItem folderItem) {
+               if (folderItem.getFolderResource() != null) {
+                       folderItem.removeItems();
+                       List<String> newPaths = new ArrayList<String>();
+                       for (String s : folderItem.getFolderResource().getSubfolderPaths()) {
+                               if (!s.endsWith("/"))
+                                       s = s + "/";
+                               newPaths.add(s);
+                       }
+                       String parentName = "";
+                       if(folderItem.getParentItem() != null && ((DnDTreeItem)folderItem.getParentItem()).getFolderResource() != null)
+                               parentName = ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().getName()+"->";
+                       parentName = parentName+folderItem.getFolderResource().getName();
+                       folderItem.getFolderResource().setSubfolderPaths(newPaths);
+                       MultipleGetCommand<FolderResource> gf = new MultipleGetCommand<FolderResource>(FolderResource.class, newPaths.toArray(new String[] {}), folderItem.getFolderResource().getCache()) {
+
+                               @Override
+                               public void onComplete() {
+                                       List<FolderResource> res = getResult();
+                                       for (FolderResource r : res)
+                                               if(r.isShared() || r.isReadForAll()){
+                                                       DnDTreeItem child = (DnDTreeItem) addImageItem(folderItem, r.getName(), images.folderYellow(), true);
+                                                       child.setUserObject(r);
+                                                       child.setState(false);
+                                                       child.doDraggable();
+                                                       if(folderItem.getState())
+                                                               update(child);
+                                               }
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GSS.get().displayError("Unable to fetch subfolders");
+                                       GWT.log("Unable to fetch subfolders", t);
+                               }
+
+                               @Override
+                               public void onError(String p, Throwable throwable) {
+                                       GWT.log("Path:"+p, throwable);
+                               }
+                       };
+                       DeferredCommand.addCommand(gf);
+               }
+               if (folderItem.getSharedResource() != null) {
+                       folderItem.removeItems();
+                       List<String> paths = folderItem.getSharedResource().getSubfolderPaths();
+                       List<String> newPaths = new ArrayList<String>();
+                       for (String r : paths)
+                               if (isRoot(r, paths))
+                                       newPaths.add(r);
+                       MultipleGetCommand<FolderResource> gf = new MultipleGetCommand<FolderResource>(FolderResource.class, newPaths.toArray(new String[] {}), null) {
+
+                               @Override
+                               public void onComplete() {
+                                       List<FolderResource> res = getResult();
+                                       for (FolderResource r : res) {
+                                               DnDTreeItem child = (DnDTreeItem) addImageItem(folderItem, r.getName(), images.folderYellow(), true);
+                                               child.setUserObject(r);
+                                               child.setState(false);
+                                               child.doDraggable();
+                                               update(child);
+                                       }
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GSS.get().displayError("Unable to fetch subfolders");
+                                       GWT.log("Unable to fetch subfolders", t);
+                               }
+
+                               @Override
+                               public void onError(String p, Throwable throwable) {
+                                       GWT.log("Path:"+p, throwable);
+                               }
+                       };
+                       DeferredCommand.addCommand(gf);
+               }
+       }
+
+       private boolean isRoot(String f, List<String> folders) {
+               for (String t : folders)
+                       if (!f.equals(t) && f.startsWith(t))
+                               return false;
+               return true;
+       }
+
+       public void updateFolderAndSubfolders(final DnDTreeItem folderItem) {
+               if (folderItem.getFolderResource() != null) {
+                       final String path = folderItem.getFolderResource().getUri();
+                       GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
+
+                               @Override
+                               public void onComplete() {
+                                       rootItem.setUserObject(getResult());
+                                       GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, folderItem.getFolderResource()) {
+
+                                               @Override
+                                               public void onComplete() {
+                                                       FolderResource rootResource = getResult();
+                                                       if(rootResource.isShared()){
+                                                               folderItem.undoDraggable();
+                                                               folderItem.updateWidget(imageItemHTML(images.folderYellow(), rootResource.getName()));
+                                                               folderItem.setUserObject(rootResource);
+                                                               folderItem.doDraggable();
+                                                               update(folderItem);
+                                                       } else
+                                                               folderItem.getParentItem().removeItem(folderItem);
+                                               }
+
+                                               @Override
+                                               public void onError(Throwable t) {
+                                                       GWT.log("Error fetching folder", t);
+                                                       GSS.get().displayError("Unable to fetch folder:" + folderItem.getFolderResource().getName());
+                                               }
+                                       };
+                                       DeferredCommand.addCommand(gf);
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GWT.log("Error fetching Shared Root folder", t);
+                                       GSS.get().displayError("Unable to fetch Shared Root folder");
+                               }
+                       };
+                       DeferredCommand.addCommand(gs);
+               }
+               else if( folderItem.getSharedResource() != null){
+                       GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
+
+                               @Override
+                               public void onComplete() {
+                                       rootItem.setUserObject(getResult());
+                                       if(rootItem.getState()){
+                                               rootItem.removeItems();
+                                               update(rootItem);
+                                       }
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GWT.log("Error fetching Shared Root folder", t);
+                                       GSS.get().displayError("Unable to fetch Shared Root folder");
+                               }
+                       };
+                       DeferredCommand.addCommand(gs);
+               }
+       }
+
+       /**
+        * Retrieve the rootItem.
+        *
+        * @return the rootItem
+        */
+       public TreeItem getRootItem() {
+               return rootItem;
+       }
+
+       public void updateNode(TreeItem node, FolderResource folder) {
+               node.getWidget().removeStyleName("gss-SelectedRow");
+               if (node instanceof DnDTreeItem) {
+                       ((DnDTreeItem) node).undoDraggable();
+                       ((DnDTreeItem) node).updateWidget(imageItemHTML(images.folderYellow(), folder.getName()));
+                       ((DnDTreeItem) node).doDraggable();
+               } else
+                       node.setWidget(imageItemHTML(images.folderYellow(), folder.getName()));
+               node.setUserObject(folder);
+       }
+}
diff --git a/src/gr/ebs/gss/client/tree/OthersSharesSubtree.java b/src/gr/ebs/gss/client/tree/OthersSharesSubtree.java
new file mode 100644 (file)
index 0000000..81b908a
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package gr.ebs.gss.client.tree;
+
+import gr.ebs.gss.client.GSS;
+import gr.ebs.gss.client.PopupTree;
+import gr.ebs.gss.client.Folders.Images;
+import gr.ebs.gss.client.dnd.DnDTreeItem;
+import gr.ebs.gss.client.rest.GetCommand;
+import gr.ebs.gss.client.rest.MultipleGetCommand;
+import gr.ebs.gss.client.rest.resource.FolderResource;
+import gr.ebs.gss.client.rest.resource.OtherUserResource;
+import gr.ebs.gss.client.rest.resource.OthersResource;
+import gr.ebs.gss.client.rest.resource.UserResource;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * @author kman
+ */
+public class OthersSharesSubtree extends Subtree {
+
+       /**
+        * A constant that denotes the completion of an IncrementalCommand.
+        */
+       public static final boolean DONE = false;
+
+       private DnDTreeItem rootItem;
+
+       public OthersSharesSubtree(PopupTree aTree, final Images _images) {
+               super(aTree, _images);
+               DeferredCommand.addCommand(new IncrementalCommand() {
+
+                       @Override
+                       public boolean execute() {
+                               return updateInit();
+                       }
+               });
+       }
+
+       public boolean updateInit() {
+               UserResource userResource = GSS.get().getCurrentUserResource();
+               if (userResource == null ||
+                                       GSS.get().getFolders().getRootItem() == null ||
+                                       GSS.get().getFolders().getTrashItem() == null ||
+                                       GSS.get().getFolders().getMySharesItem() == null)
+                       return !DONE;
+
+               GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
+                                       userResource.getOthersPath(), null) {
+
+                       @Override
+                       public void onComplete() {
+                               Widget rootItemWidget = imageItemHTML(images.othersShared(), "Other's Shared");
+                               rootItemWidget.getElement().setId("tree.othersShared");
+                               rootItem = new DnDTreeItem(rootItemWidget, false,tree,true);
+                               rootItem.setUserObject(getResult());
+                               tree.addItem(rootItem);
+                               //rootItem.removeItems();
+                               //update(rootItem);
+                               GSS.get().removeGlassPanel();
+                       }
+
+                       @Override
+                       public void onError(Throwable t) {
+                               GWT.log("Error fetching Others Root folder", t);
+                               GSS.get().displayError("Unable to fetch Others Root folder");
+                               if(rootItem != null){
+                                       rootItem = new DnDTreeItem(imageItemHTML(images.othersShared(), "ERROR"), false,tree);
+                                       tree.addItem(rootItem);
+                               }
+                       }
+               };
+               DeferredCommand.addCommand(go);
+               return DONE;
+       }
+
+       public void update(final DnDTreeItem folderItem) {
+               if (folderItem.getOthersResource() != null) {
+                       UserResource userResource = GSS.get().getCurrentUserResource();
+                       GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
+                                               userResource.getOthersPath(), null) {
+
+                               @Override
+                               public void onComplete() {
+                                       final OthersResource others = getResult();
+                                       rootItem.setUserObject(others);
+                                       MultipleGetCommand<OtherUserResource> gogo = new MultipleGetCommand<OtherUserResource>(OtherUserResource.class,
+                                                               folderItem.getOthersResource().getOthers().toArray(new String[] {}), null) {
+
+                                               @Override
+                                               public void onComplete() {
+                                                       List<OtherUserResource> res = getResult();
+                                                       folderItem.removeItems();
+                                                       for (OtherUserResource r : res) {
+                                                               DnDTreeItem child = (DnDTreeItem) addImageItem(folderItem,
+                                                                                       r.getName(), images.folderYellow(), true);
+                                                               r.setUsername(others.getUsernameOfUri(r.getUri()));
+                                                               GWT.log("Setting username:"+r.getUsername(), null );
+                                                               child.setUserObject(r);
+                                                               child.setState(false);
+                                                       }
+                                               }
+
+                                               @Override
+                                               public void onError(Throwable t) {
+                                                       GWT.log("Error fetching Others Root folder", t);
+                                                       GSS.get().displayError("Unable to fetch Others Root folder");
+                                               }
+
+                                               @Override
+                                               public void onError(String p, Throwable throwable) {
+                                                       GWT.log("Path:"+p, throwable);
+                                               }
+                                       };
+                                       DeferredCommand.addCommand(gogo);
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GWT.log("Error fetching Others Root folder", t);
+                                       GSS.get().displayError("Unable to fetch Others Root folder");
+                               }
+
+                       };
+
+                       DeferredCommand.addCommand(go);
+               } else if (folderItem.getOtherUserResource() != null) {
+
+                       GetCommand<OtherUserResource> go = new GetCommand<OtherUserResource>(OtherUserResource.class,
+                                               folderItem.getOtherUserResource().getUri(), null) {
+
+                               @Override
+                               public void onComplete() {
+                                       OtherUserResource res = getResult();
+                                       folderItem.removeItems();
+                                       for (FolderResource r : res.getFolders()) {
+                                               DnDTreeItem child = (DnDTreeItem) addImageItem(folderItem,
+                                                                       r.getName(), images.folderYellow(), true);
+                                               child.setUserObject(r);
+                                               child.doDraggable();
+                                               updateFolderAndSubfolders(child);
+                                       }
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GWT.log("Error fetching Others Root folder", t);
+                                       GSS.get().displayError("Unable to fetch Others Root folder");
+                               }
+
+                       };
+                       DeferredCommand.addCommand(go);
+               } else if (folderItem.getFolderResource() != null) {
+                       GWT.log("UPDATING :"+folderItem.getFolderResource().getName(), null);
+                       MultipleGetCommand<FolderResource> go = new MultipleGetCommand<FolderResource>(FolderResource.class,
+                                               folderItem.getFolderResource().getSubfolderPaths().toArray(new String[] {}), folderItem.getFolderResource().getCache()) {
+
+                               @Override
+                               public void onComplete() {
+                                       List<FolderResource> res = getResult();
+                                       folderItem.removeItems();
+                                       GWT.log("UPDATING :"+folderItem.getFolderResource().getName()+" :"+res.size(), null);
+                                       for (FolderResource r : res) {
+                                               DnDTreeItem child = (DnDTreeItem) addImageItem(folderItem,
+                                                                       r.getName(), images.folderYellow(), true);
+                                               child.setUserObject(r);
+                                               child.doDraggable();
+                                       }
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GWT.log("Error fetching Others Root folder", t);
+                                       GSS.get().displayError("Unable to fetch Others Root folder");
+                               }
+
+                               @Override
+                               public void onError(String p, Throwable throwable) {
+                                       GWT.log("Path:"+p, throwable);
+                               }
+                       };
+                       DeferredCommand.addCommand(go);
+               }
+
+       }
+
+       public void updateFolderAndSubfolders(final DnDTreeItem folderItem) {
+               if (folderItem.getFolderResource() != null) {
+                       final String path = folderItem.getFolderResource().getUri();
+                       GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, folderItem.getFolderResource()) {
+
+                               @Override
+                               public void onComplete() {
+                                       FolderResource rootResource = getResult();
+                                       folderItem.undoDraggable();
+                                       folderItem.updateWidget(imageItemHTML(images.folderYellow(), rootResource.getName()));
+                                       folderItem.setUserObject(rootResource);
+                                       folderItem.doDraggable();
+                               }
+
+                               @Override
+                               public void onError(Throwable t) {
+                                       GWT.log("Error fetching folder", t);
+                                       GSS.get().displayError("Unable to fetch folder:" + folderItem.getFolderResource().getName());
+                               }
+                       };
+                       DeferredCommand.addCommand(gf);
+               }
+       }
+
+       /**
+        * Retrieve the rootItem.
+        *
+        * @return the rootItem
+        */
+       public TreeItem getRootItem() {
+               return rootItem;
+       }
+
+
+}
diff --git a/src/gr/ebs/gss/client/tree/Subtree.java b/src/gr/ebs/gss/client/tree/Subtree.java
new file mode 100644 (file)
index 0000000..d266da8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.client.tree;
+
+import gr.ebs.gss.client.PopupTree;
+import gr.ebs.gss.client.Folders.Images;
+import gr.ebs.gss.client.dnd.DnDTreeItem;
+import gr.ebs.gss.client.rest.resource.FolderResource;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.TreeItem;
+
+/**
+ * @author kman
+ */
+public abstract class Subtree {
+
+       protected PopupTree tree;
+
+       final Images images;
+
+       public Subtree(PopupTree aTree, final Images _images) {
+               images = _images;
+               tree = aTree;
+       }
+
+       /**
+        * A helper method to simplify adding tree items that have attached images.
+        * {@link #addImageItem(TreeItem, String) code}
+        *
+        * @param parent the tree item to which the new item will be added.
+        * @param title the text associated with this item.
+        * @param imageProto the image of the item
+        * @return
+        */
+       protected TreeItem addImageItem(final TreeItem parent, final String title, final ImageResource imageProto, boolean draggable) {
+               final DnDTreeItem item = new DnDTreeItem(imageItemHTML(imageProto, title), draggable,tree,true);
+               parent.addItem(item);
+               return item;
+       }
+
+       /**
+        * Generates HTML for a tree item with an attached icon.
+        *
+        * @param imageProto the image icon
+        * @param title the title of the item
+        * @return the resultant HTML
+        */
+       protected HTML imageItemHTML(final ImageResource imageProto, final String title) {
+               HTML html = new HTML("<a class='hidden-link' href='javascript:;'><span >" + AbstractImagePrototype.create(imageProto).getHTML() + "&nbsp;" + title + "</span></a>");
+               return html;
+       }
+
+       public void updateSubFoldersLazily(DnDTreeItem folderItem, List<FolderResource> subfolders, ImageResource image, ImageResource sharedImage) {
+               for (int i = 0; i < folderItem.getChildCount(); i++) {
+                       TreeItem initialItem = folderItem.getChild(i);
+                       if(initialItem instanceof DnDTreeItem){
+                               DnDTreeItem c = (DnDTreeItem)initialItem;
+                               FolderResource f = (FolderResource) c.getUserObject();
+                               if (!listContainsFolder(f, subfolders)) {
+                                       c.undoDraggable();
+                                       folderItem.removeItem(c);
+                               }
+                       }
+                       else
+                               folderItem.removeItem(initialItem);
+               }
+
+               LinkedList<DnDTreeItem> itemList = new LinkedList();
+               for (FolderResource subfolder : subfolders) {
+                       DnDTreeItem item = folderItem.getChild(subfolder);
+                       if (item == null){
+                               if(subfolder.isShared() || subfolder.isReadForAll())
+                                       item = (DnDTreeItem) addImageItem(folderItem, subfolder.getName(), sharedImage, true);
+                               else
+                                       item = (DnDTreeItem) addImageItem(folderItem, subfolder.getName(), image, true);
+                       } else if(subfolder.isShared() || subfolder.isReadForAll())
+                               item.updateWidget(imageItemHTML(sharedImage, subfolder.getName()));
+                       else
+                               item.updateWidget(imageItemHTML(image, subfolder.getName()));
+                       item.setUserObject(subfolder);                  
+                       itemList.add(item);
+               }
+               for (DnDTreeItem it : itemList)
+                       it.remove();
+               for (DnDTreeItem it : itemList)
+                       folderItem.addItem(it);
+               for (int i = 0; i < folderItem.getChildCount(); i++) {
+                       DnDTreeItem c = (DnDTreeItem) folderItem.getChild(i);
+                       c.doDraggable();
+               }
+       }
+
+       private boolean listContainsFolder(FolderResource folder, List<FolderResource> subfolders) {
+               for (FolderResource f : subfolders)
+                       if (f.getUri().equals(folder.getUri()))
+                               return true;
+               return false;
+       }
+
+}
diff --git a/src/gr/ebs/gss/client/tree/TrashSubtree.java b/src/gr/ebs/gss/client/tree/TrashSubtree.java
new file mode 100644 (file)
index 0000000..d775f84
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.client.tree;
+
+import gr.ebs.gss.client.Folders.Images;
+import gr.ebs.gss.client.GSS;
+import gr.ebs.gss.client.PopupTree;
+import gr.ebs.gss.client.dnd.DnDTreeItem;
+import gr.ebs.gss.client.rest.GetCommand;
+import gr.ebs.gss.client.rest.RestException;
+import gr.ebs.gss.client.rest.resource.FolderResource;
+import gr.ebs.gss.client.rest.resource.TrashResource;
+import gr.ebs.gss.client.rest.resource.UserResource;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * @author kman
+ */
+public class TrashSubtree extends Subtree {
+
+       /**
+        * A constant that denotes the completion of an IncrementalCommand.
+        */
+       public static final boolean DONE = false;
+
+       private DnDTreeItem rootItem;
+
+       public TrashSubtree(PopupTree aTree, final Images _images) {
+               super(aTree, _images);
+               DeferredCommand.addCommand(new IncrementalCommand() {
+
+                       @Override
+                       public boolean execute() {
+                               return updateInit();
+                       }
+               });
+       }
+
+       public boolean updateInit() {
+               UserResource userResource = GSS.get().getCurrentUserResource();
+               if ( userResource == null || GSS.get().getFolders().getRootItem() == null)
+                       return !DONE;
+               update();
+               return DONE;
+       }
+
+       public void update() {
+               DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
+                       @Override
+                       public void onComplete() {
+                               if(rootItem == null){
+                                       Widget rootItemWidget = imageItemHTML(images.trash(), "Trash");
+                                       rootItemWidget.getElement().setId("tree.trash");
+                                       rootItem = new DnDTreeItem(rootItemWidget, false,tree);
+                                       tree.addItem(rootItem);
+                                       rootItem.doDroppable();
+                               }
+                               rootItem.setUserObject(getResult());
+                               rootItem.removeItems();
+                               List<FolderResource> res = rootItem.getTrashResource().getTrashedFolders();
+                               for (FolderResource r : res) {
+                                       DnDTreeItem child = (DnDTreeItem) addImageItem(rootItem, r.getName(), images.folderYellow(), true);
+                                       child.setUserObject(r);
+                                       child.setState(false);
+                               }
+                       }
+
+                       @Override
+                       public void onError(Throwable t) {
+                               if(t instanceof RestException){
+                                       int statusCode = ((RestException)t).getHttpStatusCode();
+                                       // On IE status code 1223 may be returned instead of 204.
+                                       if(statusCode == 204 || statusCode == 1223){
+                                               GWT.log("Trash is empty", null);
+                                               if(rootItem == null){
+                                                       rootItem = new DnDTreeItem(imageItemHTML(images.trash(), "Trash"), false,tree);
+                                                       tree.addItem(rootItem);
+                                                       rootItem.doDroppable();
+                                               }
+                                               rootItem.setUserObject(new TrashResource(GSS.get().getCurrentUserResource().getTrashPath()));
+                                               rootItem.removeItems();
+                                       } else{
+                                               if(rootItem == null){
+                                                       rootItem = new DnDTreeItem(imageItemHTML(images.trash(), "Trash"), false,tree);
+                                                       tree.addItem(rootItem);
+                                               }
+                                               rootItem.setUserObject(new TrashResource(GSS.get().getCurrentUserResource().getTrashPath()));
+                                               GSS.get().displayError("Unable to fetch trash folder:"+((RestException)t).getHttpStatusText());
+                                       }
+                               }
+                               else{
+                                       GWT.log("", t);
+                                       GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
+                                       if(rootItem == null){
+                                               rootItem = new DnDTreeItem(imageItemHTML(images.trash(), "Trash"), false,tree);
+                                               tree.addItem(rootItem);
+                                               rootItem.doDroppable();
+                                       }
+                                       rootItem.setUserObject(new TrashResource(GSS.get().getCurrentUserResource().getTrashPath()));
+                               }
+                       }
+               });
+       }
+
+       /**
+        * Retrieve the rootItem.
+        *
+        * @return the rootItem
+        */
+       public TreeItem getRootItem() {
+               return rootItem;
+       }
+
+}
index e5e3cbe..75d58a2 100644 (file)
@@ -23,7 +23,6 @@ import gr.ebs.gss.client.exceptions.DuplicateNameException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.RpcException;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.UserDTO;
 import gr.ebs.gss.server.ejb.TransactionHelper;
 
 import java.io.IOException;
@@ -194,10 +193,10 @@ public class Registration extends BaseServlet {
                                handleException(response, e.getMessage());
                                return;
                        }
-                       final UserDTO userDto = new TransactionHelper<UserDTO>().tryExecute(new Callable<UserDTO>() {
+                       final User userDto = new TransactionHelper<User>().tryExecute(new Callable<User>() {
                                @Override
-                               public UserDTO call() throws Exception {
-                                       return getService().createUser(username, firstname + " " + lastname, email, "", "").getDTO();
+                               public User call() throws Exception {
+                                       return getService().createUser(username, firstname + " " + lastname, email, "", "");
                                }
 
                        });
index bbed3bd..3b69060 100644 (file)
@@ -100,6 +100,11 @@ public final class FileBody  implements Serializable{
         */\r
        private long fileSize;\r
 \r
+       \r
+       public Long getId() {\r
+               return id;\r
+       }\r
+\r
        /**\r
         * Returns the version\r
         *\r
@@ -136,6 +141,11 @@ public final class FileBody  implements Serializable{
                header = newHeader;\r
        }\r
 \r
+       \r
+       public AuditInfo getAuditInfo() {\r
+               return auditInfo;\r
+       }\r
+\r
        /**\r
         * Retrieve the MIME type.\r
         *\r
index bf537a6..d4e1b92 100644 (file)
@@ -329,6 +329,19 @@ public final class FileHeader  implements Serializable{
        }\r
 \r
        /**\r
+        * Retrieve the file tags as a list of strings.\r
+        *\r
+        * @return the list of file tag strings\r
+        */\r
+       public List<String> getFileTagsAsStrings() {\r
+               List<String> result = new ArrayList<String>();\r
+               for (FileTag ft : fileTags) {\r
+                       result.add(ft.getTag());\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       /**\r
         * Retrieve the file tags.\r
         *\r
         * @return the list of file tags\r
diff --git a/src/gr/ebs/gss/server/domain/FileLock.java b/src/gr/ebs/gss/server/domain/FileLock.java
new file mode 100644 (file)
index 0000000..3930986
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2011. Electronic Business Systems Ltd
+ */
+package gr.ebs.gss.server.domain;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Version;
+
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.IndexColumn;
+
+import com.bradmcevoy.http.LockInfo;
+import com.bradmcevoy.http.LockTimeout;
+import com.bradmcevoy.http.LockToken;
+import com.bradmcevoy.http.LockInfo.LockDepth;
+import com.bradmcevoy.http.LockInfo.LockScope;
+import com.bradmcevoy.http.LockInfo.LockType;
+
+
+/**
+ * @author kman
+ *
+ */
+@Entity
+public class FileLock {
+       @Id
+       String id;
+       public String lockedByUser;
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="from_date")
+       Date from;
+    String tokenId;
+    
+    public LockScope scope;
+    public LockType type;
+    public LockDepth depth;
+    
+    Long seconds;
+    @CollectionOfElements
+    @IndexColumn(name="secId")
+    Long[] otherSeconds;
+    @Version
+    private int version;
+    
+       /**
+        * 
+        */
+       public FileLock() {
+               // TODO Auto-generated constructor stub
+       }
+       
+       public FileLock(String id,LockToken token){
+               this.id=id;
+               this.tokenId=token.tokenId;
+               if(token.info!=null){
+                       this.depth=token.info.depth;
+                       this.scope=token.info.scope;
+                       this.type=token.info.type;
+                       this.lockedByUser=token.info.lockedByUser;
+               }
+               if(token.timeout!=null){
+                       this.seconds=token.timeout.getSeconds();
+                       this.otherSeconds=token.timeout.getOtherSeconds();
+               }
+               this.from=token.getFrom();
+               
+       }
+       
+    public LockToken toToken(){
+       LockToken res = new LockToken();
+       res.tokenId=tokenId;
+       LockInfo info = new LockInfo(scope,type,lockedByUser,depth);
+       LockTimeout timeout = new LockTimeout(seconds);
+       res.timeout=timeout;
+       res.info=info;
+       res.setFrom(from);
+       return res;
+    }
+
+       
+       /**
+        * Retrieve the id.
+        *
+        * @return the id
+        */
+       public String getId() {
+               return id;
+       }
+
+       
+       /**
+        * Modify the id.
+        *
+        * @param id the id to set
+        */
+       public void setId(String id) {
+               this.id = id;
+       }
+
+       
+       /**
+        * Retrieve the lockedByUser.
+        *
+        * @return the lockedByUser
+        */
+       public String getLockedByUser() {
+               return lockedByUser;
+       }
+
+       
+       /**
+        * Modify the lockedByUser.
+        *
+        * @param lockedByUser the lockedByUser to set
+        */
+       public void setLockedByUser(String lockedByUser) {
+               this.lockedByUser = lockedByUser;
+       }
+
+       
+       /**
+        * Retrieve the from.
+        *
+        * @return the from
+        */
+       public Date getFrom() {
+               return from;
+       }
+
+       
+       /**
+        * Modify the from.
+        *
+        * @param from the from to set
+        */
+       public void setFrom(Date from) {
+               this.from = from;
+       }
+
+       
+       /**
+        * Retrieve the tokenId.
+        *
+        * @return the tokenId
+        */
+       public String getTokenId() {
+               return tokenId;
+       }
+
+       
+       /**
+        * Modify the tokenId.
+        *
+        * @param tokenId the tokenId to set
+        */
+       public void setTokenId(String tokenId) {
+               this.tokenId = tokenId;
+       }
+
+       
+       /**
+        * Retrieve the scope.
+        *
+        * @return the scope
+        */
+       public LockScope getScope() {
+               return scope;
+       }
+
+       
+       /**
+        * Modify the scope.
+        *
+        * @param scope the scope to set
+        */
+       public void setScope(LockScope scope) {
+               this.scope = scope;
+       }
+
+       
+       /**
+        * Retrieve the type.
+        *
+        * @return the type
+        */
+       public LockType getType() {
+               return type;
+       }
+
+       
+       /**
+        * Modify the type.
+        *
+        * @param type the type to set
+        */
+       public void setType(LockType type) {
+               this.type = type;
+       }
+
+       
+       /**
+        * Retrieve the depth.
+        *
+        * @return the depth
+        */
+       public LockDepth getDepth() {
+               return depth;
+       }
+
+       
+       /**
+        * Modify the depth.
+        *
+        * @param depth the depth to set
+        */
+       public void setDepth(LockDepth depth) {
+               this.depth = depth;
+       }
+
+       
+       /**
+        * Retrieve the seconds.
+        *
+        * @return the seconds
+        */
+       public Long getSeconds() {
+               return seconds;
+       }
+
+       
+       /**
+        * Modify the seconds.
+        *
+        * @param seconds the seconds to set
+        */
+       public void setSeconds(Long seconds) {
+               this.seconds = seconds;
+       }
+
+       
+       /**
+        * Retrieve the otherSeconds.
+        *
+        * @return the otherSeconds
+        */
+       public Long[] getOtherSeconds() {
+               return otherSeconds;
+       }
+
+       
+       /**
+        * Modify the otherSeconds.
+        *
+        * @param otherSeconds the otherSeconds to set
+        */
+       public void setOtherSeconds(Long[] otherSeconds) {
+               this.otherSeconds = otherSeconds;
+       }
+    
+    
+    
+    
+}
index d1c410b..ff9608c 100644 (file)
@@ -103,21 +103,6 @@ public class UserClass  implements Serializable{
         *
         * @return a new DTO with the same contents as this object
         */
-       public UserClassDTO getDTO() {
-               UserClassDTO u = new UserClassDTO();
-               u.setId(id);
-               u.setName(name);
-               u.setQuota(quota);
-               for (final User user : users)
-                       u.getUsers().add(user.getDTO());
-               return u;
-       }
-
-       /**
-        * Return a new Data Transfer Object for this user class.
-        *
-        * @return a new DTO with the same contents as this object
-        */
        public UserClassDTO getDTOWithoutUsers() {
                UserClassDTO u = new UserClassDTO();
                u.setId(id);
diff --git a/src/gr/ebs/gss/server/domain/WebDavNonce.java b/src/gr/ebs/gss/server/domain/WebDavNonce.java
new file mode 100644 (file)
index 0000000..98f8f98
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011. Electronic Business Systems Ltd
+ */
+package gr.ebs.gss.server.domain;
+
+import java.util.Date;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+
+/**
+ * @author kman
+ *
+ */
+@Entity
+public class WebDavNonce {
+       @Id
+       String id;
+       @Temporal(TemporalType.TIMESTAMP)
+       Date issued;
+    long nonceCount=0;
+       
+       /**
+        * Retrieve the id.
+        *
+        * @return the id
+        */
+       public String getId() {
+               return id;
+       }
+       
+       /**
+        * Modify the id.
+        *
+        * @param id the id to set
+        */
+       public void setId(String id) {
+               this.id = id;
+       }
+       
+       /**
+        * Retrieve the issued.
+        *
+        * @return the issued
+        */
+       public Date getIssued() {
+               return issued;
+       }
+       
+       /**
+        * Modify the issued.
+        *
+        * @param issued the issued to set
+        */
+       public void setIssued(Date issued) {
+               this.issued = issued;
+       }
+       
+       /**
+        * Retrieve the nonceCount.
+        *
+        * @return the nonceCount
+        */
+       public long getNonceCount() {
+               return nonceCount;
+       }
+       
+       /**
+        * Modify the nonceCount.
+        *
+        * @param nonceCount the nonceCount to set
+        */
+       public void setNonceCount(long nonceCount) {
+               this.nonceCount = nonceCount;
+       }
+    
+    
+}
index 3ff9c8c..59a6f75 100644 (file)
@@ -106,7 +106,7 @@ public class AdminAPIBean implements AdminAPI {
                User owner = dao.getUser(username);
                // Store the last element, since it requires special handling.
                String lastElement = pathElements.remove(pathElements.size() - 1);
-               FolderDTO cursor = api.getRootFolder(owner.getId());
+               FolderDTO cursor = getRootFolder(owner.getId());
                // Traverse and verify the specified folder path.
                for (String pathElement : pathElements) {
                        cursor = getFolder(cursor.getId(), pathElement);
@@ -133,14 +133,14 @@ public class AdminAPIBean implements AdminAPI {
                        pathElements.add(st.nextToken());
                if (pathElements.size() < 1){
 
-                               FolderDTO folder = api.getRootFolder(owner.getId());
-                               res.addAll(api.getFiles(folder.getOwner().getId(), folder.getId(), false));
+                               FolderDTO folder = getRootFolder(owner.getId());
+                               res.addAll(getFiles(folder.getOwner().getId(), folder.getId(), false));
                                return res;
                }
 
                // Store the last element, since it requires special handling.
                String lastElement = pathElements.remove(pathElements.size() - 1);
-               FolderDTO cursor = api.getRootFolder(owner.getId());
+               FolderDTO cursor = getRootFolder(owner.getId());
                // Traverse and verify the specified folder path.
                for (String pathElement : pathElements) {
                        cursor = getFolder(cursor.getId(), pathElement);
@@ -154,7 +154,7 @@ public class AdminAPIBean implements AdminAPI {
                        // Perhaps the requested resource is not a file, so
                        // check for folders as well.
                        FolderDTO folder = getFolder(cursor.getId(), lastElement);
-                       res.addAll(api.getFiles(folder.getOwner().getId(), folder.getId(), false));
+                       res.addAll(getFiles(folder.getOwner().getId(), folder.getId(), false));
 
                }
 
@@ -419,9 +419,9 @@ public class AdminAPIBean implements AdminAPI {
        public void removeUser(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException{
                User user = api.getUser(userId);
                try{
-                       FolderDTO folder = api.getRootFolder(userId);
+                       FolderDTO folder = getRootFolder(userId);
                        deleteFolder(userId, folder.getId());
-                       List<GroupDTO> groups = api.getGroups(userId);
+                       List<GroupDTO> groups = getGroups(userId);
                        for(GroupDTO group : groups)
                                api.deleteGroup(userId, group.getId());
                }
@@ -567,4 +567,40 @@ public class AdminAPIBean implements AdminAPI {
                }
        }
 
+       /*** MOVE METHODS WITH DTOS FROM ExternalAPIAbean ***/
+       private FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException {
+        if (userId == null)
+                throw new ObjectNotFoundException("No user specified");
+        Folder folder = dao.getRootFolder(userId);
+        return folder.getDTO();
+}
+
+       private List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
+    throws ObjectNotFoundException, InsufficientPermissionsException {
+               // Validate.
+               if (userId == null)
+                   throw new ObjectNotFoundException("No user specified");
+               if (folderId == null)
+                   throw new ObjectNotFoundException("No folder specified");
+               User user = dao.getEntityById(User.class, userId);
+               Folder folder = dao.getEntityById(Folder.class, folderId);
+               if (!folder.hasReadPermission(user))
+                   throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
+               // Do the actual work.
+               List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
+               List<FileHeader> files = dao.getFiles(folderId, userId, ignoreDeleted);
+               for (FileHeader f : files)
+                   result.add(f.getDTO());
+               return result;
+               }
+       
+       private List<GroupDTO> getGroups(final Long userId) throws ObjectNotFoundException {
+        if (userId == null)
+                throw new ObjectNotFoundException("No user specified");
+        final List<Group> groups = dao.getGroups(userId);
+        final List<GroupDTO> result = new ArrayList<GroupDTO>();
+        for (final Group g : groups)
+                result.add(g.getDTO());
+        return result;
+       }
 }
index 5db1f17..48b817d 100644 (file)
@@ -24,20 +24,18 @@ import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.InvitationUsedException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.QuotaExceededException;
+import gr.ebs.gss.server.domain.FileBody;
 import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.FileLock;
 import gr.ebs.gss.server.domain.FileUploadStatus;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.Group;
 import gr.ebs.gss.server.domain.Invitation;
 import gr.ebs.gss.server.domain.Nonce;
+import gr.ebs.gss.server.domain.Permission;
 import gr.ebs.gss.server.domain.User;
 import gr.ebs.gss.server.domain.UserClass;
 import gr.ebs.gss.server.domain.UserLogin;
-import gr.ebs.gss.server.domain.dto.FileBodyDTO;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.PermissionDTO;
-import gr.ebs.gss.server.domain.dto.StatsDTO;
-import gr.ebs.gss.server.domain.dto.UserDTO;
 
 import java.io.File;
 import java.io.IOException;
@@ -50,6 +48,10 @@ import javax.ejb.Local;
 import javax.ejb.TransactionAttribute;
 import javax.ejb.TransactionAttributeType;
 
+import gr.ebs.gss.server.domain.WebDavNonce;
+import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
+import gr.ebs.gss.server.domain.dto.StatsDTO;
+import gr.ebs.gss.server.domain.dto.UserDTO;
 import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
 
 /**
@@ -68,7 +70,7 @@ public interface ExternalAPI {
         * @return Folder
         * @throws ObjectNotFoundException if no Folder or user was found
         */
-       public FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException;
+       public Folder getRootFolder(Long userId) throws ObjectNotFoundException;
 
        /**
         * Retrieve the folder with the specified ID.
@@ -79,7 +81,7 @@ public interface ExternalAPI {
         * @throws ObjectNotFoundException if the folder or the user was not found
         * @throws InsufficientPermissionsException if ther user does not have read permissions for folder
         */
-       public FolderDTO getFolder(Long userId, Long folderId) throws ObjectNotFoundException,
+       public Folder getFolder(Long userId, Long folderId) throws ObjectNotFoundException,
                        InsufficientPermissionsException;
 
        /**
@@ -107,7 +109,7 @@ public interface ExternalAPI {
         * @return The Group object
         * @throws ObjectNotFoundException if the group cannot be found
         */
-       public GroupDTO getGroup(Long groupId) throws ObjectNotFoundException;
+       public Group getGroup(Long groupId) throws ObjectNotFoundException;
 
        /**
         * Returns the group with the specified name that belongs to the
@@ -118,7 +120,7 @@ public interface ExternalAPI {
         * @return The Group object
         * @throws ObjectNotFoundException if the group cannot be found
         */
-       public GroupDTO getGroup(Long userId, String name) throws ObjectNotFoundException;
+       public Group getGroup(Long userId, String name) throws ObjectNotFoundException;
 
        /**
         * Retrieve the list of groups for a particular user.
@@ -127,7 +129,7 @@ public interface ExternalAPI {
         * @return a List of Groups that belong to the specified User
         * @throws ObjectNotFoundException if the user was not found
         */
-       public List<GroupDTO> getGroups(Long userId) throws ObjectNotFoundException;
+       public List<Group> getGroups(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of files contained in the folder specified by its id.
@@ -139,7 +141,7 @@ public interface ExternalAPI {
         * @throws ObjectNotFoundException if the user or the folder cannot be found
         * @throws InsufficientPermissionsException
         */
-       public List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted) throws ObjectNotFoundException,
+       public List<FileHeader> getFiles(Long userId, Long folderId, boolean ignoreDeleted) throws ObjectNotFoundException,
                        InsufficientPermissionsException;
 
        /**
@@ -147,19 +149,19 @@ public interface ExternalAPI {
         *
         * @param userId the ID of the User
         * @param groupId the ID of the requested group
-        * @return List<UserDTO>
+        * @return List<User>
         * @throws ObjectNotFoundException if the user or group was not found, with
         *             the exception message mentioning the precise problem
         */
-       public List<UserDTO> getUsers(Long userId, Long groupId) throws ObjectNotFoundException;
+       public List<User> getUsers(Long userId, Long groupId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of users matching the specified username
         *
         * @param username the username of the User
-        * @return List<UserDTO>
+        * @return List<User>
         */
-       public List<UserDTO> getUsersByUserNameLike(String username);
+       public List<User> getUsersByUserNameLike(String username);
 
        /**
         * Creates a new folder with the specified owner, parent folder and name.
@@ -176,7 +178,7 @@ public interface ExternalAPI {
         *             problem
         * @throws InsufficientPermissionsException
         */
-       public FolderDTO createFolder(Long userId, Long parentId, String name) throws DuplicateNameException,
+       public Folder createFolder(Long userId, Long parentId, String name) throws DuplicateNameException,
                        ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
@@ -202,34 +204,10 @@ public interface ExternalAPI {
         * @throws ObjectNotFoundException if the folder or user was not found
         * @throws InsufficientPermissionsException
         */
-       public List<FolderDTO> getSubfolders(Long userId, Long folderId)
-                       throws ObjectNotFoundException, InsufficientPermissionsException;
-
-       /**
-        * Retrieve the folder with the specified ID with subfolders.
-        *
-        * @param userId the ID of the current user
-        * @param folderId the ID of the folder to retrieve
-        * @return the folder found
-        * @throws ObjectNotFoundException if the folder or the user was not found
-        * @throws InsufficientPermissionsException if ther user does not have read permissions for folder
-        */
-       public FolderDTO getFolderWithSubfolders(Long userId, Long folderId)
+       public List<Folder> getSubfolders(Long userId, Long folderId)
                        throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
-        * Retrieve the folder with the specified ID with subfolders.
-        *
-        * @param userId the ID of the current user
-        * @param callingUserId the ID of the user requesting this operation
-        * @param folderId the ID of the folder to retrieve
-        * @return the folder found
-        * @throws ObjectNotFoundException if the folder or the user was not found
-        * @throws InsufficientPermissionsException if ther user does not have read permissions for folder
-        */
-       public FolderDTO getFolderWithSubfolders(Long userId, Long callingUserId, Long folderId)
-                       throws ObjectNotFoundException, InsufficientPermissionsException;
-       /**
         * Retrieve the subfolders of the specified folder that are shared to others.
         *
         * @param userId the ID of the current user
@@ -237,7 +215,7 @@ public interface ExternalAPI {
         * @return the list of subfolders found
         * @throws ObjectNotFoundException if the folder or user was not found
         */
-       public List<FolderDTO> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException;
+       public List<Folder> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException;
 
        /**
         * Retrieve the subfolders of the specified folder that are shared to others.
@@ -248,7 +226,7 @@ public interface ExternalAPI {
         * @return the list of subfolders found
         * @throws ObjectNotFoundException if the folder or user was not found
         */
-       public List<FolderDTO> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException;
+       public List<Folder> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException;
        /**
         * Modifies the specified folder if the specified user has the appropriate
         * permission.
@@ -266,9 +244,9 @@ public interface ExternalAPI {
         * @throws DuplicateNameException if the specified name already exists in
         *             the parent folder, as either a folder or file
         */
-       public FolderDTO updateFolder(Long userId, Long folderId, String folderName,
+       public Folder updateFolder(Long userId, Long folderId, String folderName,
                                Boolean readForAll,
-                               Set<PermissionDTO> permissions)
+                               Set<Permission> permissions)
                        throws InsufficientPermissionsException, ObjectNotFoundException, DuplicateNameException;
 
        /**
@@ -317,7 +295,7 @@ public interface ExternalAPI {
         * @param name the name of the new file
         * @param mimeType the MIME type of the file
         * @param stream the input stream with the file contents
-        * @return The FileHeaderDTO created
+        * @return The FileHeader created
         * @throws DuplicateNameException if the specified name already exists in
         *             the parent folder, as either a folder or file
         * @throws ObjectNotFoundException if the user or parent folder was not
@@ -327,7 +305,7 @@ public interface ExternalAPI {
         * @throws InsufficientPermissionsException
         * @throws QuotaExceededException
         */
-       public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType,
+       public FileHeader createFile(Long userId, Long folderId, String name, String mimeType,
                                InputStream stream) throws DuplicateNameException, ObjectNotFoundException,
                                GSSIOException, InsufficientPermissionsException, QuotaExceededException;
 
@@ -345,19 +323,6 @@ public interface ExternalAPI {
        public void deleteFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
-        * Deletes the specified file in the specified user's namespace.
-        *
-        * @param userId the ID of the current user
-        * @param fileIds the IDs of the files to delete
-        * @throws ObjectNotFoundException if the user or file was not found, with
-        *             the exception message mentioning the precise problem
-        * @throws InsufficientPermissionsException if the user does not have the
-        *             appropriate privileges
-        */
-       public void deleteFiles(Long userId, List<Long> fileIds)
-                       throws ObjectNotFoundException, InsufficientPermissionsException;
-
-       /**
         * Creates a new tag for the specified user and file.
         *
         * @param userId the creator of the tag
@@ -393,7 +358,7 @@ public interface ExternalAPI {
         */
        public void updateFile(Long userId, Long fileId, String name, String tagSet,
                        Date modificationDate, Boolean versioned, Boolean readForAll,
-                       Set<PermissionDTO> permissions)
+                       Set<Permission> permissions)
                        throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
@@ -439,7 +404,7 @@ public interface ExternalAPI {
         *                      the exception message mentioning the precise problem
         * @throws InsufficientPermissionsException
         */
-       public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException,
+       public FileHeader getFile(Long userId, Long fileId) throws ObjectNotFoundException,
                        InsufficientPermissionsException;
 
        /**
@@ -453,13 +418,13 @@ public interface ExternalAPI {
         *                      the exception message mentioning the precise problem
         * @throws InsufficientPermissionsException
         */
-       public FileBodyDTO getFileBody(Long userId, Long fileId, Long bodyId)
+       public FileBody getFileBody(Long userId, Long fileId, Long bodyId)
                        throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Get the resource (file or folder) at the specified path in
         * the specified user's namespace. The returned object will be of type
-        * FileHeaderDTO or FolderDTO.<p><strong>Note:</strong> this method does not
+        * FileHeader or Folder.<p><strong>Note:</strong> this method does not
         * receive the current user as a parameter, therefore it is unable to perform
         * the necessary permission checks and should <strong>NOT</strong> be directly
         * exposed to remote clients. It is the caller's responsibility to verify that
@@ -648,31 +613,6 @@ public interface ExternalAPI {
        public void removeFileFromTrash(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
-        * Marks  the specified files as deleted in the specified user's namespace.
-        *
-        * @param userId the ID of the current user
-        * @param fileIds the IDs of the file to delete
-        * @throws ObjectNotFoundException if the user or file was not found, with
-        *             the exception message mentioning the precise problem
-        * @throws InsufficientPermissionsException if the user does not have the
-        *             appropriate privileges
-        */
-       public void moveFilesToTrash(Long userId, List<Long> fileIds)
-                       throws ObjectNotFoundException, InsufficientPermissionsException;
-
-       /**
-        * Marks  the specified deleted files as undeleted in the specified user's namespace.
-        *
-        * @param userId the ID of the current user
-        * @param fileIds the IDs of the file to undelete
-        * @throws ObjectNotFoundException if the user or file was not found, with
-        *             the exception message mentioning the precise problem
-        * @throws InsufficientPermissionsException if the user does not have the
-        *             appropriate privileges
-        */
-       public void removeFilesFromTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException;
-
-       /**
         * Marks  the specified folder as deleted in the specified user's namespace.
         *
         * @param userId the ID of the current user
@@ -798,7 +738,7 @@ public interface ExternalAPI {
         *       * @return the list of deleted file header objects
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException;
+       public List<FileHeader> getDeletedFiles(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of All deleted root folders of a user.
@@ -807,7 +747,7 @@ public interface ExternalAPI {
         *       * @return the list of deleted file header objects
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getDeletedRootFolders(Long userId) throws ObjectNotFoundException;
+       public List<Folder> getDeletedRootFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Empty Trash by deleting all marked as deleted files and folders
@@ -885,7 +825,7 @@ public interface ExternalAPI {
         * @throws ObjectNotFoundException if the user or folder could not be found
         * @throws InsufficientPermissionsException
         */
-       public Set<PermissionDTO> getFolderPermissions(Long userId, Long folderId)
+       public Set<Permission> getFolderPermissions(Long userId, Long folderId)
                        throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
@@ -897,7 +837,7 @@ public interface ExternalAPI {
         * @throws ObjectNotFoundException if the user or folder could not be found
         * @throws InsufficientPermissionsException
         */
-       public Set<PermissionDTO> getFilePermissions(Long userId, Long fileId)
+       public Set<Permission> getFilePermissions(Long userId, Long fileId)
                        throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
@@ -907,7 +847,7 @@ public interface ExternalAPI {
         * @return the list of shared root folders
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getSharedRootFolders(Long userId) throws ObjectNotFoundException;
+       public List<Folder> getSharedRootFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of all shared files of a user that are not
@@ -917,7 +857,7 @@ public interface ExternalAPI {
         * @return the list of shared files
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException;
+       public List<FileHeader> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of all shared files of a user.
@@ -926,7 +866,7 @@ public interface ExternalAPI {
         * @return the list of shared files
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getSharedFiles(Long userId) throws ObjectNotFoundException;
+       public List<FileHeader> getSharedFiles(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of all shared folders of a user.
@@ -935,7 +875,7 @@ public interface ExternalAPI {
         * @return the list of shared folders
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getSharedFolders(Long userId) throws ObjectNotFoundException;
+       public List<Folder> getSharedFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of all shared root folders of a user that calling
@@ -947,7 +887,7 @@ public interface ExternalAPI {
         *
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getSharedRootFolders(Long ownerId, Long callingUserId)
+       public List<Folder> getSharedRootFolders(Long ownerId, Long callingUserId)
                        throws ObjectNotFoundException;
 
        /**
@@ -959,7 +899,7 @@ public interface ExternalAPI {
         * @param callingUserId
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getSharedFiles(Long ownerId, Long callingUserId)
+       public List<FileHeader> getSharedFiles(Long ownerId, Long callingUserId)
                        throws ObjectNotFoundException;
 
        /**
@@ -982,7 +922,7 @@ public interface ExternalAPI {
         * @return the List of users sharing files to user
         * @throws ObjectNotFoundException
         */
-       public List<UserDTO> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException;
+       public List<User> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException;
 
        /**
         * Search Files
@@ -1043,19 +983,6 @@ public interface ExternalAPI {
        public StatsDTO getUserStatistics(Long userId) throws ObjectNotFoundException;
 
        /**
-        * Retrieves file versions
-        *
-        * @param userId the ID of the user
-        * @param fileId the ID of the file
-        * @return the list of filebodies
-        * @throws ObjectNotFoundException
-        * @throws InsufficientPermissionsException
-        *
-        */
-       public List<FileBodyDTO> getVersions(Long userId, Long fileId)
-                       throws ObjectNotFoundException, InsufficientPermissionsException;
-
-       /**
         * Restore the file contents to the specified version.
         *
         * @param userId the ID of the user
@@ -1072,20 +999,6 @@ public interface ExternalAPI {
                        throws ObjectNotFoundException, InsufficientPermissionsException,  GSSIOException, QuotaExceededException;
 
        /**
-        * Remove file version identified by bodyId
-        *
-        * @param userId the ID of the user
-        * @param fileId the ID of the file
-        * @param bodyId the ID of the body
-        *
-        * @throws ObjectNotFoundException
-        * @throws InsufficientPermissionsException
-        *
-        */
-       public void removeVersion(Long userId, Long fileId, Long bodyId)
-                       throws ObjectNotFoundException, InsufficientPermissionsException;
-
-       /**
         * Removes all old file versions for specified file keeping only the current revision
         *
         * @param userId the ID of the user
@@ -1119,7 +1032,7 @@ public interface ExternalAPI {
         * @param mimeType the MIME type of the file
         * @param fileSize the uploaded file size
         * @param filePath the uploaded file full path
-        * @return The FileHeaderDTO created
+        * @return The FileHeader created
         * @throws DuplicateNameException if the specified name already exists in
         *             the parent folder, as either a folder or file
         * @throws ObjectNotFoundException if the user or parent folder was not
@@ -1129,7 +1042,7 @@ public interface ExternalAPI {
         * @throws InsufficientPermissionsException
         * @throws QuotaExceededException
         */
-       public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
+       public FileHeader createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
                        throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
                        InsufficientPermissionsException, QuotaExceededException;
 
@@ -1142,14 +1055,14 @@ public interface ExternalAPI {
         * @param mimeType the content type of the file
         * @param fileSize the uploaded file size
         * @param filePath the uploaded file full path
-        * @return The FileHeaderDTO updated
+        * @return The FileHeader updated
         * @throws ObjectNotFoundException if the user or file was not found, with
         *                      the exception message mentioning the precise problem
         * @throws GSSIOException when an IO exception occurs
         * @throws InsufficientPermissionsException
         * @throws QuotaExceededException
         */
-       public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType,
+       public FileHeader updateFileContents(Long userId, Long fileId, String mimeType,
                                long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException,
                                InsufficientPermissionsException, QuotaExceededException;
 
@@ -1186,7 +1099,7 @@ public interface ExternalAPI {
         * @throws InsufficientPermissionsException if the user does not
         *                      have enough privileges for reading this file
         */
-       public FileBodyDTO getFileVersion(Long userId, Long fileId, int version) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public FileBody getFileVersion(Long userId, Long fileId, int version) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Search the system for a user with the specified email address.
@@ -1293,6 +1206,85 @@ public interface ExternalAPI {
        public void postFileToSolr(CommonsHttpSolrServer solr, Long id);
        
        /**
+        * @param folder
+        * @throws ObjectNotFoundException 
+        */
+       public Folder expandFolder(Folder folder) throws ObjectNotFoundException;
+
+       /**
+        * @param folder
+        * @return
+        * @throws ObjectNotFoundException
+        */
+       FileHeader expandFile(FileHeader folder) throws ObjectNotFoundException;
+
+       /**
+        * @param folder
+        * @return
+        * @throws ObjectNotFoundException
+        */
+       Group expandGroup(Group folder) throws ObjectNotFoundException;
+
+       /**
+        * @param username
+        * @return
+        */
+       User getUserByUserName(String username);
+
+       /**
+        * @param lock
+        * @return
+        */
+       FileLock saveOrUpdateLock(FileLock lock);
+
+       /**
+        * @param lock
+        */
+       void removeLock(FileLock lock);
+
+       /**
+        * @param tokenId
+        * @return
+        */
+       FileLock getLockByToken(String tokenId);
+
+       /**
+        * @param id
+        * @return
+        */
+       FileLock getLockById(String id);
+
+       /**
+        * @param userId
+        * @param folderId
+        * @param name
+        * @return
+        * @throws DuplicateNameException
+        * @throws ObjectNotFoundException
+        * @throws GSSIOException
+        * @throws InsufficientPermissionsException
+        * @throws QuotaExceededException
+        */
+       FileHeader createEmptyFile(Long userId, Long folderId, String name) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
+
+       /**
+        * @param nonce
+        * @return
+        */
+       WebDavNonce saveOrUpdateWebDavNonce(WebDavNonce nonce);
+
+       /**
+        * @param nonce
+        */
+       void removeWebDavNonce(WebDavNonce nonce);
+
+       /**
+        * @param tokenId
+        * @return
+        */
+       WebDavNonce getWebDavNonce(String tokenId);
+               
+       /**
         * Returns a user that matches the given full username 
         *
         * @param username the username of the User
index ff8ec1d..88059a0 100644 (file)
@@ -19,6 +19,8 @@
 package gr.ebs.gss.server.ejb;
 
 import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+
+import gr.ebs.gss.admin.client.ui.UsersTable;
 import gr.ebs.gss.client.exceptions.DuplicateNameException;
 import gr.ebs.gss.client.exceptions.GSSIOException;
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
@@ -32,17 +34,14 @@ import gr.ebs.gss.server.domain.FileTag;
 import gr.ebs.gss.server.domain.FileUploadStatus;
 import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.FileLock;
 import gr.ebs.gss.server.domain.Invitation;
 import gr.ebs.gss.server.domain.Nonce;
 import gr.ebs.gss.server.domain.Permission;
 import gr.ebs.gss.server.domain.User;
 import gr.ebs.gss.server.domain.UserClass;
 import gr.ebs.gss.server.domain.UserLogin;
-import gr.ebs.gss.server.domain.dto.FileBodyDTO;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.PermissionDTO;
+import gr.ebs.gss.server.domain.WebDavNonce;
 import gr.ebs.gss.server.domain.dto.StatsDTO;
 import gr.ebs.gss.server.domain.dto.UserDTO;
 
@@ -58,7 +57,6 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Random;
@@ -160,15 +158,15 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
        
        @Override
-       public FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException {
+       public Folder getRootFolder(Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                Folder folder = dao.getRootFolder(userId);
-               return folder.getDTO();
+               return folder;
        }
 
        @Override
-       public FolderDTO getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
+       public Folder getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (folderId == null)
@@ -178,7 +176,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                // Check permissions
                if (!folder.hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
-               return folder.getDTO();
+               return expandFolder(folder);
        }
 
        @Override
@@ -194,15 +192,15 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public GroupDTO getGroup(final Long groupId) throws ObjectNotFoundException {
+       public Group getGroup(final Long groupId) throws ObjectNotFoundException {
                if (groupId == null)
                        throw new ObjectNotFoundException("No group specified");
                final Group group = dao.getEntityById(Group.class, groupId);
-               return group.getDTO();
+               return group;
        }
 
        @Override
-       public GroupDTO getGroup(Long userId, String name) throws ObjectNotFoundException {
+       public Group getGroup(Long userId, String name) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (name == null)
@@ -211,23 +209,20 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                List<Group> groups = user.getGroupsSpecified();
                for (Group group: groups)
                        if (group.getName().equals(name))
-                               return group.getDTO();
+                               return group;
                throw new ObjectNotFoundException("Group " + name + " not found");
        }
 
        @Override
-       public List<GroupDTO> getGroups(final Long userId) throws ObjectNotFoundException {
+       public List<Group> getGroups(final Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                final List<Group> groups = dao.getGroups(userId);
-               final List<GroupDTO> result = new ArrayList<GroupDTO>();
-               for (final Group g : groups)
-                       result.add(g.getDTO());
-               return result;
+               return groups;
        }
 
        @Override
-       public List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
+       public List<FileHeader> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
                        throws ObjectNotFoundException, InsufficientPermissionsException {
                // Validate.
                if (userId == null)
@@ -238,16 +233,12 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                Folder folder = dao.getEntityById(Folder.class, folderId);
                if (!folder.hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
-               // Do the actual work.
-               List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
                List<FileHeader> files = dao.getFiles(folderId, userId, ignoreDeleted);
-               for (FileHeader f : files)
-                       result.add(f.getDTO());
-               return result;
+               return files;
        }
 
        @Override
-       public List<UserDTO> getUsers(final Long userId, final Long groupId) throws ObjectNotFoundException {
+       public List<User> getUsers(final Long userId, final Long groupId) throws ObjectNotFoundException {
                // Validate.
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -256,14 +247,11 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
 
                // Do the actual work.
                final List<User> users = dao.getUsers(groupId);
-               final List<UserDTO> result = new ArrayList<UserDTO>();
-               for (final User u : users)
-                       result.add(u.getDTO());
-               return result;
+               return users;
        }
 
        @Override
-       public FolderDTO createFolder(Long userId, Long parentId, String name)
+       public Folder createFolder(Long userId, Long parentId, String name)
                        throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
                // Validate.
                if (userId == null)
@@ -301,7 +289,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
         * @param creator
         * @return the new folder
         */
-       private FolderDTO createFolder(String name, Folder parent, User creator) {
+       private Folder createFolder(String name, Folder parent, User creator) {
                Folder folder = new Folder();
                folder.setName(name);
                if (parent != null) {
@@ -342,7 +330,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        folder.setReadForAll(parent.isReadForAll());
 
                dao.create(folder);
-               return folder.getDTO();
+               return folder;
        }
 
        @Override
@@ -389,7 +377,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
 
        @Override
        @SuppressWarnings("unchecked")
-       public List<FolderDTO> getSubfolders(Long userId, Long folderId)
+       public List<Folder> getSubfolders(Long userId, Long folderId)
                        throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -399,18 +387,18 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                Folder folder = dao.getEntityById(Folder.class, folderId);
                if (!folder.hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
+               List<Folder> result = new ArrayList<Folder>();
                if (folder.hasReadPermission(user))
                        for (Folder f : folder.getSubfolders())
                                if (f.hasReadPermission(user) && !f.isDeleted())
-                                       result.add(f.getDTO());
+                                       result.add(f);
                return result;
        }
 
        @Override
-       public FolderDTO updateFolder(Long userId, Long folderId, String folderName,
+       public Folder updateFolder(Long userId, Long folderId, String folderName,
                                Boolean readForAll,
-                               Set<PermissionDTO> permissions)
+                               Set<Permission> permissions)
                        throws InsufficientPermissionsException, ObjectNotFoundException,
                        DuplicateNameException {
 
@@ -447,9 +435,21 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                folder.getAuditInfo().setModifiedBy(user);
                dao.update(folder);
                touchParentFolders(folder, user, new Date());
-               return folder.getDTO();
+               // Re-index the folder contents if it was modified.
+               if ((permissions != null && !permissions.isEmpty()) || readForAll != null) {
+            indexFolder(folder);
+        }
+
+               return folder;
        }
 
+    private void indexFolder(Folder folder) {
+        for (FileHeader fh : folder.getFiles())
+            indexFile(fh.getId(), false);
+        for (Folder f : folder.getSubfolders())
+            indexFolder(f);
+    }
+
        @Override
        public void createGroup(final Long userId, final String name) throws ObjectNotFoundException, DuplicateNameException {
                // Validate.
@@ -487,16 +487,13 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        List<Folder> folders = dao.getFoldersPermittedForGroup(userId, groupId);
                        for (Folder f : folders){
                                f.getPermissions().removeAll(group.getPermissions());
-                               touchFolder(f, owner, now);
                                for(FileHeader file : f.getFiles()){
                                        file.getPermissions().removeAll(group.getPermissions());
-                                       touchFile(file, owner, now);
                                }
                        }
                        List<FileHeader> files = dao.getFilesPermittedForGroup(userId, groupId);
                        for(FileHeader h : files){
                                h.getPermissions().removeAll(group.getPermissions());
-                               touchFile(h, owner, now);
                        }
                        owner.removeSpecifiedGroup(group);
                        dao.delete(group);
@@ -505,7 +502,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
+       public FileHeader createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
                        throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
                        InsufficientPermissionsException, QuotaExceededException {
                File file = null;
@@ -645,7 +642,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        @Override
        public void updateFile(Long userId, Long fileId, String name,
                                String tagSet, Date modificationDate, Boolean versioned,
-                               Boolean readForAll,     Set<PermissionDTO> permissions)
+                               Boolean readForAll,     Set<Permission> permissions)
                        throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -781,7 +778,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
+       public FileHeader getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (fileId == null)
@@ -790,11 +787,11 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
                if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
-               return file.getDTO();
+               return file;
        }
 
        @Override
-       public FileBodyDTO getFileBody(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
+       public FileBody getFileBody(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (fileId == null)
@@ -804,7 +801,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
                FileBody body = dao.getEntityById(FileBody.class, bodyId);
-               return body.getDTO();
+               return body;
        }
 
        @Override
@@ -837,14 +834,14 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                // Use the lastElement to retrieve the actual resource.
                Object resource = null;
                try {
-                       FileHeaderDTO file = getFile(cursor==null ? rootFolderId : cursor.getId(), lastElement);
+                       FileHeader file = getFile(cursor==null ? rootFolderId : cursor.getId(), lastElement);
                        if (ignoreDeleted && file.isDeleted())
                                throw new ObjectNotFoundException("Resource not found");
                        resource = file;
                } catch (ObjectNotFoundException e) {
                        // Perhaps the requested resource is not a file, so
                        // check for folders as well.
-                       FolderDTO folder = getFolder(cursor==null ? rootFolderId : cursor.getId(), lastElement).getDTO();
+                       Folder folder = getFolder(cursor==null ? rootFolderId : cursor.getId(), lastElement);
                        if (ignoreDeleted && folder.isDeleted())
                                throw new ObjectNotFoundException("Resource not found");
                        resource = folder;
@@ -863,14 +860,14 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
         *             found, with the exception message mentioning the precise
         *             problem
         */
-       private FileHeaderDTO getFile(Long folderId, String name) throws ObjectNotFoundException {
+       private FileHeader getFile(Long folderId, String name) throws ObjectNotFoundException {
                if (folderId == null)
                        throw new ObjectNotFoundException("No parent folder specified");
                if (StringUtils.isEmpty(name))
                        throw new ObjectNotFoundException("No file specified");
 
                FileHeader file = dao.getFile(folderId, name);
-               return file.getDTO();
+               return file;
        }
 
        /**
@@ -894,7 +891,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                return folder;
        }
 
-       private FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
+       private FileHeader updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
                File file = null;
                try {
                        file = uploadFile(resourceInputStream, userId);
@@ -915,9 +912,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No destination specified");
 
                Object destination = getResourceAtPath(userId, getParentPath(dest), true);
-               if (!(destination instanceof FolderDTO))
+               if (!(destination instanceof Folder))
                        throw new ObjectNotFoundException("Destination parent folder not found");
-               FolderDTO parent = (FolderDTO) destination;
+               Folder parent = (Folder) destination;
                copyFile(userId, fileId, parent.getId(), getLastElement(dest));
        }
 
@@ -933,9 +930,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No destination specified");
 
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
-               if (!(destination instanceof FolderDTO))
+               if (!(destination instanceof Folder))
                        throw new ObjectNotFoundException("Destination parent folder not found");
-               FolderDTO parent = (FolderDTO) destination;
+               Folder parent = (Folder) destination;
                copyFile(userId, fileId, parent.getId(), getLastElement(dest));
        }
 
@@ -992,9 +989,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No destination specified");
 
                Object destination = getResourceAtPath(userId, getParentPath(dest), true);
-               if (!(destination instanceof FolderDTO))
+               if (!(destination instanceof Folder))
                        throw new ObjectNotFoundException("Destination folder not found");
-               FolderDTO parent = (FolderDTO) destination;
+               Folder parent = (Folder) destination;
                copyFolder(userId, folderId, parent.getId(), getLastElement(dest));
        }
 
@@ -1028,9 +1025,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No destination specified");
 
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
-               if (!(destination instanceof FolderDTO))
+               if (!(destination instanceof Folder))
                        throw new ObjectNotFoundException("Destination folder not found");
-               FolderDTO parent = (FolderDTO) destination;
+               Folder parent = (Folder) destination;
                copyFolderStructure(userId, folderId, parent.getId(), getLastElement(dest));
        }
 
@@ -1131,14 +1128,17 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if (parent == null)
                        throw new ObjectNotFoundException("The specified file has no parent folder");
                User user = dao.getEntityById(User.class, userId);
-               if (!file.hasDeletePermission(user))
-                       throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
-
-               file.setDeleted(true);
-               dao.update(file);
-               touchParentFolders(parent, user, new Date());
+        trashFile(user, file);
+        touchParentFolders(parent, user, new Date());
        }
 
+    private void trashFile(User user, FileHeader file) throws InsufficientPermissionsException {
+        if (!file.hasDeletePermission(user))
+            throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
+
+        file.setDeleted(true);
+    }
+
        @Override
        public void moveFileToPath(Long userId, Long ownerId, Long fileId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
                if (userId == null)
@@ -1151,9 +1151,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No destination specified");
 
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
-               if (!(destination instanceof FolderDTO))
+               if (!(destination instanceof Folder))
                        throw new ObjectNotFoundException("Destination parent folder not found");
-               FolderDTO parent = (FolderDTO) destination;
+               Folder parent = (Folder) destination;
                moveFile(userId, fileId, parent.getId(), getLastElement(dest));
        }
 
@@ -1219,9 +1219,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No destination specified");
 
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
-               if (!(destination instanceof FolderDTO))
+               if (!(destination instanceof Folder))
                        throw new ObjectNotFoundException("Destination parent folder not found");
-               FolderDTO parent = (FolderDTO) destination;
+               Folder parent = (Folder) destination;
                moveFolder(userId, folderId, parent.getId(), getLastElement(dest));
        }
 
@@ -1282,17 +1282,14 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException {
+       public List<FileHeader> getDeletedFiles(Long userId) throws ObjectNotFoundException {
                // Validate.
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
 
                // Do the actual work.
-               final List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
                final List<FileHeader> files = dao.getDeletedFiles(userId);
-               for (final FileHeader f : files)
-                       result.add(f.getDTO());
-               return result;
+               return files;
        }
 
        @Override
@@ -1309,34 +1306,39 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if (parent == null)
                        throw new ObjectNotFoundException("The specified file has no parent folder");
                User user = dao.getEntityById(User.class, userId);
-               if (!file.hasDeletePermission(user))
-                       throw new InsufficientPermissionsException("User " + user.getUsername() +
-                                               " cannot restore file " + file.getName());
-
-               file.setDeleted(false);
-               dao.update(file);
+        untrashFile(user, file);
                touchParentFolders(parent, user, new Date());
        }
 
+    private void untrashFile(User user, FileHeader file) throws InsufficientPermissionsException {
+        if (!file.hasDeletePermission(user))
+            throw new InsufficientPermissionsException("User " + user.getUsername() +
+                        " cannot restore file " + file.getName());
+
+        file.setDeleted(false);
+    }
+
        @Override
        public void moveFolderToTrash(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               if (userId == null)
-                       throw new ObjectNotFoundException("No user specified");
-               if (folderId == null)
-                       throw new ObjectNotFoundException("No folder specified");
-               Folder folder = dao.getEntityById(Folder.class, folderId);
-               User user = dao.getEntityById(User.class, userId);
-               if (!folder.hasDeletePermission(user))
-                       throw new InsufficientPermissionsException("You don't have the necessary permissions");
-               folder.setDeleted(true);
-               dao.update(folder);
-               touchParentFolders(folder, user, new Date());
-               for (FileHeader file : folder.getFiles())
-                       moveFileToTrash(userId, file.getId());
-               for (Folder subFolder : folder.getSubfolders())
-                       moveFolderToTrash(userId, subFolder.getId());
-
-       }
+        if (userId == null)
+            throw new ObjectNotFoundException("No user specified");
+        if (folderId == null)
+            throw new ObjectNotFoundException("No folder specified");
+        Folder folder = dao.getEntityById(Folder.class, folderId);
+        User user = dao.getEntityById(User.class, userId);
+        trashFolder(user, folder);
+        touchParentFolders(folder, user, new Date());
+       }
+
+    private void trashFolder(User user, Folder folder) throws ObjectNotFoundException, InsufficientPermissionsException {
+        if (!folder.hasDeletePermission(user))
+            throw new InsufficientPermissionsException("You don't have the necessary permissions");
+        folder.setDeleted(true);
+        for (FileHeader file : folder.getFiles())
+            trashFile(user, file);
+        for (Folder subFolder : folder.getSubfolders())
+            trashFolder(user, subFolder);
+    }
 
        @Override
        public void removeFolderFromTrash(Long userId, Long folderId)
@@ -1347,45 +1349,45 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No folder specified");
                Folder folder = dao.getEntityById(Folder.class, folderId);
                User user = dao.getEntityById(User.class, userId);
-               if (!folder.hasDeletePermission(user))
-                       throw new InsufficientPermissionsException("User " + user.getUsername() +
-                                               " cannot restore folder " + folder.getName());
-               folder.setDeleted(false);
-               for (FileHeader file : folder.getFiles())
-                       removeFileFromTrash(userId, file.getId());
-               for (Folder subFolder : folder.getSubfolders())
-                       removeFolderFromTrash(userId, subFolder.getId());
-               dao.update(folder);
+        untrashFolder(user, folder);
                touchParentFolders(folder, user, new Date());
        }
 
+    private void untrashFolder(User user, Folder folder) throws ObjectNotFoundException, InsufficientPermissionsException {
+        if (!folder.hasDeletePermission(user))
+            throw new InsufficientPermissionsException("User " + user.getUsername() +
+                        " cannot restore folder " + folder.getName());
+        folder.setDeleted(false);
+        for (FileHeader file : folder.getFiles())
+            untrashFile(user, file);
+        for (Folder subFolder : folder.getSubfolders())
+            untrashFolder(user, subFolder);
+    }
+
        @Override
-       public List<FolderDTO> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
+       public List<Folder> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
                List<Folder> folders = dao.getDeletedRootFolders(userId);
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
-               for (Folder folder : folders)
-                       result.add(folder.getDTO());
-               return result;
+               return folders;
        }
 
        @Override
        public void emptyTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
-               for (FolderDTO fdto : deletedRootFolders)
-                       deleteFolder(userId, fdto.getId());
-               List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
-               for (FileHeaderDTO filedto : deletedFiles)
-                       deleteFile(userId, filedto.getId());
+               List<Folder> deletedRootFolders = getDeletedRootFolders(userId);
+               for (Folder folder : deletedRootFolders)
+                       deleteFolder(userId, folder.getId());
+               List<FileHeader> deletedFiles = getDeletedFiles(userId);
+               for (FileHeader file : deletedFiles)
+                       deleteFile(userId, file.getId());
        }
 
        @Override
        public void restoreTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
-               for (FolderDTO fdto : deletedRootFolders)
-                       removeFolderFromTrash(userId, fdto.getId());
-               List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
-               for (FileHeaderDTO filedto : deletedFiles)
-                       removeFileFromTrash(userId, filedto.getId());
+               List<Folder> deletedRootFolders = getDeletedRootFolders(userId);
+               for (Folder folder : deletedRootFolders)
+                       removeFolderFromTrash(userId, folder.getId());
+               List<FileHeader> deletedFiles = getDeletedFiles(userId);
+               for (FileHeader file : deletedFiles)
+                       removeFileFromTrash(userId, file.getId());
        }
 
        @Override
@@ -1469,7 +1471,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public Set<PermissionDTO> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
+       public Set<Permission> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (folderId == null)
@@ -1479,14 +1481,14 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if(!folder.hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
                Set<Permission> perms = folder.getPermissions();
-               Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
+               Set<Permission> result = new LinkedHashSet<Permission>();
                for (Permission perm : perms)
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
-                               result.add(perm.getDTO());
+                               result.add(perm);
                for (Permission perm : perms)
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
                        } else
-                               result.add(perm.getDTO());
+                               result.add(perm);
                return result;
 
        }
@@ -1501,13 +1503,13 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
         * @throws ObjectNotFoundException
         * @throws InsufficientPermissionsException
         */
-       private void setFolderPermissions(User user, Folder folder, Set<PermissionDTO> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
+       private void setFolderPermissions(User user, Folder folder, Set<Permission> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (permissions != null && !permissions.isEmpty()) {
                        User owner = folder.getOwner();
-                       PermissionDTO ownerPerm = null;
-                       for (PermissionDTO dto : permissions)
-                               if (dto.getUser() != null && dto.getUser().getId().equals(owner.getId())) {
-                                       ownerPerm = dto;
+                       Permission ownerPerm = null;
+                       for (Permission perm : permissions)
+                               if (perm.getUser() != null && perm.getUser().getId().equals(owner.getId())) {
+                                       ownerPerm = perm;
                                        break;
                                }
                        if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
@@ -1516,10 +1518,10 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        for (Permission perm: folder.getPermissions())
                                dao.delete(perm);
                        folder.getPermissions().clear();
-                       for (PermissionDTO dto : permissions) {
+                       for (Permission p : permissions) {
                                // Skip 'empty' permission entries.
-                               if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
-                               folder.addPermission(getPermission(dto));
+                               if (!p.getRead() && !p.getWrite() && !p.getModifyACL()) continue;
+                               folder.addPermission(getPermission(p));
                        }
                        dao.update(folder);
                        for (FileHeader file : folder.getFiles()) {
@@ -1533,18 +1535,18 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                }
        }
 
-       private Permission getPermission(PermissionDTO dto) throws ObjectNotFoundException {
+       private Permission getPermission(Permission perm) throws ObjectNotFoundException {
                Permission res = new Permission();
-               if (dto.getGroup() != null)
-                       res.setGroup(dao.getEntityById(Group.class, dto.getGroup().getId()));
-               else if (dto.getUser() != null)
-                       if (dto.getUser().getId() == null)
-                               res.setUser(dao.getUser(dto.getUser().getUsername()));
+               if (perm.getGroup() != null)
+                       res.setGroup(dao.getEntityById(Group.class, perm.getGroup().getId()));
+               else if (perm.getUser() != null)
+                       if (perm.getUser().getId() == null)
+                               res.setUser(dao.getUser(perm.getUser().getUsername()));
                        else
-                               res.setUser(dao.getEntityById(User.class, dto.getUser().getId()));
-               res.setRead(dto.hasRead());
-               res.setWrite(dto.hasWrite());
-               res.setModifyACL(dto.hasModifyACL());
+                               res.setUser(dao.getEntityById(User.class, perm.getUser().getId()));
+               res.setRead(perm.hasRead());
+               res.setWrite(perm.hasWrite());
+               res.setModifyACL(perm.hasModifyACL());
                return res;
        }
 
@@ -1552,12 +1554,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersByUserNameLike(java.lang.String)
         */
        @Override
-       public List<UserDTO> getUsersByUserNameLike(String username) {
+       public List<User> getUsersByUserNameLike(String username) {
                List<User> users = dao.getUsersByUserNameLike(username);
-               List<UserDTO> result = new ArrayList<UserDTO>();
-               for (User u : users)
-                       result.add(u.getDTO());
-               return result;
+               return users;
 
        }
 
@@ -1591,15 +1590,15 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public List<FolderDTO> getSharedRootFolders(Long userId) throws ObjectNotFoundException {
+       public List<Folder> getSharedRootFolders(Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                List<Folder> folders = dao.getSharedRootFolders(userId);
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
+               List<Folder> result = new ArrayList<Folder>();
                for (Folder f : folders) {
-                       FolderDTO dto = f.getDTO();
-                       dto.setSubfolders(getSharedSubfolders(userId, f.getId()));
-                       result.add(dto);
+                       Folder lf = f;
+                       lf.setSubfolders(getSharedSubfolders(userId, f.getId()));
+                       result.add(lf);
                }
                return result;
        }
@@ -1623,20 +1622,20 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public List<UserDTO> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException {
+       public List<User> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException {
                List<User> users = dao.getUsersSharingFoldersForUser(userId);
                List<User> usersFiles = dao.getUsersSharingFilesForUser(userId);
-               List<UserDTO> res = new ArrayList<UserDTO>();
+               List<User> result = new ArrayList<User>();
                for (User u : users)
-                       res.add(u.getDTO());
+                       result.add(u);
                for(User fu : usersFiles)
                        if(!users.contains(fu))
-                               res.add(fu.getDTO());
-               return res;
+                               result.add(fu);
+               return result;
        }
 
        @Override
-       public Set<PermissionDTO> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
+       public Set<Permission> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (fileId == null)
@@ -1646,14 +1645,14 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if(!folder.hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
                Set<Permission> perms = folder.getPermissions();
-               Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
+               Set<Permission> result = new LinkedHashSet<Permission>();
                for (Permission perm : perms)
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
-                               result.add(perm.getDTO());
+                               result.add(perm);
                for (Permission perm : perms)
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
                        } else
-                               result.add(perm.getDTO());
+                               result.add(perm);
                return result;
        }
 
@@ -1668,13 +1667,13 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
         * @throws InsufficientPermissionsException
         */
        private void setFilePermissions(FileHeader file,
-                               Set<PermissionDTO> permissions)
+                               Set<Permission> permissions)
                        throws ObjectNotFoundException, InsufficientPermissionsException {
                if (permissions != null && !permissions.isEmpty()) {
-                       PermissionDTO ownerPerm = null;
-                       for (PermissionDTO dto : permissions)
-                               if (dto.getUser() != null && dto.getUser().getId().equals(file.getOwner().getId())) {
-                                       ownerPerm = dto;
+                       Permission ownerPerm = null;
+                       for (Permission perm : permissions)
+                               if (perm.getUser() != null && perm.getUser().getId().equals(file.getOwner().getId())) {
+                                       ownerPerm = perm;
                                        break;
                                }
                        if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
@@ -1683,96 +1682,84 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        for (Permission perm: file.getPermissions())
                                dao.delete(perm);
                        file.getPermissions().clear();
-                       for (PermissionDTO dto : permissions) {
+                       for (Permission perm : permissions) {
                                // Skip 'empty' permission entries.
-                               if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
-                               file.addPermission(getPermission(dto));
+                               if (!perm.getRead() && !perm.getWrite() && !perm.getModifyACL()) continue;
+                               file.addPermission(getPermission(perm));
                        }
                        dao.flush();
                }
        }
 
        @Override
-       public List<FileHeaderDTO> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
+       public List<FileHeader> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                List<FileHeader> files = dao.getSharedFilesNotInSharedFolders(userId);
-               List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
-               for (FileHeader f : files)
-                       result.add(f.getDTO());
-               return result;
+               return files;
        }
 
        @Override
-       public List<FileHeaderDTO> getSharedFiles(Long userId) throws ObjectNotFoundException {
+       public List<FileHeader> getSharedFiles(Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                List<FileHeader> files = dao.getSharedFiles(userId);
-               List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
-               for (FileHeader f : files)
-                       result.add(f.getDTO());
-               return result;
+               return files;
        }
 
        @Override
-       public List<FolderDTO> getSharedFolders(Long userId) throws ObjectNotFoundException {
+       public List<Folder> getSharedFolders(Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                List<Folder> folders = dao.getSharedFolders(userId);
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
-               for (Folder f : folders)
-                       result.add(f.getDTO());
-               return result;
+               return folders;
        }
 
        @Override
-       public List<FileHeaderDTO> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
+       public List<FileHeader> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
                if (ownerId == null)
                        throw new ObjectNotFoundException("No owner specified");
                if (callingUserId == null)
                        throw new ObjectNotFoundException("No calling user specified");
                List<FileHeader> folders = dao.getSharedFiles(ownerId, callingUserId);
-               List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
-               for (FileHeader f : folders)
-                       result.add(f.getDTO());
-               return result;
+               return folders;
        }
 
        @Override
-       public List<FolderDTO> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
+       public List<Folder> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
                if (ownerId == null)
                        throw new ObjectNotFoundException("No owner specified");
                if (callingUserId == null)
                        throw new ObjectNotFoundException("No calling user specified");
                List<Folder> folders = dao.getSharedRootFolders(ownerId, callingUserId);
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
+               List<Folder> result = new ArrayList<Folder>();
                for (Folder f : folders) {
-                       FolderDTO dto = f.getDTO();
-                       dto.setSubfolders(getSharedSubfolders(ownerId, callingUserId, f.getId()));
-                       result.add(dto);
+                       Folder lf = f;
+                       lf.setSubfolders(getSharedSubfolders(ownerId, callingUserId, f.getId()));
+                       result.add(lf);
                }
                return result;
 
        }
 
        @Override
-       public List<FolderDTO> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException {
+       public List<Folder> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (folderId == null)
                        throw new ObjectNotFoundException("No folder specified");
                User user = dao.getEntityById(User.class, userId);
                Folder folder = dao.getEntityById(Folder.class, folderId);
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
+               List<Folder> result = new ArrayList<Folder>();
                if (folder.isShared(user) || folder.isReadForAll())
                        for (Folder f : folder.getSubfolders())
                                if ((f.isShared(user) || f.isReadForAll()) && !f.isDeleted())
-                                       result.add(f.getDTO());
+                                       result.add(f);
                return result;
        }
 
        @Override
-       public List<FolderDTO> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException {
+       public List<Folder> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (callingUserId == null)
@@ -1781,13 +1768,13 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                        throw new ObjectNotFoundException("No folder specified");
                User user = dao.getEntityById(User.class, callingUserId);
                Folder folder = dao.getEntityById(Folder.class, folderId);
-               List<FolderDTO> result = new ArrayList<FolderDTO>();
+               List<Folder> result = new ArrayList<Folder>();
                if (folder.isSharedForOtherUser(user))
                        for (Folder f : folder.getSubfolders())
                                if (f.isSharedForOtherUser(user) && !f.isDeleted()){
-                                       FolderDTO dto = f.getDTO();
-                                       dto.setSubfolders(getSharedSubfolders(userId, callingUserId, dto.getId()));
-                                       result.add(dto);
+                                       Folder lf = f;
+                                       lf.setSubfolders(getSharedSubfolders(userId, callingUserId, lf.getId()));
+                                       result.add(lf);
                                }
                return result;
 
@@ -1891,52 +1878,6 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public void deleteFiles(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
-               if (userId == null)
-                       throw new ObjectNotFoundException("No user specified");
-               final User user = dao.getEntityById(User.class, userId);
-               List<String> filesToRemove = new ArrayList<String>();
-               //first delete database objects
-               for(Long fileId : fileIds){
-                       if (fileId == null)
-                               throw new ObjectNotFoundException("No file specified");
-                       final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
-                       final Folder parent = file.getFolder();
-                       if (parent == null)
-                               throw new ObjectNotFoundException("The specified file has no parent folder");
-                       if (!file.hasDeletePermission(user))
-                               throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
-
-                       parent.removeFile(file);
-                       for (final FileBody body : file.getBodies())
-                               filesToRemove.add(body.getStoredFilePath());
-                       dao.delete(file);
-                       touchParentFolders(parent, user, new Date());
-               }
-               //then remove physical files if everything is ok
-               for(String physicalFileName : filesToRemove)
-                       deleteActualFile(physicalFileName);
-               //then unindex deleted files
-               for(Long fileId : fileIds)
-                       indexFile(fileId, true);
-
-       }
-
-       @Override
-       public void moveFilesToTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
-               for(Long l : fileIds)
-                       moveFileToTrash(userId, l);
-
-       }
-
-       @Override
-       public void removeFilesFromTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
-               for(Long l : fileIds)
-                       removeFileFromTrash(userId, l);
-
-       }
-
-       @Override
        public Nonce createNonce(Long userId) throws ObjectNotFoundException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -1987,51 +1928,6 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public List<FileBodyDTO> getVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               if (userId == null)
-                       throw new ObjectNotFoundException("No user specified");
-               if (fileId == null)
-                       throw new ObjectNotFoundException("No file specified");
-               User user = dao.getEntityById(User.class, userId);
-               FileHeader header = dao.getEntityById(FileHeader.class, fileId);
-               if(!header.hasReadPermission(user))
-                       throw new InsufficientPermissionsException("You don't have the necessary permissions");
-               List<FileBodyDTO> result = new LinkedList<FileBodyDTO>();
-               for(int i = header.getBodies().size()-1 ; i>=0; i--)
-                       result.add(header.getBodies().get(i).getDTO());
-               return result;
-       }
-
-       @Override
-       public void removeVersion(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               if (userId == null)
-                       throw new ObjectNotFoundException("No user specified");
-               if (fileId == null)
-                       throw new ObjectNotFoundException("No file specified");
-               if (bodyId == null)
-                       throw new ObjectNotFoundException("No body specified");
-               User user = dao.getEntityById(User.class, userId);
-               FileHeader header = dao.getEntityById(FileHeader.class, fileId);
-               if(!header.hasWritePermission(user))
-                       throw new InsufficientPermissionsException("You don't have the necessary permissions");
-               FileBody body = dao.getEntityById(FileBody.class, bodyId);
-               if(body.equals(header.getCurrentBody())){
-
-                       if(header.getBodies().size() == 1)
-                               throw new InsufficientPermissionsException("You cant delete this version, Delete file instead!");
-                       for(FileBody b : header.getBodies())
-                               if(b.getVersion() == body.getVersion()-1)
-                                       header.setCurrentBody(b);
-               }
-               deleteActualFile(body.getStoredFilePath());
-               header.getBodies().remove(body);
-
-               Folder parent = header.getFolder();
-               touchParentFolders(parent, user, new Date());
-
-       }
-
-       @Override
        public void restoreVersion(Long userId, Long fileId, int version) throws ObjectNotFoundException, InsufficientPermissionsException,  GSSIOException, QuotaExceededException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -2159,7 +2055,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
+       public FileHeader createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
                        throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
                        InsufficientPermissionsException, QuotaExceededException {
                // Validate.
@@ -2225,11 +2121,11 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                dao.flush();
                indexFile(file.getId(), false);
 
-               return file.getDTO();
+               return file;
        }
 
        @Override
-       public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
+       public FileHeader updateFileContents(Long userId, Long fileId, String mimeType, long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (fileId == null)
@@ -2262,7 +2158,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                touchParentFolders(parent, owner, new Date());
 
                indexFile(fileId, false);
-               return file.getDTO();
+               return file;
        }
 
        /**
@@ -2432,45 +2328,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public FolderDTO getFolderWithSubfolders(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               if (userId == null)
-                       throw new ObjectNotFoundException("No user specified");
-               if (folderId == null)
-                       throw new ObjectNotFoundException("No folder specified");
-               final User user = dao.getEntityById(User.class, userId);
-               final Folder folder = dao.getEntityById(Folder.class, folderId);
-               // Check permissions
-               if (!folder.hasReadPermission(user))
-                       throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
-               List<FolderDTO> subfolders = new ArrayList<FolderDTO>();
-               if (folder.hasReadPermission(user))
-                       for (Folder f : folder.getSubfolders())
-                               if (f.hasReadPermission(user) && !f.isDeleted())
-                                       subfolders.add(f.getDTO());
-               FolderDTO result = folder.getDTO();
-               result.setSubfolders(subfolders);
-               return folder.getDTO();
-       }
-
-       @Override
-       public FolderDTO getFolderWithSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
-               if (userId == null)
-                       throw new ObjectNotFoundException("No user specified");
-               if (folderId == null)
-                       throw new ObjectNotFoundException("No folder specified");
-               User user = dao.getEntityById(User.class, callingUserId);
-               Folder folder = dao.getEntityById(Folder.class, folderId);
-               // Check permissions
-               if (!folder.hasReadPermission(user))
-                       throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
-
-               FolderDTO result = folder.getDTO();
-               result.setSubfolders(getSharedSubfolders(userId, callingUserId, folder.getId()));
-               return result;
-       }
-
-       @Override
-       public FileBodyDTO getFileVersion(Long userId, Long fileId, int version)
+       public FileBody getFileVersion(Long userId, Long fileId, int version)
                        throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -2483,7 +2341,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
                FileBody body = dao.getFileVersion(fileId, version);
-               return body.getDTO();
+               return body;
        }
 
        @Override
@@ -2578,26 +2436,6 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        /**
-        * Mark the folder as modified from the specified user and change it's modification date.
-        */
-       private void touchFolder(Folder f, User _user, Date now){
-               final AuditInfo auditInfo = f.getAuditInfo();
-               auditInfo.setModificationDate(now);
-               auditInfo.setModifiedBy(_user);
-               f.setAuditInfo(auditInfo);
-       }
-
-       /**
-        * Mark the file as modified from the specified user and change it's modification date.
-        */
-       private void touchFile(FileHeader f, User _user, Date now){
-               final AuditInfo auditInfo = f.getAuditInfo();
-               auditInfo.setModificationDate(now);
-               auditInfo.setModifiedBy(_user);
-               f.setAuditInfo(auditInfo);
-       }
-
-       /**
         * Set the provided readForAll as the new readforAll value of the specified
         * folder and sub-folders.
         *
@@ -2679,9 +2517,9 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                 for (Permission p : file.getPermissions()) {
                     if (p.getRead()) {
                         if (p.getUser() != null)
-                            solrRequest.setParam("literal.ureaders", p.getUser().getId().toString());
+                            solrRequest.getParams().add("literal.ureaders", p.getUser().getId().toString());
                         else if (p.getGroup() != null)
-                            solrRequest.setParam("literal.greaders", p.getGroup().getId().toString());
+                            solrRequest.getParams().add("literal.greaders", p.getGroup().getId().toString());
                     }
                 }
                 solrRequest.setParam("literal.owner", file.getOwner().getId().toString());
@@ -2761,6 +2599,187 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                return text.replaceAll(":", "\\\\:");
        }
        
+       /*** NEW METHODS IN ORDER TO AVOID LAZY loading exception in json render 
+        ****/
+       @Override
+       public Folder expandFolder(Folder folder) throws ObjectNotFoundException{
+               Folder result = dao.getEntityById(Folder.class, folder.getId());
+               result.getSubfolders().size();
+               result.getFiles().size();
+               result.getPermissions().size();
+               return result;
+}
+
+       @Override
+       public FileHeader expandFile(FileHeader folder) throws ObjectNotFoundException{
+               FileHeader result = dao.getEntityById(FileHeader.class, folder.getId());
+               result.getFolder();
+               result.getPermissions().size();
+               result.getFileTags().size();
+               return result;
+       }
+       
+       @Override
+       public Group expandGroup(Group folder) throws ObjectNotFoundException{
+               Group result = dao.getEntityById(Group.class, folder.getId());
+               result.getMembers().size();
+               return result;
+       }
+
+       /* (non-Javadoc)
+        * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersByUserNameLike(java.lang.String)
+        */
+       @Override
+       public User getUserByUserName(String username) {
+               User result = dao.getUserByUserName(username);
+               return result;
+       }
+       
+       /*WEBDAV CREATE EMPTY FILE*/
+       @Override
+       public FileHeader createEmptyFile(Long userId, Long folderId, String name)
+                       throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
+                       InsufficientPermissionsException, QuotaExceededException {
+               // Validate.
+               if (userId == null)
+                       throw new ObjectNotFoundException("No user specified");
+               if (folderId == null)
+                       throw new ObjectNotFoundException("No folder specified");
+               String contentType = DEFAULT_MIME_TYPE;
+               if (StringUtils.isEmpty(name))
+                       throw new ObjectNotFoundException("No file name specified");
+               if (dao.existsFolderOrFile(folderId, name))
+                       throw new DuplicateNameException("A folder or file with the name '" + name +
+                                               "' already exists at this level");
+
+               // Do the actual work.
+               Folder parent = null;
+               try {
+                       parent = dao.getEntityById(Folder.class, folderId);
+               } catch (final ObjectNotFoundException onfe) {
+                       // Supply a more accurate problem description.
+                       throw new ObjectNotFoundException("Parent folder not found");
+               }
+               final User owner = dao.getEntityById(User.class, userId);
+               if (!parent.hasWritePermission(owner))
+                       throw new InsufficientPermissionsException("You don't have the permissions to write to this folder");
+               final FileHeader file = new FileHeader();
+               file.setName(name);
+               parent.addFile(file);
+               // set file owner to folder owner
+               file.setOwner(parent.getOwner());
+               //set file's readForAll value according to parent folder readForAll value
+               file.setReadForAll(parent.isReadForAll());
+
+               final Date now = new Date();
+               final AuditInfo auditInfo = new AuditInfo();
+               auditInfo.setCreatedBy(owner);
+               auditInfo.setCreationDate(now);
+               auditInfo.setModifiedBy(owner);
+               auditInfo.setModificationDate(now);
+               file.setAuditInfo(auditInfo);
+               // TODO set the proper versioning flag on creation
+               file.setVersioned(false);
+
+               for (final Permission p : parent.getPermissions()) {
+                       final Permission permission = new Permission();
+                       permission.setGroup(p.getGroup());
+                       permission.setUser(p.getUser());
+                       permission.setRead(p.getRead());
+                       permission.setWrite(p.getWrite());
+                       permission.setModifyACL(p.getModifyACL());
+                       file.addPermission(permission);
+               }
+               // Create the file body.
+               try {
+                       createEmptyFileBody(name, contentType, 0,  file, auditInfo);
+               } catch (FileNotFoundException e) {
+                       throw new GSSIOException(e);
+               }
+               touchParentFolders(parent, owner, new Date());
+               dao.flush();
+               return file;
+       }
+       
+       private void createEmptyFileBody(String name, String mimeType, long fileSize, 
+                               FileHeader header, AuditInfo auditInfo)
+                       throws FileNotFoundException, QuotaExceededException, ObjectNotFoundException {
+
+               long currentTotalSize = 0;
+               if (!header.isVersioned() && header.getCurrentBody() != null && header.getBodies() != null)
+                       currentTotalSize = header.getTotalSize();
+               Long quotaLeft = getQuotaLeft(header.getOwner().getId());
+               
+
+               FileBody body = new FileBody();
+
+               // if no mime type or the generic mime type is defined by the client, then try to identify it from the filename extension
+               if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType)
+                                       || "application/download".equals(mimeType) || "application/force-download".equals(mimeType)
+                                       || "octet/stream".equals(mimeType) || "application/unknown".equals(mimeType))
+                       body.setMimeType(identifyMimeType(name));
+               else
+                       body.setMimeType(mimeType);
+               body.setAuditInfo(auditInfo);
+               body.setFileSize(fileSize);
+               body.setOriginalFilename(name);
+               body.setStoredFilePath(generateRepositoryFilePath());
+               //CLEAR OLD VERSION IF FILE IS NOT VERSIONED AND GETS UPDATED
+               if(!header.isVersioned() && header.getCurrentBody() != null){
+                       header.setCurrentBody(null);
+                       if (header.getBodies() != null) {
+                               Iterator<FileBody> it = header.getBodies().iterator();
+                               while(it.hasNext()){
+                                       FileBody bo = it.next();
+                                       deleteActualFile(bo.getStoredFilePath());
+                                       it.remove();
+                                       dao.delete(bo);
+                               }
+                       }
+               }
+
+               dao.flush();
+               header.addBody(body);
+               header.setAuditInfo(auditInfo);
+
+               dao.create(body);
+       }
+       /*** WEBDAV LOCK **/
+       @Override
+       public FileLock getLockById(String id) {
+               return dao.getLockById(id);
+       }
+
+       @Override
+       public FileLock getLockByToken(String tokenId) {
+               return dao.getLockByToken(tokenId);
+       }
+
+       @Override
+       public void removeLock(FileLock lock) {
+               dao.removeLock(lock);           
+       }
+
+       @Override
+       public FileLock saveOrUpdateLock(FileLock lock) {
+               return dao.saveOrUpdateLock(lock);
+       }
+       
+       @Override
+       public WebDavNonce getWebDavNonce(String tokenId) {
+               return dao.getWebDavNonce(tokenId);
+       }
+
+       @Override
+       public void removeWebDavNonce(WebDavNonce nonce) {
+               dao.removeWebDavNonce(nonce);           
+       }
+
+       @Override
+       public WebDavNonce saveOrUpdateWebDavNonce(WebDavNonce nonce) {
+               return dao.saveOrUpdateWebDavNonce(nonce);
+       }
+       
        /* (non-Javadoc)
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersByUserNameLike(java.lang.String)
         */
index f6083b4..cc2552b 100644 (file)
@@ -24,12 +24,10 @@ import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.QuotaExceededException;
 import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.Permission;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.PermissionDTO;
-import gr.ebs.gss.server.domain.dto.UserDTO;
 
 import java.io.InputStream;
 import java.util.Date;
@@ -54,7 +52,7 @@ public interface ExternalAPIRemote {
         * @return Folder
         * @throws ObjectNotFoundException if no Folder or user was found
         */
-       public FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException;
+       public Folder getRootFolder(Long userId) throws ObjectNotFoundException;
 
        /**
         * Retrieve the folder with the specified ID.
@@ -65,7 +63,7 @@ public interface ExternalAPIRemote {
         * @throws ObjectNotFoundException if the folder or the user was not found
         * @throws InsufficientPermissionsException if ther user does not have read permissions for folder
         */
-       public FolderDTO getFolder(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public Folder getFolder(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Returns the user with the specified ID.
@@ -77,22 +75,13 @@ public interface ExternalAPIRemote {
        public User getUser(Long userId) throws ObjectNotFoundException;
 
        /**
-        * Returns the user with the specified ID.
-        *
-        * @param userId The ID of the User to be found
-        * @return The User object
-        * @throws ObjectNotFoundException if the user cannot be found
-        */
-       public UserDTO getUserDTO(Long userId) throws ObjectNotFoundException;
-
-       /**
         * Returns the group with the specified ID.
         *
         * @param groupId The ID of the Group to be found
         * @return The Group object
         * @throws ObjectNotFoundException if the group cannot be found
         */
-       public GroupDTO getGroup(Long groupId) throws ObjectNotFoundException;
+       public Group getGroup(Long groupId) throws ObjectNotFoundException;
 
        /**
         * Retrieve the list of groups for a particular user.
@@ -101,7 +90,7 @@ public interface ExternalAPIRemote {
         * @return a List of Groups that belong to the specified User
         * @throws ObjectNotFoundException if the user was not found
         */
-       public List<GroupDTO> getGroups(Long userId) throws ObjectNotFoundException;
+       public List<Group> getGroups(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of files contained in the folder specified by its id.
@@ -113,26 +102,26 @@ public interface ExternalAPIRemote {
         * @throws ObjectNotFoundException if the user or the folder cannot be found
         * @throws InsufficientPermissionsException
         */
-       public List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public List<FileHeader> getFiles(Long userId, Long folderId, boolean ignoreDeleted) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Returns a list of users for the specified group
         *
         * @param userId the ID of the User
         * @param groupId the ID of the requested group
-        * @return List<UserDTO>
+        * @return List<User>
         * @throws ObjectNotFoundException if the user or group was not found, with
         *             the exception message mentioning the precise problem
         */
-       public List<UserDTO> getUsers(Long userId, Long groupId) throws ObjectNotFoundException;
+       public List<User> getUsers(Long userId, Long groupId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of users for the specified username
         *
         * @param username the username of the User
-        * @return List<UserDTO>
+        * @return List<User>
         */
-       public List<UserDTO> getUsersByUserNameLike(String username);
+       public List<User> getUsersByUserNameLike(String username);
 
        /**
         * Creates a new folder with the specified owner, parent folder and name.
@@ -149,7 +138,7 @@ public interface ExternalAPIRemote {
         *             problem
         * @throws InsufficientPermissionsException
         */
-       public FolderDTO createFolder(Long userId, Long parentId, String name) throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException;
+       public Folder createFolder(Long userId, Long parentId, String name) throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Deletes the specified folder if the specified user has the appropriate
@@ -173,7 +162,7 @@ public interface ExternalAPIRemote {
         * @throws ObjectNotFoundException if the folder or user was not found
         * @throws InsufficientPermissionsException
         */
-       public List<FolderDTO> getSubfolders(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public List<Folder> getSubfolders(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
 
        /**
@@ -184,7 +173,7 @@ public interface ExternalAPIRemote {
         * @return the list of subfolders found
         * @throws ObjectNotFoundException if the folder or user was not found
         */
-       public List<FolderDTO> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException;
+       public List<Folder> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException;
 
        /**
         * Modifies the specified folder if the specified user has the appropriate
@@ -203,9 +192,9 @@ public interface ExternalAPIRemote {
         * @throws DuplicateNameException if the specified name already exists in
         *             the parent folder, as either a folder or file
         */
-       public FolderDTO updateFolder(Long userId, Long folderId, String folderName,
+       public Folder updateFolder(Long userId, Long folderId, String folderName,
                                Boolean readForAll,
-                               Set<PermissionDTO> permissions)
+                               Set<Permission> permissions)
                        throws InsufficientPermissionsException, ObjectNotFoundException,
                        DuplicateNameException;
 
@@ -254,7 +243,7 @@ public interface ExternalAPIRemote {
         * @param name the name of the new file
         * @param mimeType the MIME type of the file
         * @param stream the input stream with the file contents
-        * @return The FileHeaderDTO created
+        * @return The FileHeader created
         * @throws DuplicateNameException if the specified name already exists in
         *             the parent folder, as either a folder or file
         * @throws ObjectNotFoundException if the user or parent folder was not
@@ -263,7 +252,7 @@ public interface ExternalAPIRemote {
         * @throws GSSIOException if there was an error while storing the file contents
         * @throws InsufficientPermissionsException
         */
-       public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
+       public FileHeader createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
 
        /**
         * Deletes the specified file in the specified user's namespace.
@@ -313,7 +302,7 @@ public interface ExternalAPIRemote {
         */
        public void updateFile(Long userId, Long fileId, String name, String tagSet,
                        Date modificationDate, Boolean versioned, Boolean readForAll,
-                       Set<PermissionDTO> permissions)
+                       Set<Permission> permissions)
                        throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
@@ -341,12 +330,12 @@ public interface ExternalAPIRemote {
         *                      the exception message mentioning the precise problem
         * @throws InsufficientPermissionsException
         */
-       public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public FileHeader getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Get the resource (file or folder) at the specified path in
         * the specified user's namespace. The returned object will be of type
-        * FileHeaderDTO or FolderDTO.<p><strong>Note:</strong> this method does not
+        * FileHeader or Folder.<p><strong>Note:</strong> this method does not
         * receive the current user as a parameter, therefore it is unable to perform
         * the necessary permission checks and should <strong>NOT</strong> be directly
         * exposed to remote clients. It is the caller's responsibility to verify that
@@ -531,7 +520,7 @@ public interface ExternalAPIRemote {
         *       * @return the list of deleted file header objects
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException;
+       public List<FileHeader> getDeletedFiles(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of All deleted root folders of a user.
@@ -540,7 +529,7 @@ public interface ExternalAPIRemote {
         *       * @return the list of deleted file header objects
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getDeletedRootFolders(Long userId) throws ObjectNotFoundException;
+       public List<Folder> getDeletedRootFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Empty Trash by deleting all marked as deleted files and folders
@@ -610,7 +599,7 @@ public interface ExternalAPIRemote {
         * @throws ObjectNotFoundException if the user or folder could not be found
         * @throws InsufficientPermissionsException
         */
-       public Set<PermissionDTO> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public Set<Permission> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Retrieve file user and group permissions
@@ -621,7 +610,7 @@ public interface ExternalAPIRemote {
         * @throws ObjectNotFoundException if the user or folder could not be found
         * @throws InsufficientPermissionsException
         */
-       public Set<PermissionDTO> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException;
+       public Set<Permission> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException;
 
        /**
         * Returns a list of All Shared root folders of a user.
@@ -630,7 +619,7 @@ public interface ExternalAPIRemote {
         *       * @return the list of shared root folders
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getSharedRootFolders(Long userId) throws ObjectNotFoundException;
+       public List<Folder> getSharedRootFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of All Shared  files of a user.
@@ -639,7 +628,7 @@ public interface ExternalAPIRemote {
         *       * @return the list of shared files
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException;
+       public List<FileHeader> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of All Shared root folders of a user that calling user has at least read permissions.
@@ -650,7 +639,7 @@ public interface ExternalAPIRemote {
         *
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FolderDTO> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException;
+       public List<Folder> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException;
 
        /**
         * Returns a list of All Shared  files of a user that calling user has at least read permissions..
@@ -660,7 +649,7 @@ public interface ExternalAPIRemote {
         * @param callingUserId
         * @throws ObjectNotFoundException if the user cannot be found
         */
-       public List<FileHeaderDTO> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException;
+       public List<FileHeader> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException;
 
        /**
         * Remove a user member from a group
@@ -681,7 +670,7 @@ public interface ExternalAPIRemote {
         * @return the List of users sharing files to user
         * @throws ObjectNotFoundException
         */
-       public List<UserDTO> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException;
+       public List<User> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException;
 
        /**
         * Indexes the file meta-data and contents. It actually sends the info to be indexed to a message queue
index 2e5872f..69f0e04 100644 (file)
@@ -25,11 +25,13 @@ import gr.ebs.gss.server.domain.FileHeader;
 import gr.ebs.gss.server.domain.FileUploadStatus;
 import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.FileLock;
 import gr.ebs.gss.server.domain.Invitation;
 import gr.ebs.gss.server.domain.Nonce;
 import gr.ebs.gss.server.domain.User;
 import gr.ebs.gss.server.domain.UserClass;
 import gr.ebs.gss.server.domain.UserLogin;
+import gr.ebs.gss.server.domain.WebDavNonce;
 
 import java.util.Date;
 import java.util.List;
@@ -530,13 +532,51 @@ public interface GSSDAO {
         * @return a list of last user login and the current session user login
         */
        public List<UserLogin> getAllLoginsForUser (Long userId);
-       
+
        /**
-        * Returns the user matching with the specified username
-        *
-        * @param username the email of the User
-        * @return User
+        * @param username
+        * @return
+        */
+       User getUserByUserName(String username);
+
+       /**
+        * @param id
+        * @return
+        */
+       FileLock getLockById(String id);
+
+       /**
+        * @param tokenId
+        * @return
+        */
+       FileLock getLockByToken(String tokenId);
+
+       /**
+        * @param lock
+        */
+       void removeLock(FileLock lock);
+
+       /**
+        * @param lock
+        * @return
+        */
+       FileLock saveOrUpdateLock(FileLock lock);
+
+       /**
+        * @param lock
+        * @return
+        */
+       WebDavNonce saveOrUpdateWebDavNonce(WebDavNonce lock);
+
+       /**
+        * @param lock
+        */
+       void removeWebDavNonce(WebDavNonce lock);
+
+       /**
+        * @param tokenId
+        * @return
         */
-       public User getUserByUserName(String username);
+       WebDavNonce getWebDavNonce(String tokenId);
 
 }
index ac01be6..f06c373 100644 (file)
@@ -26,11 +26,13 @@ import gr.ebs.gss.server.domain.FileHeader;
 import gr.ebs.gss.server.domain.FileUploadStatus;
 import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.FileLock;
 import gr.ebs.gss.server.domain.Invitation;
 import gr.ebs.gss.server.domain.Nonce;
 import gr.ebs.gss.server.domain.User;
 import gr.ebs.gss.server.domain.UserClass;
 import gr.ebs.gss.server.domain.UserLogin;
+import gr.ebs.gss.server.domain.WebDavNonce;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
@@ -797,6 +799,64 @@ public class GSSDAOBean implements GSSDAO {
                                                                .getResultList();
                return res;                                                                     
        }
+       
+       @Override
+       public User getUserByUserName(String username) {
+               return (User) manager.createQuery("select u from User u where u.username=:username").
+               setParameter("username", username).getSingleResult();
+               
+       }
+       
+       
+       /** WEBDAV LOCK API **/
+       @Override
+       public FileLock getLockById(String id) {
+               return manager.find(FileLock.class, id);
+       }
+
+       @Override
+       public FileLock getLockByToken(String tokenId) {
+               return (FileLock) manager.createQuery("select c from FileLock c where c.tokenId=:tokenId").setParameter("tokenId", tokenId).getSingleResult();
+       }
+
+       @Override
+       public void removeLock(FileLock lock) {
+               lock =getLockById(lock.getId());
+               if(lock!=null)
+                       manager.remove(lock);           
+       }
+
+       @Override
+       public FileLock saveOrUpdateLock(FileLock lock) {
+               if(getLockById(lock.getId())!=null)
+                       manager.merge(lock);
+               else
+                       manager.persist(lock);
+               manager.flush();
+               return lock;
+       }
+       
+       @Override
+       public WebDavNonce getWebDavNonce(String tokenId) {
+               return manager.find(WebDavNonce.class, tokenId);
+       }
+
+       @Override
+       public void removeWebDavNonce(WebDavNonce nonce) {
+               nonce =getWebDavNonce(nonce.getId());
+               if(nonce!=null)
+                       manager.remove(nonce);          
+       }
+
+       @Override
+       public WebDavNonce saveOrUpdateWebDavNonce(WebDavNonce nonce) {
+               if(getWebDavNonce(nonce.getId())!=null)
+                       manager.merge(nonce);
+               else
+                       manager.persist(nonce);
+               manager.flush();
+               return nonce;
+       }
 
        @Override
        public User getUserByUserName(String username) {
index 109f3b1..39ac8aa 100644 (file)
@@ -26,13 +26,13 @@ import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.QuotaExceededException;
 import gr.ebs.gss.client.exceptions.RpcException;
 import gr.ebs.gss.server.Login;
+import gr.ebs.gss.server.domain.FileBody;
+import gr.ebs.gss.server.domain.FileHeader;
 import gr.ebs.gss.server.domain.FileUploadStatus;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.Permission;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileBodyDTO;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.PermissionDTO;
 import gr.ebs.gss.server.ejb.ExternalAPI;
 import gr.ebs.gss.server.ejb.TransactionHelper;
 import gr.ebs.gss.server.webdav.Range;
@@ -205,8 +205,8 @@ public class FilesHandler extends RequestHandler {
        User owner = getOwner(req);
         boolean exists = true;
         Object resource = null;
-        FileHeaderDTO file = null;
-        FolderDTO folder = null;
+        FileHeader file = null;
+        Folder folder = null;
         try {
                resource = getService().getResourceAtPath(owner.getId(), path, false);
         } catch (ObjectNotFoundException e) {
@@ -223,10 +223,10 @@ public class FilesHandler extends RequestHandler {
                return;
        }
 
-       if (resource instanceof FolderDTO)
-               folder = (FolderDTO) resource;
+       if (resource instanceof Folder)
+               folder = (Folder) resource;
        else
-               file = (FileHeaderDTO) resource;        // Note that file will be null, if (!exists).
+               file = (FileHeader) resource;   // Note that file will be null, if (!exists).
 
        // Now it's time to perform the deferred authentication check.
                // Since regular signature checking was already performed,
@@ -362,7 +362,7 @@ public class FilesHandler extends RequestHandler {
                // Fetch the version to retrieve, if specified.
                String verStr = req.getParameter(VERSION_PARAM);
                int version = 0;
-               FileBodyDTO oldBody = null;
+               FileBody oldBody = null;
                if (verStr != null && file != null)
                        try {
                                version = Integer.valueOf(verStr);
@@ -402,10 +402,10 @@ public class FilesHandler extends RequestHandler {
        boolean expectJSON = false;
 
        if (file != null) {
-               contentType = version>0 ? oldBody.getMimeType() : file.getMimeType();
+               contentType = version>0 ? oldBody.getMimeType() : file.getCurrentBody().getMimeType();
                if (contentType == null) {
                        contentType = context.getMimeType(file.getName());
-                       file.setMimeType(contentType);
+                       file.getCurrentBody().setMimeType(contentType);
                }
        } else { // folder != null
                String accept = req.getHeader("Accept");
@@ -447,7 +447,7 @@ public class FilesHandler extends RequestHandler {
                        return;
                }
                // Get content length.
-               contentLength = version>0 ? oldBody.getFileSize() : file.getFileSize();
+               contentLength = version>0 ? oldBody.getFileSize() : file.getCurrentBody().getFileSize();
                // Special case for zero length files, which would cause a
                // (silent) ISE when setting the output buffer size.
                if (contentLength == 0L)
@@ -643,7 +643,7 @@ public class FilesHandler extends RequestHandler {
         * Return the filename of the specified file properly formatted for
         * including in the Content-Disposition header.
         */
-       private String getDispositionFilename(FileHeaderDTO file) throws UnsupportedEncodingException {
+       private String getDispositionFilename(FileHeader file) throws UnsupportedEncodingException {
                return URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");
        }
 
@@ -676,7 +676,7 @@ public class FilesHandler extends RequestHandler {
         * @throws IOException if an I/O error occurs
         */
        private void serveProgress(HttpServletRequest req, HttpServletResponse resp,
-                               String parameter, User user, FileHeaderDTO file)        throws IOException {
+                               String parameter, User user, FileHeader file)   throws IOException {
                String filename = file == null ? parameter : file.getName();
                try {
                        FileUploadStatus status = getService().getFileUploadStatus(user.getId(), filename);
@@ -787,13 +787,13 @@ public class FilesHandler extends RequestHandler {
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                        return;
                }
-               if (resource instanceof FolderDTO) {
+               if (resource instanceof Folder) {
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
                        return;
                }
 
                try {
-                       final FileHeaderDTO file = (FileHeaderDTO) resource;
+                       final FileHeader file = (FileHeader) resource;
                        final int oldVersion = Integer.parseInt(version);
 
                        new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
@@ -837,7 +837,7 @@ public class FilesHandler extends RequestHandler {
        User owner = getOwner(request);
        boolean exists = true;
         Object resource = null;
-        FileHeaderDTO file = null;
+        FileHeader file = null;
         try {
                resource = getService().getResourceAtPath(owner.getId(), path, false);
         } catch (ObjectNotFoundException e) {
@@ -848,8 +848,8 @@ public class FilesHandler extends RequestHandler {
                }
 
         if (exists)
-                       if (resource instanceof FileHeaderDTO) {
-                       file = (FileHeaderDTO) resource;
+                       if (resource instanceof FileHeader) {
+                       file = (FileHeader) resource;
                        if (file.isDeleted()) {
                                response.sendError(HttpServletResponse.SC_CONFLICT, file.getName() + " is in the trash");
                        return;
@@ -871,11 +871,11 @@ public class FilesHandler extends RequestHandler {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                        return;
                }
-       if (!(parent instanceof FolderDTO)) {
+       if (!(parent instanceof Folder)) {
                response.sendError(HttpServletResponse.SC_CONFLICT);
                return;
        }
-       final FolderDTO folder = (FolderDTO) parent;
+       final Folder folderLocal = (Folder) parent;
        final String fileName = getLastElement(path);
 
        if (!isValidResourceName(fileName)) {
@@ -970,25 +970,25 @@ public class FilesHandler extends RequestHandler {
                                        } catch (IOException ex) {
                                                throw new GSSIOException(ex, false);
                                        }
-                                       FileHeaderDTO fileDTO = null;
+                                       FileHeader fileLocal = null;
                                        final File upf = uploadedFile;
-                                       final FileHeaderDTO f = file;
+                                       final FileHeader f = file;
                                        final User u = user;
                                        if (file == null)
-                                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                                               fileLocal = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
                                                        @Override
-                                                       public FileHeaderDTO call() throws Exception {
-                                                               return getService().createFile(u.getId(), folder.getId(), fileName, contentType, upf.getCanonicalFile().length(), upf.getAbsolutePath());
+                                                       public FileHeader call() throws Exception {
+                                                               return getService().createFile(u.getId(), folderLocal.getId(), fileName, contentType, upf.getCanonicalFile().length(), upf.getAbsolutePath());
                                                        }
                                                });
                                        else
-                                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                                               fileLocal = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
                                                        @Override
-                                                       public FileHeaderDTO call() throws Exception {
+                                                       public FileHeader call() throws Exception {
                                                                return getService().updateFileContents(u.getId(), f.getId(), contentType, upf.getCanonicalFile().length(), upf.getAbsolutePath());
                                                        }
                                                });
-                                       updateAccounting(owner, new Date(), fileDTO.getFileSize());
+                                       updateAccounting(owner, new Date(), fileLocal.getCurrentBody().getFileSize());
                                        getService().removeFileUploadProgress(user.getId(), fileName);
                                }
                        }
@@ -1099,21 +1099,21 @@ public class FilesHandler extends RequestHandler {
                try {
                        final User dOwner = destOwner;
                        final String dest = destination;
-                       if (resource instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) resource;
+                       if (resource instanceof Folder) {
+                               final Folder folderLocal = (Folder) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().moveFolderToPath(user.getId(), dOwner.getId(), folder.getId(), dest);
+                                               getService().moveFolderToPath(user.getId(), dOwner.getId(), folderLocal.getId(), dest);
                                                return null;
                                        }
                                });
                        } else {
-                               final FileHeaderDTO file = (FileHeaderDTO) resource;
+                               final FileHeader fileLocal = (FileHeader) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().moveFileToPath(user.getId(), dOwner.getId(), file.getId(), dest);
+                                               getService().moveFileToPath(user.getId(), dOwner.getId(), fileLocal.getId(), dest);
                                                return null;
                                        }
                                });
@@ -1184,21 +1184,21 @@ public class FilesHandler extends RequestHandler {
                try {
                        final User dOwner = destOwner;
                        final String dest = destination;
-                       if (resource instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) resource;
+                       if (resource instanceof Folder) {
+                               final Folder folderLocal = (Folder) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().copyFolderStructureToPath(user.getId(), dOwner.getId(), folder.getId(), dest);
+                                               getService().copyFolderStructureToPath(user.getId(), dOwner.getId(), folderLocal.getId(), dest);
                                                return null;
                                        }
                                });
                        } else {
-                               final FileHeaderDTO file = (FileHeaderDTO) resource;
+                               final FileHeader fileLocal = (FileHeader) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().copyFileToPath(user.getId(), dOwner.getId(), file.getId(), dest);
+                                               getService().copyFileToPath(user.getId(), dOwner.getId(), fileLocal.getId(), dest);
                                                return null;
                                        }
                                });
@@ -1303,21 +1303,21 @@ public class FilesHandler extends RequestHandler {
                }
 
                try {
-                       if (resource instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) resource;
+                       if (resource instanceof Folder) {
+                               final Folder folderLocal = (Folder) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().moveFolderToTrash(user.getId(), folder.getId());
+                                               getService().moveFolderToTrash(user.getId(), folderLocal.getId());
                                                return null;
                                        }
                                });
                        } else {
-                               final FileHeaderDTO file = (FileHeaderDTO) resource;
+                               final FileHeader fileLocal = (FileHeader) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().moveFileToTrash(user.getId(), file.getId());
+                                               getService().moveFileToTrash(user.getId(), fileLocal.getId());
                                                return null;
                                        }
                                });
@@ -1356,21 +1356,21 @@ public class FilesHandler extends RequestHandler {
                }
 
                try {
-                       if (resource instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) resource;
+                       if (resource instanceof Folder) {
+                               final Folder folderLocal = (Folder) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().removeFolderFromTrash(user.getId(), folder.getId());
+                                               getService().removeFolderFromTrash(user.getId(), folderLocal.getId());
                                                return null;
                                        }
                                });
                        } else {
-                               final FileHeaderDTO file = (FileHeaderDTO) resource;
+                               final FileHeader fileLocal = (FileHeader) resource;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().removeFileFromTrash(user.getId(), file.getId());
+                                               getService().removeFileFromTrash(user.getId(), fileLocal.getId());
                                                return null;
                                        }
                                });
@@ -1424,15 +1424,15 @@ public class FilesHandler extends RequestHandler {
                        json = new JSONObject(input.toString());
                        if (logger.isDebugEnabled())
                                logger.debug("JSON update: " + json);
-                       if (resource instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) resource;
+                       if (resource instanceof Folder) {
+                               final Folder folderLocal = (Folder) resource;
                                String name = json.optString("name");
                                if (!isValidResourceName(name)) {
                                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
                                return;
                        }
                                JSONArray permissions = json.optJSONArray("permissions");
-                               Set<PermissionDTO> perms = null;
+                               Set<Permission> perms = null;
                                if (permissions != null)
                                        perms = parsePermissions(user, permissions);
                                Boolean readForAll = null;
@@ -1441,18 +1441,18 @@ public class FilesHandler extends RequestHandler {
                                if (!name.isEmpty() || permissions != null || readForAll != null) {
                                        final String fName = name.isEmpty()? null: name;
                                        final Boolean freadForAll =  readForAll;
-                                       final Set<PermissionDTO> fPerms = perms;
-                                       FolderDTO folderUpdated = new TransactionHelper<FolderDTO>().tryExecute(new Callable<FolderDTO>() {
+                                       final Set<Permission> fPerms = perms;
+                                       Folder folderUpdated = new TransactionHelper<Folder>().tryExecute(new Callable<Folder>() {
                                                @Override
-                                               public FolderDTO call() throws Exception {
-                                                       return getService().updateFolder(user.getId(), folder.getId(), fName, freadForAll, fPerms);
+                                               public Folder call() throws Exception {
+                                                       return getService().updateFolder(user.getId(), folderLocal.getId(), fName, freadForAll, fPerms);
                                                }
 
                                        });
                                        resp.getWriter().println(getNewUrl(req, folderUpdated));
                                }
                        } else {
-                               final FileHeaderDTO file = (FileHeaderDTO) resource;
+                               final FileHeader fileLocal = (FileHeader) resource;
                                String name = null;
                                if (json.opt("name") != null)
                                        name = json.optString("name");
@@ -1476,7 +1476,7 @@ public class FilesHandler extends RequestHandler {
                                        tags = t.toString();
                                }
                                JSONArray permissions = json.optJSONArray("permissions");
-                               Set<PermissionDTO> perms = null;
+                               Set<Permission> perms = null;
                                if (permissions != null)
                                        perms = parsePermissions(user, permissions);
                                Boolean readForAll = null;
@@ -1490,11 +1490,11 @@ public class FilesHandler extends RequestHandler {
                                        final Date mDate = modificationDate != null? new Date(modificationDate): null;
                                        final Boolean fVersioned = versioned;
                                        final Boolean fReadForAll = readForAll;
-                                       final Set<PermissionDTO> fPerms = perms;
+                                       final Set<Permission> fPerms = perms;
                                        new TransactionHelper<Object>().tryExecute(new Callable<Object>() {
                                                @Override
                                                public Object call() throws Exception {
-                                                       getService().updateFile(user.getId(), file.getId(),
+                                                       getService().updateFile(user.getId(), fileLocal.getId(),
                                                                                fName, fTags, mDate, fVersioned,
                                                                                fReadForAll, fPerms);
                                                        return null;
@@ -1522,7 +1522,7 @@ public class FilesHandler extends RequestHandler {
        /**
         * Returns the new URL of an updated folder.
         */
-       private String getNewUrl(HttpServletRequest req, FolderDTO folder) throws UnsupportedEncodingException {
+       private String getNewUrl(HttpServletRequest req, Folder folder) throws UnsupportedEncodingException {
                String parentUrl = URLDecoder.decode(getContextPath(req, true),"UTF-8");
                String fpath = URLDecoder.decode(getRelativePath(req), "UTF-8");
                if (parentUrl.indexOf(fpath) != -1)
@@ -1535,7 +1535,7 @@ public class FilesHandler extends RequestHandler {
 
        /**
         * Helper method to convert a JSON array of permissions into a set of
-        * PermissionDTO objects.
+        * Permission objects.
         *
         * @param user the current user
         * @param permissions the JSON array to parse
@@ -1545,14 +1545,14 @@ public class FilesHandler extends RequestHandler {
         * @throws ObjectNotFoundException if the user could not be found
         * @throws UnsupportedEncodingException
         */
-       private Set<PermissionDTO> parsePermissions(User user, JSONArray permissions)
+       private Set<Permission> parsePermissions(User user, JSONArray permissions)
                        throws JSONException, RpcException, ObjectNotFoundException, UnsupportedEncodingException {
                if (permissions == null)
                        return null;
-               Set<PermissionDTO> perms = new HashSet<PermissionDTO>();
+               Set<Permission> perms = new HashSet<Permission>();
                for (int i = 0; i < permissions.length(); i++) {
                        JSONObject j = permissions.getJSONObject(i);
-                       PermissionDTO perm = new PermissionDTO();
+                       Permission perm = new Permission();
                        perm.setModifyACL(j.optBoolean("modifyACL"));
                        perm.setRead(j.optBoolean("read"));
                        perm.setWrite(j.optBoolean("write"));
@@ -1561,7 +1561,7 @@ public class FilesHandler extends RequestHandler {
                                User u = getService().findUser(permUser);
                                if (u == null)
                                        throw new ObjectNotFoundException("User " + permUser + " not found");
-                               perm.setUser(u.getDTO());
+                               perm.setUser(u);
                        }
                        // 31/8/2009: Add optional groupUri which takes priority if it exists
                        String permGroupUri = j.optString("groupUri");
@@ -1573,11 +1573,11 @@ public class FilesHandler extends RequestHandler {
                                User u = getService().findUser(usr);
                                if (u == null)
                                        throw new ObjectNotFoundException("User " + permUser + " not found");
-                               GroupDTO g = getService().getGroup(u.getId(), grp);
+                               Group g = getService().getGroup(u.getId(), grp);
                                perm.setGroup(g);
                        }
                        else if (!permGroup.isEmpty()) {
-                               GroupDTO g = getService().getGroup(user.getId(), permGroup);
+                               Group g = getService().getGroup(user.getId(), permGroup);
                                perm.setGroup(g);
                        }
                        if (permUser.isEmpty() && permGroupUri.isEmpty() && permGroup.isEmpty())
@@ -1630,12 +1630,12 @@ public class FilesHandler extends RequestHandler {
                        return;
                }
                try {
-                       if (parent instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) parent;
-                               FolderDTO newFolder = new TransactionHelper<FolderDTO>().tryExecute(new Callable<FolderDTO>() {
+                       if (parent instanceof Folder) {
+                               final Folder folderLocal = (Folder) parent;
+                               Folder newFolder = new TransactionHelper<Folder>().tryExecute(new Callable<Folder>() {
                                        @Override
-                                       public FolderDTO call() throws Exception {
-                                               return getService().createFolder(user.getId(), folder.getId(), folderName);
+                                       public Folder call() throws Exception {
+                                               return getService().createFolder(user.getId(), folderLocal.getId(), folderName);
                                        }
 
                                });
@@ -1688,7 +1688,7 @@ public class FilesHandler extends RequestHandler {
        User owner = getOwner(req);
        boolean exists = true;
         Object resource = null;
-        FileHeaderDTO file = null;
+        FileHeader fileLocal = null;
         try {
                resource = getService().getResourceAtPath(owner.getId(), path, false);
         } catch (ObjectNotFoundException e) {
@@ -1699,8 +1699,8 @@ public class FilesHandler extends RequestHandler {
                }
 
         if (exists)
-                       if (resource instanceof FileHeaderDTO)
-                       file = (FileHeaderDTO) resource;
+                       if (resource instanceof FileHeader)
+                       fileLocal = (FileHeader) resource;
                        else {
                        resp.sendError(HttpServletResponse.SC_CONFLICT, path + " is a folder");
                        return;
@@ -1736,13 +1736,13 @@ public class FilesHandler extends RequestHandler {
                        resourceInputStream = req.getInputStream();
 
         try {
-               FolderDTO folder = null;
+               Folder folderLocal = null;
                Object parent = getService().getResourceAtPath(owner.getId(), getParentPath(path), true);
-               if (!(parent instanceof FolderDTO)) {
+               if (!(parent instanceof Folder)) {
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
                        return;
                }
-                       folder = (FolderDTO) parent;
+                       folderLocal = (Folder) parent;
                final String name = getLastElement(path);
                final String mimeType = context.getMimeType(name);
                File uploadedFile = null;
@@ -1751,27 +1751,27 @@ public class FilesHandler extends RequestHandler {
                        } catch (IOException ex) {
                                throw new GSSIOException(ex, false);
                        }
-               FileHeaderDTO fileDTO = null;
+               FileHeader fileTemp = null;
                final File uploadedf = uploadedFile;
-                       final FolderDTO parentf = folder;
-                       final FileHeaderDTO f = file;
+                       final Folder parentf = folderLocal;
+                       final FileHeader f = fileLocal;
             if (exists)
-               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+               fileTemp = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
                                        @Override
-                                       public FileHeaderDTO call() throws Exception {
+                                       public FileHeader call() throws Exception {
                                                return getService().updateFileContents(user.getId(), f.getId(), mimeType, uploadedf.getCanonicalFile().length(), uploadedf.getAbsolutePath());
                                        }
                                });
                        else
-                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                               fileTemp = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
                                        @Override
-                                       public FileHeaderDTO call() throws Exception {
+                                       public FileHeader call() throws Exception {
                                                return getService().createFile(user.getId(), parentf.getId(), name, mimeType, uploadedf.getCanonicalFile().length(), uploadedf.getAbsolutePath());
                                        }
 
                                });
-            updateAccounting(owner, new Date(), fileDTO.getFileSize());
-                       getService().removeFileUploadProgress(user.getId(), fileDTO.getName());
+            updateAccounting(owner, new Date(), fileTemp.getCurrentBody().getFileSize());
+                       getService().removeFileUploadProgress(user.getId(), fileTemp.getName());
         } catch(ObjectNotFoundException e) {
             result = false;
         } catch (RpcException e) {
@@ -1836,16 +1836,16 @@ public class FilesHandler extends RequestHandler {
                return;
        }
 
-       FolderDTO folder = null;
-       FileHeaderDTO file = null;
-       if (object instanceof FolderDTO)
-               folder = (FolderDTO) object;
+       Folder folderLocal = null;
+       FileHeader fileLocal = null;
+       if (object instanceof Folder)
+               folderLocal = (Folder) object;
        else
-               file = (FileHeaderDTO) object;
+               fileLocal = (FileHeader) object;
 
-       if (file != null)
+       if (fileLocal != null)
                        try {
-                               final FileHeaderDTO f = file;
+                               final FileHeader f = fileLocal;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
@@ -1868,9 +1868,9 @@ public class FilesHandler extends RequestHandler {
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                        return;
                }
-               else if (folder != null)
+               else if (folderLocal != null)
                        try {
-                               final FolderDTO fo = folder;
+                               final Folder fo = folderLocal;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
@@ -1907,8 +1907,17 @@ public class FilesHandler extends RequestHandler {
         * @throws InsufficientPermissionsException if the user does not have
         *                      the necessary privileges to read the directory
      */
-    private InputStream renderJson(User user, FolderDTO folder) throws IOException,
+    private InputStream renderJson(User user, Folder folder) throws IOException,
                ServletException, InsufficientPermissionsException {
+       try {
+                       folder = getService().expandFolder(folder);
+               } catch (ObjectNotFoundException e1) {
+                       // TODO Auto-generated catch block
+                       e1.printStackTrace();
+               } catch (RpcException e1) {
+                       // TODO Auto-generated catch block
+                       e1.printStackTrace();
+               }
        JSONObject json = new JSONObject();
        try {
                        json.put("name", folder.getName()).
@@ -1929,7 +1938,7 @@ public class FilesHandler extends RequestHandler {
                                json.put("parent", j);
                        }
                List<JSONObject> subfolders = new ArrayList<JSONObject>();
-               for (FolderDTO f: folder.getSubfolders())
+               for (Folder f: folder.getSubfolders())
                                if (!f.isDeleted()) {
                                        JSONObject j = new JSONObject();
                                        j.put("name", f.getName()).
@@ -1938,15 +1947,15 @@ public class FilesHandler extends RequestHandler {
                                }
                json.put("folders", subfolders);
                List<JSONObject> files = new ArrayList<JSONObject>();
-               List<FileHeaderDTO> fileHeaders = getService().getFiles(user.getId(), folder.getId(), false);
-               for (FileHeaderDTO f: fileHeaders) {
+               List<FileHeader> fileHeaders = getService().getFiles(user.getId(), folder.getId(), false);
+               for (FileHeader f: fileHeaders) {
                        JSONObject j = new JSONObject();
                                j.put("name", f.getName()).
                                        put("owner", f.getOwner().getUsername()).
                                        put("deleted", f.isDeleted()).
-                                       put("version", f.getVersion()).
-                                       put("content", f.getMimeType()).
-                                       put("size", f.getFileSize()).
+                                       put("version", f.getCurrentBody().getVersion()).
+                                       put("content", f.getCurrentBody().getMimeType()).
+                                       put("size", f.getCurrentBody().getFileSize()).
                                        put("shared", f.getShared()).
                                        put("versioned",f.isVersioned()).
                                        put("creationDate", f.getAuditInfo().getCreationDate().getTime()).
@@ -1957,7 +1966,7 @@ public class FilesHandler extends RequestHandler {
                                files.add(j);
                }
                json.put("files", files);
-               Set<PermissionDTO> perms = getService().getFolderPermissions(user.getId(), folder.getId());
+               Set<Permission> perms = getService().getFolderPermissions(user.getId(), folder.getId());
                json.put("permissions", renderJson(perms));
                } catch (JSONException e) {
                        throw new ServletException(e);
@@ -1985,7 +1994,7 @@ public class FilesHandler extends RequestHandler {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
      */
-    private String renderJsonMetadata(User user, FolderDTO folder)
+    private String renderJsonMetadata(User user, Folder folder)
                throws ServletException, InsufficientPermissionsException {
        // Check if the user has read permission.
                try {
@@ -2029,18 +2038,19 @@ public class FilesHandler extends RequestHandler {
         * @throws InsufficientPermissionsException if the user does not have
         *                      the necessary privileges to read the directory
      */
-    private String renderJson(User user, FileHeaderDTO file, FileBodyDTO oldBody)
+    private String renderJson(User user, FileHeader file, FileBody oldBody)
                throws ServletException, InsufficientPermissionsException {
        JSONObject json = new JSONObject();
        try {
+               file=getService().expandFile(file);
                // Need to encode file name in order to properly display it in the web client.
                        json.put("name", URLEncoder.encode(file.getName(),"UTF-8")).
                                        put("owner", file.getOwner().getUsername()).
                                        put("versioned", file.isVersioned()).
-                                       put("version", oldBody != null ? oldBody.getVersion() : file.getVersion()).
+                                       put("version", oldBody != null ? oldBody.getVersion() : file.getCurrentBody().getVersion()).
                                        put("readForAll", file.isReadForAll()).
                                        put("shared", file.getShared()).
-                                       put("tags", renderJson(file.getTags())).
+                                       put("tags", renderJson(file.getFileTagsAsStrings())).
                                        put("path", file.getFolder().getPath()).
                                put("uri", getApiRoot() + file.getURI()).
                                        put("deleted", file.isDeleted());
@@ -2060,9 +2070,9 @@ public class FilesHandler extends RequestHandler {
                                                put("creationDate", file.getAuditInfo().getCreationDate().getTime()).
                                                put("modifiedBy", file.getAuditInfo().getModifiedBy().getUsername()).
                                                put("modificationDate", file.getAuditInfo().getModificationDate().getTime()).
-                                               put("content", file.getMimeType()).
-                                               put("size", file.getFileSize());
-               Set<PermissionDTO> perms = getService().getFilePermissions(user.getId(), file.getId());
+                                               put("content", file.getCurrentBody().getMimeType()).
+                                               put("size", file.getCurrentBody().getFileSize());
+               Set<Permission> perms = getService().getFilePermissions(user.getId(), file.getId());
                json.put("permissions", renderJson(perms));
                } catch (JSONException e) {
                        throw new ServletException(e);
@@ -2086,15 +2096,15 @@ public class FilesHandler extends RequestHandler {
         * @throws JSONException
         * @throws UnsupportedEncodingException
         */
-       private JSONArray renderJson(Set<PermissionDTO> permissions) throws JSONException, UnsupportedEncodingException {
+       private JSONArray renderJson(Set<Permission> permissions) throws JSONException, UnsupportedEncodingException {
                JSONArray perms = new JSONArray();
-               for (PermissionDTO p: permissions) {
+               for (Permission p: permissions) {
                        JSONObject permission = new JSONObject();
                        permission.put("read", p.hasRead()).put("write", p.hasWrite()).put("modifyACL", p.hasModifyACL());
                        if (p.getUser() != null)
                                permission.put("user", p.getUser().getUsername());
                        if (p.getGroup() != null) {
-                               GroupDTO group = p.getGroup();
+                               Group group = p.getGroup();
                                permission.put("groupUri", getApiRoot() + group.getOwner().getUsername() + PATH_GROUPS + "/" + URLEncoder.encode(group.getName(),"UTF-8"));
                                permission.put("group", URLEncoder.encode(p.getGroup().getName(),"UTF-8"));
                        }
@@ -2202,7 +2212,7 @@ public class FilesHandler extends RequestHandler {
         * @throws IOException
         * @throws ServletException
         */
-       private InputStream renderHtml(String contextPath, String path, FolderDTO folder, User user)
+       private InputStream renderHtml(String contextPath, String path, Folder folder, User user)
                throws IOException, ServletException {
                String name = folder.getName();
                // Prepare a writer to a buffered area
@@ -2268,7 +2278,7 @@ public class FilesHandler extends RequestHandler {
                boolean shade = false;
                Iterator iter = folder.getSubfolders().iterator();
                while (iter.hasNext()) {
-                       FolderDTO subf = (FolderDTO) iter.next();
+                       Folder subf = (Folder) iter.next();
                        if(subf.isReadForAll() && !subf.isDeleted()){
                                String resourceName = subf.getName();
                                if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
@@ -2302,7 +2312,7 @@ public class FilesHandler extends RequestHandler {
 
                        }
                }
-               List<FileHeaderDTO> files;
+               List<FileHeader> files;
                try {
                        files = getService().getFiles(user.getId(), folder.getId(), true);
                } catch (ObjectNotFoundException e) {
@@ -2312,7 +2322,7 @@ public class FilesHandler extends RequestHandler {
                } catch (RpcException e) {
                        throw new ServletException(e.getMessage());
                }
-               for (FileHeaderDTO file : files)
+               for (FileHeader file : files)
                //Display only file resources that are marked as public and are not deleted
                        if(file.isReadForAll() && !file.isDeleted()){
                                String resourceName = file.getName();
@@ -2334,7 +2344,7 @@ public class FilesHandler extends RequestHandler {
                                sb.append("</tt></a></td>\r\n");
 
                                sb.append("<td align=\"right\"><tt>");
-                               sb.append(renderSize(file.getFileSize()));
+                               sb.append(renderSize(file.getCurrentBody().getFileSize()));
                                sb.append("</tt></td>\r\n");
 
                                sb.append("<td align=\"right\"><tt>");
index bfbe658..a5847e1 100644 (file)
@@ -22,9 +22,8 @@ import gr.ebs.gss.client.exceptions.DuplicateNameException;
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.Group;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.UserDTO;
 import gr.ebs.gss.server.ejb.TransactionHelper;
 
 import java.io.IOException;
@@ -76,9 +75,9 @@ public class GroupsHandler extends RequestHandler {
        if (path.equals("/"))
                        // Request to serve all groups
                try {
-               List<GroupDTO> groups = getService().getGroups(owner.getId());
+               List<Group> groups = getService().getGroups(owner.getId());
                JSONArray json = new JSONArray();
-               for (GroupDTO group: groups) {
+               for (Group group: groups) {
                        JSONObject j = new JSONObject();
                        j.put("name", group.getName()).
                                put("uri", parentUrl + URLEncoder.encode(group.getName(),"UTF-8"));
@@ -111,8 +110,9 @@ public class GroupsHandler extends RequestHandler {
                                if (logger.isDebugEnabled())
                                        logger.debug("Serving member " + path.substring(slash + 1) +
                                                                " from group " + path.substring(0, slash));
-                               GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
-                               for (UserDTO u: group.getMembers())
+                               Group group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
+                               group = getService().expandGroup(group);
+                               for (User u: group.getMembers())
                                        if (u.getUsername().equals(path.substring(slash + 1))) {
                                                // Build the proper parent URL
                                                String pathInfo = req.getPathInfo();
@@ -127,9 +127,10 @@ public class GroupsHandler extends RequestHandler {
                                // Request to serve group
                                if (logger.isDebugEnabled())
                                        logger.debug("Serving group " + path);
-                               GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
+                               Group group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
+                               group = getService().expandGroup(group);
                                JSONArray json = new JSONArray();
-                               for (UserDTO u: group.getMembers())
+                               for (User u: group.getMembers())
                                        json.put(parentUrl + u.getUsername());
 
                                sendJson(req, resp, json.toString());
@@ -203,7 +204,7 @@ public class GroupsHandler extends RequestHandler {
                        if (logger.isDebugEnabled())
                                logger.debug("Adding member " + username +
                                                        " to group " + path);
-                       final GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
+                       final Group group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
                        final User member = getService().findUser(username);
                        if (member == null) {
                                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "User " + username + " not found");
@@ -270,8 +271,8 @@ public class GroupsHandler extends RequestHandler {
                        if (logger.isDebugEnabled())
                                logger.debug("Removing member " + path.substring(slash + 1) +
                                                        " from group " + path.substring(0, slash));
-                       final GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
-                       for (final UserDTO u: group.getMembers())
+                       final Group group = getService().getGroup(owner.getId(), URLDecoder.decode(path.substring(0, slash),"UTF-8"));
+                       for (final User u: group.getMembers())
                                if (u.getUsername().equals(path.substring(slash + 1)))
                                        new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                                @Override
@@ -283,7 +284,7 @@ public class GroupsHandler extends RequestHandler {
                } else {
                        if (logger.isDebugEnabled())
                                logger.debug("Removing group " + path);
-                               final GroupDTO group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
+                               final Group group = getService().getGroup(owner.getId(), URLDecoder.decode(path,"UTF-8"));
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
index db668ea..7b26592 100644 (file)
@@ -20,10 +20,9 @@ package gr.ebs.gss.server.rest;
 
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.UserDTO;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -74,8 +73,8 @@ public class OthersHandler extends RequestHandler {
                        // Request to retrieve the other users who have shared resources to this user
                        JSONArray json = new JSONArray();
 
-               List<UserDTO> others = getService().getUsersSharingFoldersForUser(owner.getId());
-                       for (UserDTO u: others) {
+               List<User> others = getService().getUsersSharingFoldersForUser(owner.getId());
+                       for (User u: others) {
                                JSONObject j = new JSONObject();
                                j.put("username", u.getUsername()).
                                        put("uri", parentUrl + u.getUsername());
@@ -108,8 +107,8 @@ public class OthersHandler extends RequestHandler {
                        JSONObject json = new JSONObject();
 
                                List<JSONObject> subfolders = new ArrayList<JSONObject>();
-               List<FolderDTO> folders = getService().getSharedRootFolders(other.getId(), owner.getId());
-                       for (FolderDTO f: folders) {
+               List<Folder> folders = getService().getSharedRootFolders(other.getId(), owner.getId());
+                       for (Folder f: folders) {
                                JSONObject j = new JSONObject();
                                j.put("name", f.getName()).
                                        put("uri", getApiRoot() + f.getURI());
@@ -118,15 +117,15 @@ public class OthersHandler extends RequestHandler {
                        json.put("folders", subfolders);
 
                List<JSONObject> files = new ArrayList<JSONObject>();
-               List<FileHeaderDTO> fileHeaders = getService().getSharedFiles(other.getId(), owner.getId());
-               for (FileHeaderDTO f: fileHeaders) {
+               List<FileHeader> fileHeaders = getService().getSharedFiles(other.getId(), owner.getId());
+               for (FileHeader f: fileHeaders) {
                        JSONObject j = new JSONObject();
                                j.put("name", f.getName()).
                                        put("owner", f.getOwner().getUsername()).
                                        put("deleted", f.isDeleted()).
-                                       put("version", f.getVersion()).
-                                       put("size", f.getFileSize()).
-                                       put("content", f.getMimeType()).
+                                       put("version", f.getCurrentBody().getVersion()).
+                                       put("size", f.getCurrentBody().getFileSize()).
+                                       put("content", f.getCurrentBody().getMimeType()).
                                        put("creationDate", f.getAuditInfo().getCreationDate().getTime()).
                                        put("modificationDate", f.getAuditInfo().getModificationDate().getTime()).
                                        put("path", f.getFolder().getPath()).
index 84270b6..df90cd7 100644 (file)
@@ -22,8 +22,8 @@ import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfigu
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
 import gr.ebs.gss.server.webdav.Webdav;
 
 import java.io.ByteArrayInputStream;
@@ -73,7 +73,7 @@ public class RequestHandler extends Webdav {
        /**
         * The path for the resource manipulation subsystem.
         */
-       protected static final String PATH_FILES = FileHeaderDTO.PATH_FILES;
+       protected static final String PATH_FILES = FileHeader.PATH_FILES;
 
        /**
         * The path for the trash virtual folder.
index 1b784fa..9a7d130 100644 (file)
@@ -21,9 +21,9 @@ package gr.ebs.gss.server.rest;
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
 
 import java.io.IOException;
 import java.net.URLEncoder;
@@ -73,8 +73,8 @@ public class SharedHandler extends RequestHandler {
                        JSONObject json = new JSONObject();
 
                                List<JSONObject> subfolders = new ArrayList<JSONObject>();
-               List<FolderDTO> folders = getService().getSharedRootFolders(owner.getId());
-               for (FolderDTO f: folders) {
+               List<Folder> folders = getService().getSharedRootFolders(owner.getId());
+               for (Folder f: folders) {
                                JSONObject j = new JSONObject();
                                j.put("name", f.getName()).
                                        put("uri", getApiRoot() + f.getURI());
@@ -84,16 +84,16 @@ public class SharedHandler extends RequestHandler {
                        }
                        json.put("folders", subfolders);
 
-               List<FileHeaderDTO> fileHeaders = getService().getSharedFilesNotInSharedFolders(owner.getId());
+               List<FileHeader> fileHeaders = getService().getSharedFilesNotInSharedFolders(owner.getId());
                List<JSONObject> files = new ArrayList<JSONObject>();
-               for (FileHeaderDTO f: fileHeaders) {
+               for (FileHeader f: fileHeaders) {
                        JSONObject j = new JSONObject();
                                j.put("name", f.getName()).
                                        put("owner", f.getOwner().getUsername()).
                                        put("deleted", f.isDeleted()).
-                                       put("version", f.getVersion()).
-                                       put("size", f.getFileSize()).
-                                       put("content", f.getMimeType()).
+                                       put("version", f.getCurrentBody().getVersion()).
+                                       put("size", f.getCurrentBody().getFileSize()).
+                                       put("content", f.getCurrentBody().getMimeType()).
                                        put("path", f.getFolder().getPath()).
                                        put("shared", f.getShared()).
                                        put("versioned",f.isVersioned()).
index 9930d72..ad89bba 100644 (file)
@@ -21,9 +21,9 @@ package gr.ebs.gss.server.rest;
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
 import gr.ebs.gss.server.ejb.TransactionHelper;
 
 import java.io.IOException;
@@ -71,8 +71,8 @@ public class TrashHandler extends RequestHandler {
                        return;
        }
 
-       List<FileHeaderDTO> files = null;
-               List<FolderDTO> folders = null;
+       List<FileHeader> files = null;
+               List<Folder> folders = null;
        User user = getUser(req);
        User owner = getOwner(req);
        if (!owner.equals(user)) {
@@ -99,7 +99,7 @@ public class TrashHandler extends RequestHandler {
                JSONObject json = new JSONObject();
        try {
                List<JSONObject> trashFolders = new ArrayList<JSONObject>();
-               for (FolderDTO f: folders) {
+               for (Folder f: folders) {
                        JSONObject j = new JSONObject();
                        j.put("name", f.getName()).
                                put("uri", getApiRoot() + f.getURI());
@@ -109,16 +109,16 @@ public class TrashHandler extends RequestHandler {
                }
                json.put("folders", trashFolders);
                List<JSONObject> trashFiles = new ArrayList<JSONObject>();
-               for (FileHeaderDTO f: files) {
+               for (FileHeader f: files) {
                        JSONObject j = new JSONObject();
                                j.put("name", f.getName()).
                                        put("owner", f.getOwner().getUsername()).
                                        put("deleted", f.isDeleted()).
-                                       put("version", f.getVersion()).
-                                       put("size", f.getFileSize()).
+                                       put("version", f.getCurrentBody().getVersion()).
+                                       put("size", f.getCurrentBody().getFileSize()).
+                                       put("content", f.getCurrentBody().getMimeType()).
                                        put("shared", f.getShared()).
                                    put("versioned",f.isVersioned()).
-                                       put("content", f.getMimeType()).
                                        put("path", f.getFolder().getPath()).
                                        put("creationDate", f.getAuditInfo().getCreationDate().getTime()).
                                        put("modificationDate", f.getAuditInfo().getModificationDate().getTime()).
index 0e5f530..914aee8 100644 (file)
@@ -19,7 +19,7 @@
 package gr.ebs.gss.server.rest;
 
 import gr.ebs.gss.client.exceptions.RpcException;
-import gr.ebs.gss.server.domain.dto.UserDTO;
+import gr.ebs.gss.server.domain.User;
 
 import java.io.IOException;
 import java.util.List;
@@ -71,29 +71,18 @@ public class UserSearchHandler extends RequestHandler {
                        try {
                        JSONArray json = new JSONArray();
 
-                       if (mustEndWithAt && !path.endsWith("@") && !path.contains("@")){
+                       if (mustEndWithAt && !path.endsWith("@"))
                                path += '@';
-                                       List<UserDTO> users = getService().getUsersByUserNameLike(path.substring(1));
-                                       for (UserDTO u: users) {
-                                               // Build the proper parent URL
-                                               String pathInfo = req.getPathInfo();
-                                               String parentUrl = contextPath.replaceFirst(pathInfo, "");
-                                               JSONObject j = new JSONObject();
-                                       j.put("username", u.getUsername()).put("name", u.getName()).
-                                               put("uri", parentUrl + "/" + u.getUsername());
-                                       json.put(j);
-                                       }
-                       }else if(path.contains("@")){
-                               path = path.substring(1,path.length());
-                               UserDTO user = getService().getUserByUserName(path);
-                               String pathInfo = req.getPathInfo();
+                               List<User> users = getService().getUsersByUserNameLike(path.substring(1));
+                       for (User u: users) {
+                                       // Build the proper parent URL
+                                       String pathInfo = req.getPathInfo();
                                        String parentUrl = contextPath.replaceFirst(pathInfo, "");
                                JSONObject j = new JSONObject();
-                               j.put("username", user.getUsername())
-                                               .put("name", user.getName())
-                                       .put("uri", parentUrl + "/" + user.getUsername());
+                               j.put("username", u.getUsername()).put("name", u.getName()).
+                                       put("uri", parentUrl + "/" + u.getUsername());
                                json.put(j);
-                               }
+                       }
                sendJson(req, resp, json.toString());
                // Workaround for IE's broken caching behavior.
                        resp.setHeader("Expires", "-1");
index 1b29beb..9d9ad9e 100644 (file)
@@ -25,11 +25,11 @@ import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
 import gr.ebs.gss.client.exceptions.QuotaExceededException;
 import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.AuditInfo;
+import gr.ebs.gss.server.domain.FileBody;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.AuditInfoDTO;
-import gr.ebs.gss.server.domain.dto.FileBodyDTO;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
 import gr.ebs.gss.server.ejb.ExternalAPI;
 import gr.ebs.gss.server.ejb.TransactionHelper;
 
@@ -586,13 +586,13 @@ public class Webdav extends HttpServlet {
                                        return;
                                }
                                parseProperties(req, generatedXML, currentPath, type, properties, object);
-                               if (object instanceof FolderDTO && depth > 0) {
-                                       FolderDTO folder = (FolderDTO) object;
+                               if (object instanceof Folder && depth > 0) {
+                                       Folder folderLocal = (Folder) object;
                                        // Retrieve the subfolders.
-                                       List subfolders = folder.getSubfolders();
+                                       List subfolders = folderLocal.getSubfolders();
                                        Iterator iter = subfolders.iterator();
                                        while (iter.hasNext()) {
-                                               FolderDTO f = (FolderDTO) iter.next();
+                                               Folder f = (Folder) iter.next();
                                                String newPath = currentPath;
                                                if (!newPath.endsWith("/"))
                                                        newPath += "/";
@@ -600,9 +600,9 @@ public class Webdav extends HttpServlet {
                                                stackBelow.push(newPath);
                                        }
                                        // Retrieve the files.
-                                       List<FileHeaderDTO> files;
+                                       List<FileHeader> files;
                                        try {
-                                               files = getService().getFiles(user.getId(), folder.getId(), true);
+                                               files = getService().getFiles(user.getId(), folderLocal.getId(), true);
                                        } catch (ObjectNotFoundException e) {
                                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                                                return;
@@ -613,7 +613,7 @@ public class Webdav extends HttpServlet {
                                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                                                return;
                                        }
-                                       for (FileHeaderDTO file : files) {
+                                       for (FileHeader file : files) {
                                                String newPath = currentPath;
                                                if (!newPath.endsWith("/"))
                                                        newPath += "/";
@@ -690,7 +690,7 @@ public class Webdav extends HttpServlet {
                String path = getRelativePath(req);
                boolean exists = true;
                Object resource = null;
-               FileHeaderDTO file = null;
+               FileHeader file = null;
                try {
                        resource = getService().getResourceAtPath(user.getId(), path, true);
                } catch (ObjectNotFoundException e) {
@@ -701,8 +701,8 @@ public class Webdav extends HttpServlet {
                }
 
                if (exists)
-                       if (resource instanceof FileHeaderDTO)
-                               file = (FileHeaderDTO) resource;
+                       if (resource instanceof FileHeader)
+                               file = (FileHeader) resource;
                        else {
                                resp.sendError(HttpServletResponse.SC_CONFLICT);
                                return;
@@ -739,11 +739,11 @@ public class Webdav extends HttpServlet {
 
                try {
                        Object parent = getService().getResourceAtPath(user.getId(), getParentPath(path), true);
-                       if (!(parent instanceof FolderDTO)) {
+                       if (!(parent instanceof Folder)) {
                                resp.sendError(HttpServletResponse.SC_CONFLICT);
                                return;
                        }
-                       final FolderDTO folder = (FolderDTO) parent;
+                       final Folder folderLocal = (Folder) parent;
                        final String name = getLastElement(path);
                        final String mimeType = getServletContext().getMimeType(name);
                File uploadedFile = null;
@@ -753,24 +753,24 @@ public class Webdav extends HttpServlet {
                                throw new GSSIOException(ex, false);
                        }
                        // FIXME: Add attributes
-                       FileHeaderDTO fileDTO = null;
-                       final FileHeaderDTO f = file;
+                       FileHeader fileLocal = null;
+                       final FileHeader f = file;
                        final File uf = uploadedFile;
                        if (exists)
-                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                               fileLocal = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
                                        @Override
-                                       public FileHeaderDTO call() throws Exception {
+                                       public FileHeader call() throws Exception {
                                                return getService().updateFileContents(user.getId(), f.getId(), mimeType, uf.length(), uf.getAbsolutePath());
                                        }
                                });
                        else
-                               fileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
+                               fileLocal = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
                                        @Override
-                                       public FileHeaderDTO call() throws Exception {
-                                               return getService().createFile(user.getId(), folder.getId(), name, mimeType, uf.length(), uf.getAbsolutePath());
+                                       public FileHeader call() throws Exception {
+                                               return getService().createFile(user.getId(), folderLocal.getId(), name, mimeType, uf.length(), uf.getAbsolutePath());
                                        }
                                });
-                       updateAccounting(user, new Date(), fileDTO.getFileSize());
+                       updateAccounting(user, new Date(), fileLocal.getCurrentBody().getFileSize());
                } catch (ObjectNotFoundException e) {
                        result = false;
                } catch (InsufficientPermissionsException e) {
@@ -1012,7 +1012,7 @@ public class Webdav extends HttpServlet {
                        String lockTokenStr = req.getServletPath() + "-" + lock.type + "-" + lock.scope + "-" + req.getUserPrincipal() + "-" + lock.depth + "-" + lock.owner + "-" + lock.tokens + "-" + lock.expiresAt + "-" + System.currentTimeMillis() + "-" + secret;
                        String lockToken = md5Encoder.encode(md5Helper.digest(lockTokenStr.getBytes()));
 
-                       if (exists && object instanceof FolderDTO && lock.depth == INFINITY)
+                       if (exists && object instanceof Folder && lock.depth == INFINITY)
                                // Locking a collection (and all its member resources)
                                lock.tokens.addElement(lockToken);
                        else {
@@ -1150,12 +1150,12 @@ public class Webdav extends HttpServlet {
                        return;
                }
                try {
-                       if (parent instanceof FolderDTO) {
-                               final FolderDTO folder = (FolderDTO) parent;
+                       if (parent instanceof Folder) {
+                               final Folder folderLocal = (Folder) parent;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().createFolder(user.getId(), folder.getId(), getLastElement(path));
+                                               getService().createFolder(user.getId(), folderLocal.getId(), getLastElement(path));
                                                return null;
                                        }
                                });
@@ -1322,24 +1322,24 @@ public class Webdav extends HttpServlet {
                if (path.toUpperCase().startsWith("/WEB-INF") || path.toUpperCase().startsWith("/META-INF"))
                        return;
 
-               FolderDTO folder = null;
-               FileHeaderDTO file = null;
-               if (resource instanceof FolderDTO)
-                       folder = (FolderDTO) resource;
+               Folder folderLocal = null;
+               FileHeader fileLocal = null;
+               if (resource instanceof Folder)
+                       folderLocal = (Folder) resource;
                else
-                       file = (FileHeaderDTO) resource;
+                       fileLocal = (FileHeader) resource;
                // Retrieve the creation date.
                long creation = 0;
-               if (folder != null)
-                       creation = folder.getAuditInfo().getCreationDate().getTime();
+               if (folderLocal != null)
+                       creation = folderLocal.getAuditInfo().getCreationDate().getTime();
                else
-                       creation = file.getAuditInfo().getCreationDate().getTime();
+                       creation = fileLocal.getAuditInfo().getCreationDate().getTime();
                // Retrieve the modification date.
                long modification = 0;
-               if (folder != null)
-                       modification = folder.getAuditInfo().getCreationDate().getTime();
+               if (folderLocal != null)
+                       modification = folderLocal.getAuditInfo().getCreationDate().getTime();
                else
-                       modification = file.getAuditInfo().getCreationDate().getTime();
+                       modification = fileLocal.getAuditInfo().getCreationDate().getTime();
 
                generatedXML.writeElement(null, "D:response", XMLWriter.OPENING);
                String status = new String("HTTP/1.1 " + WebdavStatus.SC_OK + " " + WebdavStatus.getStatusText(WebdavStatus.SC_OK));
@@ -1352,7 +1352,7 @@ public class Webdav extends HttpServlet {
                        href += path.substring(1);
                else
                        href += path;
-               if (folder != null && !href.endsWith("/"))
+               if (folderLocal != null && !href.endsWith("/"))
                        href += "/";
 
                generatedXML.writeText(rewriteUrl(href));
@@ -1377,13 +1377,13 @@ public class Webdav extends HttpServlet {
                                generatedXML.writeElement(null, "D:displayname", XMLWriter.OPENING);
                                generatedXML.writeData(resourceName);
                                generatedXML.writeElement(null, "D:displayname", XMLWriter.CLOSING);
-                               if (file != null) {
+                               if (fileLocal != null) {
                                        generatedXML.writeProperty(null, "D:getlastmodified", FastHttpDateFormat.formatDate(modification, null));
-                                       generatedXML.writeProperty(null, "D:getcontentlength", String.valueOf(file.getFileSize()));
-                                       String contentType = file.getMimeType();
+                                       generatedXML.writeProperty(null, "D:getcontentlength", String.valueOf(fileLocal.getCurrentBody().getFileSize()));
+                                       String contentType = fileLocal.getCurrentBody().getMimeType();
                                        if (contentType != null)
                                                generatedXML.writeProperty(null, "D:getcontenttype", contentType);
-                                       generatedXML.writeProperty(null, "D:getetag", getETag(file, null));
+                                       generatedXML.writeProperty(null, "D:getetag", getETag(fileLocal, null));
                                        generatedXML.writeElement(null, "D:resourcetype", XMLWriter.NO_CONTENT);
                                } else {
                                        generatedXML.writeElement(null, "D:resourcetype", XMLWriter.OPENING);
@@ -1415,7 +1415,7 @@ public class Webdav extends HttpServlet {
 
                                generatedXML.writeElement(null, "D:creationdate", XMLWriter.NO_CONTENT);
                                generatedXML.writeElement(null, "D:displayname", XMLWriter.NO_CONTENT);
-                               if (file != null) {
+                               if (fileLocal != null) {
                                        generatedXML.writeElement(null, "D:getcontentlanguage", XMLWriter.NO_CONTENT);
                                        generatedXML.writeElement(null, "D:getcontentlength", XMLWriter.NO_CONTENT);
                                        generatedXML.writeElement(null, "D:getcontenttype", XMLWriter.NO_CONTENT);
@@ -1456,35 +1456,35 @@ public class Webdav extends HttpServlet {
                                                generatedXML.writeData(resourceName);
                                                generatedXML.writeElement(null, "D:displayname", XMLWriter.CLOSING);
                                        } else if (property.equals("D:getcontentlanguage")) {
-                                               if (folder != null)
+                                               if (folderLocal != null)
                                                        propertiesNotFound.addElement(property);
                                                else
                                                        generatedXML.writeElement(null, "D:getcontentlanguage", XMLWriter.NO_CONTENT);
                                        } else if (property.equals("D:getcontentlength")) {
-                                               if (folder != null)
+                                               if (folderLocal != null)
                                                        propertiesNotFound.addElement(property);
                                                else
-                                                       generatedXML.writeProperty(null, "D:getcontentlength", String.valueOf(file.getFileSize()));
+                                                       generatedXML.writeProperty(null, "D:getcontentlength", String.valueOf(fileLocal.getCurrentBody().getFileSize()));
                                        } else if (property.equals("D:getcontenttype")) {
-                                               if (folder != null)
+                                               if (folderLocal != null)
                                                        propertiesNotFound.addElement(property);
                                                else
                                                        // XXX Once we properly store the MIME type in the
                                                        // file,
                                                        // retrieve it from there.
-                                                       generatedXML.writeProperty(null, "D:getcontenttype", getServletContext().getMimeType(file.getName()));
+                                                       generatedXML.writeProperty(null, "D:getcontenttype", getServletContext().getMimeType(fileLocal.getName()));
                                        } else if (property.equals("D:getetag")) {
-                                               if (folder != null)
+                                               if (folderLocal != null)
                                                        propertiesNotFound.addElement(property);
                                                else
-                                                       generatedXML.writeProperty(null, "D:getetag", getETag(file, null));
+                                                       generatedXML.writeProperty(null, "D:getetag", getETag(fileLocal, null));
                                        } else if (property.equals("D:getlastmodified")) {
-                                               if (folder != null)
+                                               if (folderLocal != null)
                                                        propertiesNotFound.addElement(property);
                                                else
                                                        generatedXML.writeProperty(null, "D:getlastmodified", FastHttpDateFormat.formatDate(modification, null));
                                        } else if (property.equals("D:resourcetype")) {
-                                               if (folder != null) {
+                                               if (folderLocal != null) {
                                                        generatedXML.writeElement(null, "D:resourcetype", XMLWriter.OPENING);
                                                        generatedXML.writeElement(null, "D:collection", XMLWriter.NO_CONTENT);
                                                        generatedXML.writeElement(null, "D:resourcetype", XMLWriter.CLOSING);
@@ -1539,13 +1539,13 @@ public class Webdav extends HttpServlet {
        /**
         * Get the ETag associated with a file.
         *
-        * @param file the FileHeaderDTO object for this file
+        * @param file the FileHeader object for this file
         * @param oldBody the old version of the file, if requested
         * @return a string containing the ETag
         */
-       protected String getETag(FileHeaderDTO file, FileBodyDTO oldBody) {
+       protected String getETag(FileHeader file, FileBody oldBody) {
                if (oldBody == null)
-                       return "\"" + file.getFileSize() + "-" + file.getAuditInfo().getModificationDate().getTime() + "\"";
+                       return "\"" + file.getCurrentBody().getFileSize() + "-" + file.getAuditInfo().getModificationDate().getTime() + "\"";
                return "\"" + oldBody.getFileSize() + "-" + oldBody.getAuditInfo().getModificationDate().getTime() + "\"";
        }
 
@@ -1635,7 +1635,7 @@ public class Webdav extends HttpServlet {
                methodsAllowed.append(", PROPPATCH, COPY, MOVE, LOCK, UNLOCK");
                methodsAllowed.append(", PROPFIND");
 
-               if (!(object instanceof FolderDTO))
+               if (!(object instanceof Folder))
                        methodsAllowed.append(", PUT");
 
                return methodsAllowed;
@@ -1755,11 +1755,11 @@ public class Webdav extends HttpServlet {
 
                User user = getUser(req);
                User owner = getOwner(req);
-               FileHeaderDTO oldResource = null;
+               FileHeader oldResource = null;
                try {
                        Object obj = getService().getResourceAtPath(owner.getId(), path, true);
-                       if (obj instanceof FileHeaderDTO)
-                               oldResource = (FileHeaderDTO) obj;
+                       if (obj instanceof FileHeader)
+                               oldResource = (FileHeader) obj;
                } catch (ObjectNotFoundException e) {
                        // Do nothing.
                }
@@ -1818,8 +1818,8 @@ public class Webdav extends HttpServlet {
                User user = getUser(req);
                boolean exists = true;
                Object resource = null;
-               FileHeaderDTO file = null;
-               FolderDTO folder = null;
+               FileHeader file = null;
+               Folder folder = null;
                try {
                        resource = getService().getResourceAtPath(user.getId(), path, true);
                } catch (ObjectNotFoundException e) {
@@ -1834,10 +1834,10 @@ public class Webdav extends HttpServlet {
                        return;
                }
 
-               if (resource instanceof FolderDTO)
-                       folder = (FolderDTO) resource;
+               if (resource instanceof Folder)
+                       folder = (Folder) resource;
                else
-                       file = (FileHeaderDTO) resource;
+                       file = (FileHeader) resource;
 
                // If the resource is not a collection, and the resource path
                // ends with "/" or "\", return NOT FOUND
@@ -1857,10 +1857,10 @@ public class Webdav extends HttpServlet {
                // Find content type.
                String contentType = null;
                if (file != null) {
-                       contentType = file.getMimeType();
+                       contentType = file.getCurrentBody().getMimeType();
                        if (contentType == null) {
                                contentType = getServletContext().getMimeType(file.getName());
-                               file.setMimeType(contentType);
+                               file.getCurrentBody().setMimeType(contentType);
                        }
                } else
                        contentType = "text/html;charset=UTF-8";
@@ -1878,7 +1878,7 @@ public class Webdav extends HttpServlet {
                        // Last-Modified header
                        resp.setHeader("Last-Modified", getLastModifiedHttp(file.getAuditInfo()));
                        // Get content length
-                       contentLength = file.getFileSize();
+                       contentLength = file.getCurrentBody().getFileSize();
                        // Special case for zero length files, which would cause a
                        // (silent) ISE when setting the output buffer size
                        if (contentLength == 0L)
@@ -1999,7 +1999,7 @@ public class Webdav extends HttpServlet {
         * @param auditInfo the audit info for the specified resource
         * @return the last modified date in HTTP format
         */
-       protected String getLastModifiedHttp(AuditInfoDTO auditInfo) {
+       protected String getLastModifiedHttp(AuditInfo auditInfo) {
                Date modifiedDate = auditInfo.getModificationDate();
                if (modifiedDate == null)
                        modifiedDate = auditInfo.getCreationDate();
@@ -2022,7 +2022,7 @@ public class Webdav extends HttpServlet {
         * @return Vector of ranges
         * @throws IOException
         */
-       protected ArrayList parseRange(HttpServletRequest request, HttpServletResponse response, FileHeaderDTO file, FileBodyDTO oldBody) throws IOException {
+       protected ArrayList parseRange(HttpServletRequest request, HttpServletResponse response, FileHeader file, FileBody oldBody) throws IOException {
                // Checking If-Range
                String headerValue = request.getHeader("If-Range");
                if (headerValue != null) {
@@ -2051,7 +2051,7 @@ public class Webdav extends HttpServlet {
                                return FULL;
                }
 
-               long fileLength = oldBody == null ? file.getFileSize() : oldBody.getFileSize();
+               long fileLength = oldBody == null ? file.getCurrentBody().getFileSize() : oldBody.getFileSize();
                if (fileLength == 0)
                        return null;
 
@@ -2136,7 +2136,7 @@ public class Webdav extends HttpServlet {
         * @throws IOException
         */
        protected boolean checkIfHeaders(HttpServletRequest request, HttpServletResponse response,
-                               FileHeaderDTO file, FileBodyDTO oldBody) throws IOException {
+                               FileHeader file, FileBody oldBody) throws IOException {
                // TODO : Checking the WebDAV If header
                return checkIfMatch(request, response, file, oldBody) &&
                                checkIfModifiedSince(request, response, file, oldBody) &&
@@ -2157,7 +2157,7 @@ public class Webdav extends HttpServlet {
         * @throws IOException
         */
        private boolean checkIfMatch(HttpServletRequest request, HttpServletResponse response,
-                               FileHeaderDTO file, FileBodyDTO oldBody) throws IOException {
+                               FileHeader file, FileBody oldBody) throws IOException {
                String eTag = getETag(file, oldBody);
                String headerValue = request.getHeader("If-Match");
                if (headerValue != null)
@@ -2191,7 +2191,7 @@ public class Webdav extends HttpServlet {
         *         processing is stopped
         */
        private boolean checkIfModifiedSince(HttpServletRequest request,
-                               HttpServletResponse response, FileHeaderDTO file, FileBodyDTO oldBody) {
+                               HttpServletResponse response, FileHeader file, FileBody oldBody) {
                try {
                        long headerValue = request.getDateHeader("If-Modified-Since");
                        long lastModified = oldBody == null ?
@@ -2226,7 +2226,7 @@ public class Webdav extends HttpServlet {
         * @throws IOException
         */
        private boolean checkIfNoneMatch(HttpServletRequest request,
-                               HttpServletResponse response, FileHeaderDTO file, FileBodyDTO oldBody)
+                               HttpServletResponse response, FileHeader file, FileBody oldBody)
                        throws IOException {
                String eTag = getETag(file, oldBody);
                String headerValue = request.getHeader("If-None-Match");
@@ -2270,7 +2270,7 @@ public class Webdav extends HttpServlet {
         * @throws IOException
         */
        private boolean checkIfUnmodifiedSince(HttpServletRequest request,
-                               HttpServletResponse response, FileHeaderDTO file, FileBodyDTO oldBody)
+                               HttpServletResponse response, FileHeader file, FileBody oldBody)
                        throws IOException {
                try {
                        long lastModified = oldBody == null ?
@@ -2305,8 +2305,8 @@ public class Webdav extends HttpServlet {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
         */
-       protected void copy(FileHeaderDTO file, InputStream is, ServletOutputStream ostream,
-                               HttpServletRequest req, FileBodyDTO oldBody) throws IOException,
+       protected void copy(FileHeader file, InputStream is, ServletOutputStream ostream,
+                               HttpServletRequest req, FileBody oldBody) throws IOException,
                                ObjectNotFoundException, InsufficientPermissionsException, RpcException {
                IOException exception = null;
                InputStream resourceInputStream = null;
@@ -2374,8 +2374,8 @@ public class Webdav extends HttpServlet {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
         */
-       protected void copy(FileHeaderDTO file, InputStream is, PrintWriter writer,
-                               HttpServletRequest req, FileBodyDTO oldBody) throws IOException,
+       protected void copy(FileHeader file, InputStream is, PrintWriter writer,
+                               HttpServletRequest req, FileBody oldBody) throws IOException,
                                ObjectNotFoundException, InsufficientPermissionsException, RpcException {
                IOException exception = null;
                
@@ -2447,8 +2447,8 @@ public class Webdav extends HttpServlet {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
         */
-       protected void copy(FileHeaderDTO file, PrintWriter writer, Iterator ranges,
-                               String contentType, HttpServletRequest req, FileBodyDTO oldBody)
+       protected void copy(FileHeader file, PrintWriter writer, Iterator ranges,
+                               String contentType, HttpServletRequest req, FileBody oldBody)
                        throws IOException, ObjectNotFoundException, InsufficientPermissionsException, RpcException {
                User user = getUser(req);
                IOException exception = null;
@@ -2579,8 +2579,8 @@ public class Webdav extends HttpServlet {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
         */
-       protected void copy(FileHeaderDTO file, ServletOutputStream ostream, Range range,
-                               HttpServletRequest req, FileBodyDTO oldBody) throws IOException,
+       protected void copy(FileHeader file, ServletOutputStream ostream, Range range,
+                               HttpServletRequest req, FileBody oldBody) throws IOException,
                                ObjectNotFoundException, InsufficientPermissionsException, RpcException {
                IOException exception = null;
                User user = getUser(req);
@@ -2611,8 +2611,8 @@ public class Webdav extends HttpServlet {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
         */
-       protected void copy(FileHeaderDTO file, PrintWriter writer, Range range,
-                               HttpServletRequest req, FileBodyDTO oldBody) throws IOException,
+       protected void copy(FileHeader file, PrintWriter writer, Range range,
+                               HttpServletRequest req, FileBody oldBody) throws IOException,
                                ObjectNotFoundException, InsufficientPermissionsException, RpcException {
                IOException exception = null;
                User user = getUser(req);
@@ -2649,9 +2649,9 @@ public class Webdav extends HttpServlet {
         * @throws InsufficientPermissionsException
         * @throws ObjectNotFoundException
         */
-       protected void copy(FileHeaderDTO file, ServletOutputStream ostream,
+       protected void copy(FileHeader file, ServletOutputStream ostream,
                                Iterator ranges, String contentType, HttpServletRequest req,
-                               FileBodyDTO oldBody) throws IOException, ObjectNotFoundException,
+                               FileBody oldBody) throws IOException, ObjectNotFoundException,
                                InsufficientPermissionsException, RpcException {
                IOException exception = null;
                User user = getUser(req);
@@ -2693,7 +2693,7 @@ public class Webdav extends HttpServlet {
         * @throws IOException
         * @throws ServletException
         */
-       private InputStream renderHtml(String contextPath, String path, FolderDTO folder, HttpServletRequest req) throws IOException, ServletException {
+       private InputStream renderHtml(String contextPath, String path, Folder folder, HttpServletRequest req) throws IOException, ServletException {
                String name = folder.getName();
                // Prepare a writer to a buffered area
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
@@ -2758,7 +2758,7 @@ public class Webdav extends HttpServlet {
                boolean shade = false;
                Iterator iter = folder.getSubfolders().iterator();
                while (iter.hasNext()) {
-                       FolderDTO subf = (FolderDTO) iter.next();
+                       Folder subf = (Folder) iter.next();
                        String resourceName = subf.getName();
                        if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
                                continue;
@@ -2789,7 +2789,7 @@ public class Webdav extends HttpServlet {
 
                        sb.append("</tr>\r\n");
                }
-               List<FileHeaderDTO> files;
+               List<FileHeader> files;
                try {
                        User user = getUser(req);
                        files = getService().getFiles(user.getId(), folder.getId(), true);
@@ -2800,8 +2800,8 @@ public class Webdav extends HttpServlet {
                } catch (RpcException e) {
                        throw new ServletException(e.getMessage());
                }
-               for (FileHeaderDTO file : files) {
-                       String resourceName = file.getName();
+               for (FileHeader fileLocal : files) {
+                       String resourceName = fileLocal.getName();
                        if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
                                continue;
 
@@ -2820,11 +2820,11 @@ public class Webdav extends HttpServlet {
                        sb.append("</tt></a></td>\r\n");
 
                        sb.append("<td align=\"right\"><tt>");
-                       sb.append(renderSize(file.getFileSize()));
+                       sb.append(renderSize(fileLocal.getCurrentBody().getFileSize()));
                        sb.append("</tt></td>\r\n");
 
                        sb.append("<td align=\"right\"><tt>");
-                       sb.append(getLastModifiedHttp(file.getAuditInfo()));
+                       sb.append(getLastModifiedHttp(fileLocal.getAuditInfo()));
                        sb.append("</tt></td>\r\n");
 
                        sb.append("</tr>\r\n");
@@ -3020,14 +3020,14 @@ public class Webdav extends HttpServlet {
                } catch (ObjectNotFoundException e) {
                }
 
-               if (object instanceof FolderDTO) {
-                       final FolderDTO folder = (FolderDTO) object;
+               if (object instanceof Folder) {
+                       final Folder folderLocal = (Folder) object;
                        try {
                                final String des = dest;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().copyFolder(user.getId(), folder.getId(), des);
+                                               getService().copyFolder(user.getId(), folderLocal.getId(), des);
                                                return null;
                                        }
                                });
@@ -3053,16 +3053,16 @@ public class Webdav extends HttpServlet {
                                if (!dest.endsWith("/"))
                                        newDest += "/";
                                // Recursively copy the subfolders.
-                               Iterator iter = folder.getSubfolders().iterator();
+                               Iterator iter = folderLocal.getSubfolders().iterator();
                                while (iter.hasNext()) {
-                                       FolderDTO subf = (FolderDTO) iter.next();
+                                       Folder subf = (Folder) iter.next();
                                        String resourceName = subf.getName();
                                        copyResource(errorList, newSource + resourceName, newDest + resourceName, req);
                                }
                                // Recursively copy the files.
-                               List<FileHeaderDTO> files;
-                               files = getService().getFiles(user.getId(), folder.getId(), true);
-                               for (FileHeaderDTO file : files) {
+                               List<FileHeader> files;
+                               files = getService().getFiles(user.getId(), folderLocal.getId(), true);
+                               for (FileHeader file : files) {
                                        String resourceName = file.getName();
                                        copyResource(errorList, newSource + resourceName, newDest + resourceName, req);
                                }
@@ -3077,14 +3077,14 @@ public class Webdav extends HttpServlet {
                                return false;
                        }
 
-               } else if (object instanceof FileHeaderDTO) {
-                       final FileHeaderDTO file = (FileHeaderDTO) object;
+               } else if (object instanceof FileHeader) {
+                       final FileHeader fileLocal = (FileHeader) object;
                        try {
                                final String des = dest;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
-                                               getService().copyFile(user.getId(), file.getId(), des);
+                                               getService().copyFile(user.getId(), fileLocal.getId(), des);
                                                return null;
                                        }
                                });
@@ -3173,16 +3173,16 @@ public class Webdav extends HttpServlet {
                        return false;
                }
 
-               FolderDTO folder = null;
-               FileHeaderDTO file = null;
-               if (object instanceof FolderDTO)
-                       folder = (FolderDTO) object;
+               Folder folderLocal = null;
+               FileHeader fileLocal = null;
+               if (object instanceof Folder)
+                       folderLocal = (Folder) object;
                else
-                       file = (FileHeaderDTO) object;
+                       fileLocal = (FileHeader) object;
 
-               if (file != null)
+               if (fileLocal != null)
                        try {
-                               final FileHeaderDTO f = file;
+                               final FileHeader f = fileLocal;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
@@ -3205,11 +3205,11 @@ public class Webdav extends HttpServlet {
                                resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                                return false;
                        }
-               else if (folder != null) {
+               else if (folderLocal != null) {
                        Hashtable<String, Integer> errorList = new Hashtable<String, Integer>();
-                       deleteCollection(req, folder, path, errorList);
+                       deleteCollection(req, folderLocal, path, errorList);
                        try {
-                               final FolderDTO f = folder;
+                               final Folder f = folderLocal;
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                        @Override
                                        public Void call() throws Exception {
@@ -3245,7 +3245,7 @@ public class Webdav extends HttpServlet {
         * @param path Path to the collection to be deleted
         * @param errorList Contains the list of the errors which occurred
         */
-       private void deleteCollection(HttpServletRequest req, FolderDTO folder, String path, Hashtable<String, Integer> errorList) {
+       private void deleteCollection(HttpServletRequest req, Folder folder, String path, Hashtable<String, Integer> errorList) {
 
                if (logger.isDebugEnabled())
                        logger.debug("Delete:" + path);
@@ -3265,7 +3265,7 @@ public class Webdav extends HttpServlet {
 
                Iterator iter = folder.getSubfolders().iterator();
                while (iter.hasNext()) {
-                       FolderDTO subf = (FolderDTO) iter.next();
+                       Folder subf = (Folder) iter.next();
                        String childName = path;
                        if (!childName.equals("/"))
                                childName += "/";
@@ -3277,14 +3277,14 @@ public class Webdav extends HttpServlet {
                                try {
                                        final User user = getUser(req);
                                        Object object = getService().getResourceAtPath(user.getId(), childName, true);
-                                       FolderDTO childFolder = null;
-                                       FileHeaderDTO childFile = null;
-                                       if (object instanceof FolderDTO)
-                                               childFolder = (FolderDTO) object;
+                                       Folder childFolder = null;
+                                       FileHeader childFile = null;
+                                       if (object instanceof Folder)
+                                               childFolder = (Folder) object;
                                        else
-                                               childFile = (FileHeaderDTO) object;
+                                               childFile = (FileHeader) object;
                                        if (childFolder != null) {
-                                               final FolderDTO cf = childFolder;
+                                               final Folder cf = childFolder;
                                                deleteCollection(req, childFolder, childName, errorList);
                                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                                        @Override
@@ -3294,7 +3294,7 @@ public class Webdav extends HttpServlet {
                                                        }
                                                });
                                        } else if (childFile != null) {
-                                               final FileHeaderDTO cf = childFile;
+                                               final FileHeader cf = childFile;
                                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
                                                        @Override
                                                        public Void call() throws Exception {
@@ -3429,7 +3429,7 @@ public class Webdav extends HttpServlet {
         *         processing is stopped
         */
        public boolean checkIfModifiedSince(HttpServletRequest request,
-                               HttpServletResponse response, FolderDTO folder) {
+                               HttpServletResponse response, Folder folder) {
                try {
                        long headerValue = request.getDateHeader("If-Modified-Since");
                        long lastModified = folder.getAuditInfo().getModificationDate().getTime();
diff --git a/src/gr/ebs/gss/server/webdav/login/GssWebDAVLoginModule.java b/src/gr/ebs/gss/server/webdav/login/GssWebDAVLoginModule.java
deleted file mode 100644 (file)
index 1e62c49..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*\r
- * Copyright 2005, 2008, 2009 Electronic Business Systems Ltd.\r
- *\r
- * This file is part of GSS.\r
- *\r
- * GSS is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * GSS is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with GSS.  If not, see <http://www.gnu.org/licenses/>.\r
- */\r
-package gr.ebs.gss.server.webdav.login;\r
-\r
-import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;\r
-import gr.ebs.gss.client.exceptions.RpcException;\r
-import gr.ebs.gss.server.domain.User;\r
-import gr.ebs.gss.server.domain.UserLogin;\r
-import gr.ebs.gss.server.ejb.ExternalAPI;\r
-import gr.ebs.gss.server.ejb.TransactionHelper;\r
-\r
-import java.io.UnsupportedEncodingException;\r
-import java.security.Principal;\r
-import java.security.acl.Group;\r
-import java.util.Date;\r
-import java.util.HashSet;\r
-import java.util.concurrent.Callable;\r
-\r
-import javax.naming.Context;\r
-import javax.naming.InitialContext;\r
-import javax.naming.NamingException;\r
-import javax.rmi.PortableRemoteObject;\r
-import javax.security.auth.login.FailedLoginException;\r
-import javax.security.auth.login.LoginException;\r
-\r
-import org.apache.commons.codec.binary.Base64;\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.jboss.security.auth.spi.UsernamePasswordLoginModule;\r
-\r
-\r
-/**\r
- * The custom login module for the GSS WebDAV implementation.\r
- */\r
-public class GssWebDAVLoginModule extends UsernamePasswordLoginModule {\r
-\r
-       /**\r
-        * Logger for this class\r
-        */\r
-       private static final Log logger = LogFactory.getLog(GssWebDAVLoginModule.class);\r
-\r
-       /**\r
-        * A helper method that retrieves a reference to the ExternalAPI bean and\r
-        * stores it for future use.\r
-        *\r
-        * @return an ExternalAPI instance\r
-        * @throws RpcException in case an error occurs\r
-        */\r
-       private ExternalAPI getService() throws RpcException {\r
-               try {\r
-                       final Context ctx = new InitialContext();\r
-                       final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));\r
-                       return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);\r
-               } catch (final NamingException e) {\r
-                       logger.error("Unable to retrieve the ExternalAPI EJB", e);\r
-                       throw new RpcException("An error occurred while contacting the naming service");\r
-               }\r
-       }\r
-\r
-       @Override\r
-       protected String getUsersPassword() throws LoginException {\r
-               String username = getUsername();\r
-               try {\r
-                       final User user = getService().findUser(username);\r
-                       if (user == null) throw new FailedLoginException("User '" + username + "' not found.");\r
-                       if (!user.isActive()) throw new FailedLoginException("User '" + username + "' is disabled.");\r
-                       if (user.getWebDAVPassword() != null && user.getWebDAVPassword().length() > 0)\r
-                               return user.getWebDAVPassword();\r
-                       // If no password has ever been generated, use token instead\r
-                       String tokenEncoded = new String(Base64.encodeBase64(user.getAuthToken()), "US-ASCII");\r
-                       user.setWebDAVPassword(tokenEncoded);\r
-                       new TransactionHelper<Void>().tryExecute(new Callable<Void>() {\r
-                               @Override\r
-                               public Void call() throws Exception {\r
-                                       getService().updateUser(user);\r
-                                       return null;\r
-                               }\r
-                       });\r
-                       return tokenEncoded;\r
-               } catch (RpcException e) {\r
-                       String error = "An error occurred while communicating with the service";\r
-                       logger.error(error, e);\r
-                       throw new LoginException(e.getMessage());\r
-               } catch (UnsupportedEncodingException e) {\r
-            logger.error("", e);\r
-            throw new LoginException(e.getMessage());\r
-               } catch (Exception e) {\r
-            logger.error("", e);\r
-                       throw new LoginException(e.getMessage());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Overrides parent's implementation by returning only the simpleUser\r
-        * role for any successful login.\r
-        *\r
-        * @return Group[] that contains only the authenticatedUser group (role)\r
-        * @throws LoginException\r
-        * @see org.jboss.security.auth.spi.AbstractServerLoginModule#getRoleSets()\r
-        */\r
-       @Override\r
-       protected Group[] getRoleSets() throws LoginException {\r
-               Principal principal;\r
-               try {\r
-                       principal = createIdentity("simpleUser");\r
-               } catch (Exception e) {\r
-                       logger.error("", e);\r
-                       throw new LoginException(e.getMessage());\r
-               }\r
-               Group rolesGroup = null;\r
-               rolesGroup = createGroup("Roles", new HashSet());\r
-               rolesGroup.addMember(principal);\r
-               Group[] roles = new Group[1];\r
-               roles[0] = rolesGroup;\r
-               // Update the last login.\r
-               try {\r
-                       new TransactionHelper<Void>().tryExecute(new Callable<Void>() {\r
-                               @Override\r
-                               public Void call() throws Exception {\r
-                                       User user = getService().findUser(getUsername());\r
-                                       UserLogin userLogin = new UserLogin();\r
-                                       userLogin.setLoginDate(new Date());\r
-                                       getService().addUserLogin(userLogin);\r
-                                       getService().updateUser(user);\r
-                                       return null;\r
-                               }\r
-                       });\r
-               } catch (Exception e) {\r
-                       logger.error("", e);\r
-                       throw new LoginException(e.getMessage());\r
-               }\r
-               return roles;\r
-       }\r
-\r
-}\r
diff --git a/src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java b/src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java
new file mode 100644 (file)
index 0000000..5d6a9fd
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.User;
+import gr.ebs.gss.server.ejb.ExternalAPI;
+import gr.ebs.gss.server.ejb.TransactionHelper;
+
+import java.util.Date;
+import java.util.concurrent.Callable;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.HttpManager;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.ResourceFactory;
+import com.bradmcevoy.http.SecurityManager;
+import com.ettrema.http.fs.LockManager;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GSSResourceFactory implements ResourceFactory {
+       private static final Logger log = LoggerFactory.getLogger(GSSResourceFactory.class);
+       
+       SecurityManager securityManager;
+    LockManager lockManager;
+    Long maxAgeSeconds;
+    String contextPath;
+    boolean allowDirectoryBrowsing;
+    String defaultPage;
+    HttpManager httpManager;
+       @Override
+       public Resource getResource(String host, String url) {
+               
+
+
+               log.debug("getResource: host: " + host + " - url:" + url);
+        url = stripContext(url);
+        if(url==null||url.trim().equals("")||url.equals("/")){
+               url="/";
+        }
+        /*//log.info("URL:"+url);
+        if(url.equals("/OthersShared")||url.equals("/OthersShared/")){
+               //log.info("[returning others]");
+               return new GssOthersResource(host, this);
+        }
+        if(url.startsWith("/OthersShared")){
+               
+        }*/
+        try {
+               User user =null;
+               if(HttpManager.request().getAuthorization()!=null && HttpManager.request().getAuthorization().getTag()==null){
+                       String username = HttpManager.request().getAuthorization().getUser();
+                       if(username !=null)
+                               user = getService().getUserByUserName(username);
+               }
+               else if(HttpManager.request().getAuthorization()!=null&&HttpManager.request().getAuthorization().getTag()!=null){
+                       user =(User) HttpManager.request().getAuthorization().getTag();
+               }
+       
+               if(user==null){
+                       //create a resource based on path if no resource exists at this path it will be handled by subsequent webdav method calls
+                               return new GssRootFolderResource(host, this, null,url);
+               }
+                       
+               Object r = getResourceGss(url,user);
+               if(r==null){
+                       
+                       return null;
+               }
+               if(r instanceof Folder){
+                       
+                       return new GssFolderResource(host, this,r ,user);
+               }
+               else
+                       return new GssFileResource(host, this,r,user);
+               } catch (RpcException e) {
+                       e.printStackTrace();
+               }
+               return null;
+    }
+       public Long maxAgeSeconds(GssResource resource) {
+        return maxAgeSeconds;
+    }
+       protected Object getResourceGss(String path, User user) throws RpcException{
+
+               if(user ==null){
+                       if(HttpManager.request().getAuthorization()!=null && HttpManager.request().getAuthorization().getTag()==null){
+                               String username = HttpManager.request().getAuthorization().getUser();
+                               if(username !=null)
+                                       user = getService().getUserByUserName(username);
+                       }
+                       else if(HttpManager.request().getAuthorization()!=null&&HttpManager.request().getAuthorization().getTag()!=null){
+                               user =(User) HttpManager.request().getAuthorization().getTag();
+                       }
+               }
+               
+               if(user==null){
+                       return null;
+               }
+               boolean exists = true;
+               Object resource = null;
+               try {
+                       resource = getService().getResourceAtPath(user.getId(), path, true);
+               } catch (ObjectNotFoundException e) {
+                       exists = false;
+               } catch (RpcException e) {
+                       
+                       return null;
+               }
+
+               if (!exists) {
+                       
+                       return null;
+               }
+               if(resource instanceof Folder){
+                       try {
+                               resource = getService().expandFolder((Folder) resource);
+                       } catch (ObjectNotFoundException e) {
+                               // TODO Auto-generated catch block
+                               return null;
+                       }
+               }
+               else if(resource instanceof FileHeader){
+                       try {
+                               resource = getService().expandFile((FileHeader) resource);
+                       } catch (ObjectNotFoundException e) {
+                               // TODO Auto-generated catch block
+                               return null;
+                       }
+               }
+               return resource;
+       }
+       
+       
+        private String stripContext( String url ) {
+               if( this.contextPath != null && contextPath.length() > 0 ) {
+                   url = url.replaceFirst( '/' + contextPath, "");
+                   log.debug( "stripped context: " + url);
+                   return url;
+               } else {
+                   return url;
+               }
+           }
+        
+        /**
+                * For a provided path, remove the last element and return the rest, that is
+                * the path of the parent folder.
+                *
+                * @param path the specified path
+                * @return the path of the parent folder
+                * @throws ObjectNotFoundException if the provided string contains no path
+                *             delimiters
+                */
+               protected String getParentPath(String path) throws ObjectNotFoundException {
+                       int lastDelimiter = path.lastIndexOf('/');
+                       if (lastDelimiter == 0)
+                               return "/";
+                       if (lastDelimiter == -1)
+                               // No path found.
+                               throw new ObjectNotFoundException("There is no parent in the path: " + path);
+                       else if (lastDelimiter < path.length() - 1)
+                               // Return the part before the delimiter.
+                               return path.substring(0, lastDelimiter);
+                       else {
+                               // Remove the trailing delimiter and then recurse.
+                               String strippedTrail = path.substring(0, lastDelimiter);
+                               return getParentPath(strippedTrail);
+                       }
+               }
+               
+               /**
+                * A helper method that retrieves a reference to the ExternalAPI bean and
+                * stores it for future use.
+                *
+                * @return an ExternalAPI instance
+                * @throws RpcException in case an error occurs
+                */
+               protected ExternalAPI getService() throws RpcException {
+                       try {
+                               final Context ctx = new InitialContext();
+                               final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
+                               return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
+                       } catch (final NamingException e) {
+                               log.error("Unable to retrieve the ExternalAPI EJB", e);
+                               throw new RpcException("An error occurred while contacting the naming service");
+                       }
+               }
+
+               private void updateAccounting(final User user, final Date date, final long bandwidthDiff) {
+                       try {
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                                       @Override
+                                       public Void call() throws Exception {
+                                               getService().updateAccounting(user, date, bandwidthDiff);
+                                               return null;
+                                       }
+                               });
+                       } catch (RuntimeException e) {
+                               throw e;
+                       } catch (Exception e) {
+                               // updateAccounting() doesn't throw any checked exceptions
+                               assert false;
+                       }
+               }
+
+               
+               /**
+                * Retrieve the securityManager.
+                *
+                * @return the securityManager
+                */
+               public SecurityManager getSecurityManager() {
+                       return securityManager;
+               }
+
+               
+               /**
+                * Retrieve the lockManager.
+                *
+                * @return the lockManager
+                */
+               public LockManager getLockManager() {
+                       return lockManager;
+               }
+
+               
+               /**
+                * Retrieve the maxAgeSeconds.
+                *
+                * @return the maxAgeSeconds
+                */
+               public Long getMaxAgeSeconds() {
+                       return maxAgeSeconds;
+               }
+
+               
+               /**
+                * Retrieve the contextPath.
+                *
+                * @return the contextPath
+                */
+               public String getContextPath() {
+                       return contextPath;
+               }
+
+               
+               /**
+                * Retrieve the allowDirectoryBrowsing.
+                *
+                * @return the allowDirectoryBrowsing
+                */
+               public boolean isAllowDirectoryBrowsing() {
+                       return allowDirectoryBrowsing;
+               }
+
+               
+               /**
+                * Retrieve the defaultPage.
+                *
+                * @return the defaultPage
+                */
+               public String getDefaultPage() {
+                       return defaultPage;
+               }
+               
+               public String getRealm(String host) {
+               return securityManager.getRealm(host);
+           }
+
+               
+               /**
+                * Modify the securityManager.
+                *
+                * @param securityManager the securityManager to set
+                */
+               public void setSecurityManager(SecurityManager securityManager) {
+                       this.securityManager = securityManager;
+               }
+
+               
+               /**
+                * Modify the lockManager.
+                *
+                * @param lockManager the lockManager to set
+                */
+               public void setLockManager(LockManager lockManager) {
+                       this.lockManager = lockManager;
+               }
+
+               
+               /**
+                * Modify the maxAgeSeconds.
+                *
+                * @param maxAgeSeconds the maxAgeSeconds to set
+                */
+               public void setMaxAgeSeconds(Long maxAgeSeconds) {
+                       this.maxAgeSeconds = maxAgeSeconds;
+               }
+
+               
+               /**
+                * Modify the contextPath.
+                *
+                * @param contextPath the contextPath to set
+                */
+               public void setContextPath(String contextPath) {
+                       this.contextPath = contextPath;
+               }
+
+               
+               /**
+                * Modify the defaultPage.
+                *
+                * @param defaultPage the defaultPage to set
+                */
+               public void setDefaultPage(String defaultPage) {
+                       this.defaultPage = defaultPage;
+               }
+               
+               
+               /**
+                * Retrieve the httpManager.
+                *
+                * @return the httpManager
+                */
+               public HttpManager getHttpManager() {
+                       return httpManager;
+               }
+               
+               
+               /**
+                * Modify the httpManager.
+                *
+                * @param httpManager the httpManager to set
+                */
+               public void setHttpManager(HttpManager httpManager) {
+                       this.httpManager = httpManager;
+               }
+               
+               
+       
+               public static String getUsernameFromAuthHeader(String header) {
+                       String first = header.split(",")[0];
+                       int indx = first.indexOf("\"");
+                       return first.substring(indx+1,first.length()-1);
+               }
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java b/src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java
new file mode 100644 (file)
index 0000000..d3f24a6
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.ejb.ExternalAPI;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.AuthenticationHandler;
+import com.bradmcevoy.http.AuthenticationService;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.http11.auth.BasicAuthHandler;
+import com.bradmcevoy.http.http11.auth.DigestAuthenticationHandler;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssAuthenticationService extends com.bradmcevoy.http.AuthenticationService{
+       private static final Logger log = LoggerFactory.getLogger( AuthenticationService.class );
+    private List<AuthenticationHandler> authenticationHandlers;
+    private List<AuthenticationHandler> extraHandlers;
+    private List<AuthenticationHandler> allHandlers;
+    private boolean disableBasic;
+    private boolean disableDigest;
+
+    /**
+     * Creates a AuthenticationService using the given handlers. Use this if
+     * you don't want the default of a BasicAuthHandler and a DigestAuthenticationHandler
+     *
+     * @param authenticationHandlers
+     */
+    public GssAuthenticationService( List<AuthenticationHandler> authenticationHandlers ) {
+        this.authenticationHandlers = authenticationHandlers;
+        setAllHandlers();
+    }
+
+
+    /**
+     * Creates with Basic and Digest handlers
+     *
+     */
+    public GssAuthenticationService() {
+        AuthenticationHandler digest = new com.bradmcevoy.http.http11.auth.DigestAuthenticationHandler();
+        AuthenticationHandler basic = new BasicAuthHandler();
+        authenticationHandlers = new ArrayList<AuthenticationHandler>();
+        authenticationHandlers.add( basic );
+        authenticationHandlers.add( digest );
+        setAllHandlers();
+    }
+
+    public void setDisableBasic( boolean b ) {
+        if( b ) {
+            Iterator<AuthenticationHandler> it = this.authenticationHandlers.iterator();
+            while( it.hasNext() ) {
+                AuthenticationHandler hnd = it.next();
+                if( hnd instanceof BasicAuthHandler ) {
+                    it.remove();
+                }
+            }
+        }
+        disableBasic = b;
+        setAllHandlers();
+    }
+
+    public boolean isDisableBasic() {
+        return disableBasic;
+    }
+
+    public void setDisableDigest( boolean b ) {
+        if( b ) {
+            Iterator<AuthenticationHandler> it = this.authenticationHandlers.iterator();
+            while( it.hasNext() ) {
+                AuthenticationHandler hnd = it.next();
+                if( hnd instanceof DigestAuthenticationHandler ) {
+                    it.remove();
+                }
+            }
+        }
+        disableDigest = b;
+        setAllHandlers();
+    }
+
+    public boolean isDisableDigest() {
+        return disableDigest;
+    }
+
+   
+    /**
+     * Generates a list of http authentication challenges, one for each
+     * supported authentication method, to be sent to the client.
+     *
+     * @param resource - the resoruce being requested
+     * @param request - the current request
+     * @return - a list of http challenges
+     */
+    public List<String> getChallenges( Resource resource, Request request ) {
+        List<String> challenges = new ArrayList<String>();
+        for( AuthenticationHandler h : allHandlers ) {
+            if( h.isCompatible( resource ) ) {
+                log.debug( "challenge for auth: " + h.getClass() );
+                String ch = h.getChallenge( resource, request );
+                challenges.add( ch );
+            } else {
+                log.debug( "not challenging for auth: " + h.getClass() + " for resource type: " + resource.getClass() );
+            }
+        }
+        return challenges;
+    }
+
+    public List<AuthenticationHandler> getAuthenticationHandlers() {
+        return allHandlers;
+    }
+
+    public List<AuthenticationHandler> getExtraHandlers() {
+        return extraHandlers;
+    }
+
+    public void setExtraHandlers( List<AuthenticationHandler> extraHandlers ) {
+        this.extraHandlers = extraHandlers;
+        setAllHandlers();
+    }
+
+    /**
+     * Merge standard and extra handlers into single list
+     */
+    private void setAllHandlers() {
+        List<AuthenticationHandler> handlers = new ArrayList<AuthenticationHandler>();
+        if( authenticationHandlers != null ) {
+            handlers.addAll( authenticationHandlers );
+        }
+        if( extraHandlers != null ) {
+            handlers.addAll( extraHandlers );
+        }
+        this.allHandlers = Collections.unmodifiableList( handlers );
+    }
+
+    
+       public AuthStatus authenticate( Resource resource, Request request ) {
+        log.trace( "authenticate" );
+        Auth auth = request.getAuthorization();
+        boolean preAuthenticated = ( auth != null && auth.getTag() != null );
+        if( preAuthenticated ) {
+            log.trace( "request is pre-authenticated" );
+            return new AuthStatus( auth, false );
+        }
+        for( AuthenticationHandler h : getAuthenticationHandlers() ) {
+            if( h.supports( resource, request ) ) {
+                Object loginToken = h.authenticate( resource, request );
+                if( loginToken == null ) {
+                    log.warn( "authentication failed by AuthenticationHandler:" + h.getClass() );
+                    return new AuthStatus( auth, true );
+                } else {
+                    if( log.isTraceEnabled() ) {
+                        log.trace( "authentication passed by: " + h.getClass() );
+                    }
+                    if( auth == null ) { // some authentication handlers do not require an Auth object
+                        auth = new Auth( Auth.Scheme.FORM, null, loginToken );
+                        request.setAuthorization( auth );
+                    }
+                    auth.setTag( loginToken );
+                }
+                return new AuthStatus( auth, false );
+            }
+        }
+        return null;
+    }
+       
+       /**
+        * A helper method that retrieves a reference to the ExternalAPI bean and
+        * stores it for future use.
+        *
+        * @return an ExternalAPI instance
+        * @throws RpcException in case an error occurs
+        */
+       protected ExternalAPI getService() throws RpcException {
+               try {
+                       final Context ctx = new InitialContext();
+                       final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
+                       return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
+               } catch (final NamingException e) {
+                       log.error("Unable to retrieve the ExternalAPI EJB", e);
+                       throw new RpcException("An error occurred while contacting the naming service");
+               }
+       }
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssFileResource.java b/src/gr/ebs/gss/server/webdav/milton/GssFileResource.java
new file mode 100644 (file)
index 0000000..0aa37ae
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.client.exceptions.DuplicateNameException;
+import gr.ebs.gss.client.exceptions.GSSIOException;
+import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
+import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.User;
+import gr.ebs.gss.server.ejb.TransactionHelper;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.commons.io.IOUtils;
+import org.jboss.remoting.transport.coyote.ClientAbortException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.MoveableResource;
+import com.bradmcevoy.http.PropFindableResource;
+import com.bradmcevoy.http.PropPatchableResource;
+import com.bradmcevoy.http.Range;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.exceptions.BadRequestException;
+import com.bradmcevoy.http.exceptions.ConflictException;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.bradmcevoy.http.webdav.PropPatchHandler.Fields;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssFileResource extends GssResource implements CopyableResource, DeletableResource, GetableResource, MoveableResource, PropFindableResource, PropPatchableResource {
+       /**
+        * Size of file transfer buffer in bytes.
+        */
+       private static final int BUFFER_SIZE = 4096;
+
+       /**
+        * The output buffer size to use when serving resources.
+        */
+       protected int output = 2048;
+
+       /**
+        * The input buffer size to use when serving resources.
+        */
+       private int input = 2048;
+       
+       FileHeader file;
+       private static final Logger log = LoggerFactory.getLogger(GssFileResource.class);
+       /**
+        * @param host
+        * @param factory
+        * @param resource
+        */
+       public GssFileResource(String host, GSSResourceFactory factory, Object resource, User currentUser) {
+               super(host, factory, resource);
+               this.file = (FileHeader) resource;
+               this.currentUser = currentUser;
+               
+       }
+       @Override
+       public String checkRedirect(Request arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+       @Override
+       public Date getModifiedDate() {
+               return file.getAuditInfo().getModificationDate();
+       }
+       @Override
+       public String getName() {
+               return file.getName();
+       }
+       @Override
+       public String getUniqueId() {
+               return "file:"+file.getId().toString();
+       }
+       @Override
+       public void moveTo(final CollectionResource newParent, final String arg1) throws ConflictException, NotAuthorizedException, BadRequestException {
+               if( newParent instanceof GssFolderResource ) {
+                       final GssFolderResource newFsParent = (GssFolderResource) newParent;
+                       try {
+                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+
+                                       @Override
+                                       public Void call() throws Exception {
+                                               if(newFsParent.folder.getId().equals(file.getFolder().getId())){
+                                                       factory.getService().updateFile(getCurrentUser().getId(), file.getId(), arg1, null, new Date(), null, null, null);
+                                               }
+                                               else{
+                                                       factory.getService().moveFile(getCurrentUser().getId(), file.getId(), newFsParent.folder.getId(), arg1);
+                                               }
+                                               return null;
+                                       }
+                                       
+                               });
+                               GssFileResource.this.file = factory.getService().getFile(getCurrentUser().getId(), file.getId());
+                               
+                       } catch (InsufficientPermissionsException e) {
+                               throw new NotAuthorizedException(this);
+                       } catch (ObjectNotFoundException e) {
+                               throw new BadRequestException(this);
+                       } catch (DuplicateNameException e) {
+                               throw new ConflictException(this);
+                       } catch (RpcException e) {
+                               throw new RuntimeException("System error");
+                       } catch (GSSIOException e) {
+                               throw new RuntimeException("Unable to Move");
+                       } catch (Exception e) {
+                               throw new RuntimeException("Unable to Move");
+                       }
+        } else {
+            throw new RuntimeException("Destination is an unknown type. Must be a Folder, is a: " + newParent.getClass());
+        }
+               
+       }
+       @Override
+       public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
+               if( newParent instanceof GssFolderResource ) {                  
+                       final GssFolderResource newFsParent = (GssFolderResource) newParent;
+                       try {
+                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+
+                                       @Override
+                                       public Void call() throws Exception {
+                                               factory.getService().copyFile(getCurrentUser().getId(), file.getId(), newFsParent.folder.getId(), arg1);
+                                               return null;
+                                       }
+                                       
+                               });
+                                GssFileResource.this.file = factory.getService().getFile(getCurrentUser().getId(), file.getId());
+                       } catch (InsufficientPermissionsException e) {
+                               throw new NotAuthorizedException(this);
+                       } catch (ObjectNotFoundException e) {
+                               throw new BadRequestException(this);
+                       } catch (DuplicateNameException e) {
+                               throw new ConflictException(this);
+                       } catch (RpcException e) {
+                               throw new RuntimeException("System error");
+                       } catch (GSSIOException e) {
+                               throw new RuntimeException("Unable to Move");
+                       } catch (Exception e) {
+                               throw new RuntimeException("Unable to Move");
+                       }
+        } else {
+            throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
+        }
+               
+       }
+       @Override
+       public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
+               try {
+                       new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+
+                               @Override
+                               public Void call() throws Exception {
+                                       factory.getService().deleteFile(getCurrentUser().getId(), file.getId());
+                                       return null;
+                               }
+                       });
+               } catch (ObjectNotFoundException e) {
+                       throw new BadRequestException(this);                    
+               } catch (InsufficientPermissionsException e) {
+                       throw new NotAuthorizedException(this);
+               } catch (RpcException e) {
+                       throw new BadRequestException(this);
+               }
+               catch (Exception e) {
+                       e.printStackTrace();
+                       throw new BadRequestException(this);
+               }
+       }
+       @Override
+       public Long getContentLength() {
+               return file.getCurrentBody().getFileSize();
+       }
+       @Override
+       public String getContentType(String preferredList ) {
+        return file.getCurrentBody().getMimeType();
+       }
+       @Override
+       public Long getMaxAgeSeconds(Auth arg0) {
+               return factory.maxAgeSeconds( this );
+       }
+       @Override
+       public void sendContent(OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException {
+        InputStream in = null;
+        try {
+            in = factory.getService().getFileContents(getCurrentUser().getId(), file.getId());
+            if( range != null ) {
+               copy(in, out, range);
+            } else {
+               copyRange(in, out);
+            }
+            out.flush();
+            IOUtils.closeQuietly( in );
+        } catch (ObjectNotFoundException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (InsufficientPermissionsException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } 
+               catch(ClientAbortException ex){
+                       //do nothing
+               }
+               finally {
+            IOUtils.closeQuietly( in );
+        }
+               
+       }
+       
+       protected void copy(InputStream resourceInputStream, OutputStream ostream, Range range) throws IOException {
+               IOException exception = null;
+               InputStream istream = new BufferedInputStream(resourceInputStream, input);
+               exception = copyRange(istream, ostream, range.getStart(), range.getFinish());
+               // Clean up the input stream
+               istream.close();
+               // Rethrow any exception that has occurred
+               if (exception != null)
+                       throw exception;
+       }
+       protected void copy(InputStream resourceInputStream, OutputStream ostream) throws IOException{
+               IOException exception = null;
+               InputStream istream = new BufferedInputStream(resourceInputStream, input);
+               // Copy the input stream to the output stream
+               exception = copyRange(istream, ostream);
+               // Clean up the input stream
+               istream.close();
+               // Rethrow any exception that has occurred
+               if (exception != null)
+                       throw exception;
+       }
+       
+       private IOException copyRange(InputStream istream, OutputStream ostream) {
+               // Copy the input stream to the output stream
+               IOException exception = null;
+               byte buffer[] = new byte[input];
+               int len = buffer.length;
+               while (true)
+                       try {
+                               len = istream.read(buffer);
+                               if (len == -1)
+                                       break;
+                               ostream.write(buffer, 0, len);
+                       } catch (IOException e) {
+                               exception = e;
+                               len = -1;
+                               break;
+                       }
+               return exception;
+       }
+       
+       private IOException copyRange(InputStream istream, OutputStream ostream, long start, long end) {
+               log.debug("Serving bytes:" + start + "-" + end);
+               try {
+                       istream.skip(start);
+               } catch (IOException e) {
+                       return e;
+               }
+               IOException exception = null;
+               long bytesToRead = end - start + 1;
+               byte buffer[] = new byte[input];
+               int len = buffer.length;
+               while (bytesToRead > 0 && len >= buffer.length) {
+                       try {
+                               len = istream.read(buffer);
+                               if (bytesToRead >= len) {
+                                       ostream.write(buffer, 0, len);
+                                       bytesToRead -= len;
+                               } else {
+                                       ostream.write(buffer, 0, (int) bytesToRead);
+                                       bytesToRead = 0;
+                               }
+                       } catch (IOException e) {
+                               exception = e;
+                               len = -1;
+                       }
+                       if (len < buffer.length)
+                               break;
+               }
+               return exception;
+       }
+       @Override
+       public Date getCreateDate() {
+               // TODO Auto-generated method stub
+               return file.getAuditInfo().getCreationDate();
+       }
+       @Override
+       public void setProperties(Fields arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+       
+       
+       @Override
+       public boolean authorise(Request request, Method method, Auth auth) {
+        boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
+        if(result){
+               User user = getCurrentUser();
+               //check permission
+               try {
+                               factory.getService().getFile(user.getId(), file.getId());
+                       } catch (ObjectNotFoundException e) {
+                               return false;
+                       } catch (InsufficientPermissionsException e) {
+                               return false;
+                       } catch (RpcException e) {
+                               return false;
+                       }
+                       return true;
+        }
+        return result;
+    }
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java b/src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java
new file mode 100644 (file)
index 0000000..a73a902
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.client.exceptions.DuplicateNameException;
+import gr.ebs.gss.client.exceptions.GSSIOException;
+import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
+import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.client.exceptions.QuotaExceededException;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.User;
+import gr.ebs.gss.server.ejb.TransactionHelper;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.QuotaResource;
+import com.bradmcevoy.http.Range;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.XmlWriter;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.exceptions.BadRequestException;
+import com.bradmcevoy.http.exceptions.ConflictException;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssFolderResource extends GssResource implements MakeCollectionableResource, PutableResource, CopyableResource, DeletableResource, MoveableResource, PropFindableResource, LockingCollectionResource, GetableResource, QuotaResource{
+        private static final Logger log = LoggerFactory.getLogger(GssFolderResource.class);
+       Folder folder;
+       
+       /**
+        * @param host
+        * @param factory
+        * @param resource
+        */
+       public GssFolderResource(String host, GSSResourceFactory factory, Object resource, User currentUser) {
+               super(host, factory, resource);
+               folder=(Folder) resource;
+               this.currentUser=currentUser;
+       }
+       @Override
+       public String checkRedirect(Request request) {
+               if( factory.getDefaultPage() != null ) {
+            return request.getAbsoluteUrl() + "/" + factory.getDefaultPage();
+        } else {
+            return null;
+        }
+       }
+       @Override
+       public Date getModifiedDate() {
+               if(folder!=null && folder.getAuditInfo()!=null)
+                       return folder.getAuditInfo().getModificationDate();
+               return null;
+       }
+       @Override
+       public String getName() {
+               return folder.getName();
+       }
+       @Override
+       public String getUniqueId() {
+               return "folder:"+folder.getId().toString();
+       }
+       @Override
+       public void moveTo(final CollectionResource newParent, final String arg1) throws ConflictException, NotAuthorizedException, BadRequestException {
+               if( newParent instanceof GssFolderResource ) {
+                       final GssFolderResource newFsParent = (GssFolderResource) newParent;
+                       try {
+                               if(newFsParent.folder.getName().equals(folder.getParent().getName())){
+                                       if(!folder.getName().equals(arg1))
+                                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+       
+                                                       @Override
+                                                       public Void call() throws Exception {
+                                                               factory.getService().updateFolder(getCurrentUser().getId(), folder.getId(), arg1, null, null);
+                                                               return null;
+                                                       }
+                                                       
+                                               });
+                               }
+                               else new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+
+                                       @Override
+                                       public Void call() throws Exception {
+                                               factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);                                            
+                                               return null;
+                                       }
+                                       
+                               });
+                               GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
+                               
+                       } catch (InsufficientPermissionsException e) {
+                               throw new NotAuthorizedException(this);
+                       } catch (ObjectNotFoundException e) {
+                               throw new BadRequestException(this);
+                       } catch (DuplicateNameException e) {
+                               throw new ConflictException(this);
+                       } catch (RpcException e) {
+                               throw new RuntimeException("System error");
+                       } catch (GSSIOException e) {
+                               throw new RuntimeException("Unable to Move");
+                       } catch (Exception e) {
+                               throw new RuntimeException("Unable to Move");
+                       }
+        } else {
+            throw new RuntimeException("Destination is an unknown type. Must be a Folder, is a: " + newParent.getClass());
+        }
+               
+       }
+       @Override
+       public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
+               if( newParent instanceof GssFolderResource ) {                  
+                       final GssFolderResource newFsParent = (GssFolderResource) newParent;
+                       try {
+                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+
+                                       @Override
+                                       public Void call() throws Exception {
+                                               factory.getService().copyFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
+                                               return null;
+                                       }
+                                       
+                               });
+                               GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
+                       } catch (InsufficientPermissionsException e) {
+                               throw new NotAuthorizedException(this);
+                       } catch (ObjectNotFoundException e) {
+                               throw new BadRequestException(this);
+                       } catch (DuplicateNameException e) {
+                               throw new ConflictException(this);
+                       } catch (RpcException e) {
+                               throw new RuntimeException("System error");
+                       } catch (GSSIOException e) {
+                               throw new RuntimeException("Unable to Move");
+                       } catch (Exception e) {
+                               throw new RuntimeException("Unable to Move");
+                       }
+        } else {
+            throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
+        }
+               
+       }
+       @Override
+       public CollectionResource createCollection(final String name) throws NotAuthorizedException, ConflictException, BadRequestException {
+               ////log.info("CALLING CREATECOLLECTION:"+name);
+               try {
+                       final Folder folderParent = folder;
+                       Folder created = new TransactionHelper<Folder>().tryExecute(new Callable<Folder>() {
+                               @Override
+                               public Folder call() throws Exception {
+                                       Folder f = factory.getService().createFolder(getCurrentUser().getId(), folder.getId(), name);
+                                       return f;
+                               }
+                       });
+                       return new GssFolderResource(host, factory, created, getCurrentUser());
+               } catch (DuplicateNameException e) {
+                       e.printStackTrace();
+                       // XXX If the existing name is a folder we should be returning
+                       // SC_METHOD_NOT_ALLOWED, or even better, just do the createFolder
+                       // without checking first and then deal with the exceptions.
+                       throw new ConflictException(this);
+               } catch (InsufficientPermissionsException e) {
+                       e.printStackTrace();
+                       throw new NotAuthorizedException(this);
+               } catch (ObjectNotFoundException e) {
+                       e.printStackTrace();
+                       return null;
+               } catch (RpcException e) {
+                       e.printStackTrace();
+                       throw new RuntimeException("System Error");
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       throw new RuntimeException("System Error");
+               }
+       }
+       @Override
+       public Resource child(String name) {
+               for(Folder f : folder.getSubfolders())
+                       if(f.getName().equals(name))
+                               return new GssFolderResource(host, factory, f, getCurrentUser());
+               
+                       try {
+                               for(FileHeader f : factory.getService().getFiles(folder.getOwner().getId(), folder.getId(), true))
+                                       if(f.getName().equals(name))
+                                               return new GssFileResource(host, factory, f,getCurrentUser());
+                       } catch (ObjectNotFoundException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       } catch (InsufficientPermissionsException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+           ////log.info("CALLING CHILD return null");
+               return null;
+       }
+       @Override
+       public List<? extends Resource> getChildren() {
+               try {
+                       this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
+               } catch (ObjectNotFoundException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (InsufficientPermissionsException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               List<GssResource> result = new ArrayList<GssResource>();
+               for(Folder f : folder.getSubfolders())
+                       if(!f.isDeleted())
+                               result.add(new GssFolderResource(host, factory, f, getCurrentUser()));
+               try {
+                       for(FileHeader f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
+                               result.add(new GssFileResource(host, factory, f,getCurrentUser()));
+               } catch (ObjectNotFoundException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (InsufficientPermissionsException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               return result;
+       }
+       @Override
+       public Resource createNew(final String name, InputStream in, Long length, final String contentType ) throws IOException, ConflictException, NotAuthorizedException, BadRequestException {
+               
+       File uploadedFile = null;
+       try {
+                       uploadedFile = factory.getService().uploadFile(in, getCurrentUser().getId());
+               } catch (IOException ex) {
+                       throw new IOException(ex);
+               } catch (ObjectNotFoundException e) {
+                       e.printStackTrace();
+                       throw new BadRequestException(this);
+               } catch (RpcException e) {
+                       throw new RuntimeException("Unable to upload file");                    
+               }
+               final File uf = uploadedFile;
+               try {
+                       String pathFolder = folder.getPath();
+                       if(!pathFolder.endsWith("/"))
+                               pathFolder=pathFolder+"/";
+                       String fname = pathFolder+name;
+                       ////log.info("fname:"+fname+" "+URLDecoder.decode(fname));
+                       Object ff2;
+                       try{
+                               ff2 = factory.getService().getResourceAtPath(folder.getOwner().getId(), URLDecoder.decode(fname), true);
+                       }
+                       catch(ObjectNotFoundException ex){
+                               ff2=null;
+                       }
+                       final Object ff = ff2;
+                       FileHeader kmfile = null;
+                       if(ff != null && ff instanceof FileHeader){
+                               kmfile = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
+                                       @Override
+                                       public FileHeader call()  throws Exception{
+                                               return factory.getService().updateFileContents(getCurrentUser().getId(), ((FileHeader)ff).getId(),  contentType, uf.length(), uf.getAbsolutePath());
+                                       }
+                               });
+                       }
+                       else
+                               kmfile = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
+                                       @Override
+                                       public FileHeader call() throws Exception{
+                                               return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, contentType, uf.length(), uf.getAbsolutePath());
+                                       }
+                               });
+                       return new GssFileResource(host, factory, kmfile, getCurrentUser());
+               } catch (ObjectNotFoundException e) {
+                       e.printStackTrace();
+                       throw new BadRequestException(this);
+               } catch (InsufficientPermissionsException e) {
+                       e.printStackTrace();
+                       throw new NotAuthorizedException(this);
+               }
+               catch (DuplicateNameException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       throw new ConflictException(this);
+               }
+               catch(QuotaExceededException e){
+                       e.printStackTrace();
+                       throw new ConflictException(this);
+               }
+               catch(Exception e){
+                       e.printStackTrace();
+                       throw new RuntimeException("System Error");
+               }
+       }
+       @Override
+       public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
+               try {
+                       
+                               new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+
+                                       @Override
+                                       public Void call() throws Exception {
+                                               factory.getService().deleteFolder(getCurrentUser().getId(), folder.getId());
+                                               return  null;
+                                       }
+                               });
+                        
+               } catch (InsufficientPermissionsException e) {
+                       e.printStackTrace();
+                       throw new NotAuthorizedException(this);
+               } catch (ObjectNotFoundException e) {
+                       e.printStackTrace();
+                       throw new BadRequestException(this);
+               } catch (RpcException e) {
+                       e.printStackTrace();
+                       throw new BadRequestException(this);
+               }
+               catch (Exception e) {
+                       e.printStackTrace();
+                       throw new BadRequestException(this);
+               }
+       }
+       @Override
+       public Date getCreateDate() {
+               if(folder!=null && folder.getAuditInfo()!=null)
+                       return folder.getAuditInfo().getCreationDate();
+               return null;
+       }
+       @Override
+       public LockToken createAndLock(final String name, LockTimeout timeout, LockInfo lockInfo ) throws NotAuthorizedException {
+               FileHeader kmfile=null;
+               try {
+                       kmfile = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
+                               @Override
+                               public FileHeader call() throws Exception {
+                                       return factory.getService().createEmptyFile(getCurrentUser().getId(), folder.getId(), name);
+                               }
+                       });
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+        GssFileResource newRes = new GssFileResource( host, factory, kmfile ,getCurrentUser());
+        LockResult res = newRes.lock( timeout, lockInfo );
+        return res.getLockToken();
+               
+       }
+       @Override
+       public Long getContentLength() {
+               return null;
+       }
+       @Override
+       public String getContentType(String arg0) {
+                return "text/html";
+       }
+       @Override
+       public Long getMaxAgeSeconds(Auth arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+       /**
+    * 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 {
+       String subpath = folder.getPath();//getFile().getCanonicalPath().substring( factory.getRoot().getCanonicalPath().length() ).replace( '\\', '/' );
+       String uri = "/" + factory.getContextPath() + subpath;
+       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() ) {
+           w.open( "tr" );
+
+           w.open( "td" );
+           w.begin( "a" ).writeAtt( "href", uri + "/" + r.getName() ).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();
+   }
+       @Override
+       public Long getQuotaAvailable() {
+               if(getCurrentUser()!=null)
+                       try {
+                               return factory.getService().getUserStatistics(getCurrentUser().getId()).getQuotaLeftSize();
+                       } catch (ObjectNotFoundException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               return null;
+       }
+       @Override
+       public Long getQuotaUsed() {
+               if(getCurrentUser()!=null)
+                       try {
+                               return factory.getService().getUserStatistics(getCurrentUser().getId()).getFileSize();
+                       } catch (ObjectNotFoundException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               return null;
+       }
+       
+       @Override
+       public boolean authorise(Request request, Method method, Auth auth) {
+        boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
+        if(result){
+               User user = getCurrentUser();
+               //check permission
+               try {
+                               this.folder=factory.getService().getFolder(user.getId(), folder.getId());
+                       } catch (ObjectNotFoundException e) {
+                               return false;
+                       } catch (InsufficientPermissionsException e) {
+                               return false;
+                       } catch (RpcException e) {
+                               return false;
+                       }
+                       return true;
+        }
+        return result;
+    }
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssLockManager.java b/src/gr/ebs/gss/server/webdav/milton/GssLockManager.java
new file mode 100644 (file)
index 0000000..3120b14
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+
+
+import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileLock;
+import gr.ebs.gss.server.ejb.ExternalAPI;
+
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.LockInfo;
+import com.bradmcevoy.http.LockResult;
+import com.bradmcevoy.http.LockTimeout;
+import com.bradmcevoy.http.LockToken;
+import com.bradmcevoy.http.LockableResource;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.ettrema.http.fs.LockManager;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssLockManager implements LockManager {
+
+    private static final Logger log = LoggerFactory.getLogger( GssLockManager.class );
+    /**
+     * maps current locks by the file associated with the resource
+     */
+    
+    public GssLockManager() {
+
+    }
+
+    public synchronized LockResult lock( LockTimeout timeout, LockInfo lockInfo, LockableResource r ) {
+        GssResource resource = (GssResource) r;
+        LockToken currentLock = currentLock( resource );
+        if( currentLock != null ) {
+            return LockResult.failed( LockResult.FailureReason.ALREADY_LOCKED );
+        }
+
+        LockToken newToken = new LockToken( UUID.randomUUID().toString(), lockInfo, timeout );
+        FileLock newLock = new FileLock( resource.getUniqueId(), newToken);
+        getService().saveOrUpdateLock(newLock);
+        return LockResult.success( newToken );
+    }
+
+    public synchronized LockResult refresh( String tokenId, LockableResource resource ) {
+        FileLock curLock = getService().getLockByToken(tokenId);
+        if( curLock == null ) {
+            log.debug( "can't refresh because no lock");
+            return LockResult.failed( LockResult.FailureReason.PRECONDITION_FAILED );
+        } else {
+            curLock.setFrom( new Date() );
+            return LockResult.success( curLock.toToken() );
+        }
+    }
+
+    public synchronized void unlock( String tokenId, LockableResource r ) throws NotAuthorizedException {
+       GssResource resource = (GssResource) r;
+        LockToken lockToken = currentLock( resource );
+        if( lockToken == null ) {
+            log.debug( "not locked" );
+            return;
+        }
+        if( lockToken.tokenId.equals( tokenId ) ) {
+            removeLock( lockToken );
+        } else {
+            throw new NotAuthorizedException( resource );
+        }
+    }
+
+    private LockToken currentLock( GssResource resource ) {
+        FileLock curLock = getService().getLockById(resource.getUniqueId());
+        if( curLock == null ) return null;
+        LockToken token = curLock.toToken();
+        if( token.isExpired() ) {
+            removeLock( token );
+            return null;
+        } else {
+            return token;
+        }
+    }
+
+    private void removeLock( LockToken token ) {
+        log.debug( "removeLock: " + token.tokenId );
+        FileLock currentLock = getService().getLockByToken(token.tokenId);
+        if( currentLock != null ) {
+            getService().removeLock(currentLock);
+        } else {
+            log.warn( "couldnt find lock: " + token.tokenId );
+        }
+    }
+
+    public LockToken getCurrentToken( LockableResource r ) {
+       GssResource resource = (GssResource) r;
+        FileLock lock = getService().getLockById( resource.getUniqueId() );
+        if( lock == null ) return null;
+        LockToken token = new LockToken();
+        token.info = new LockInfo( LockInfo.LockScope.EXCLUSIVE, LockInfo.LockType.WRITE, lock.lockedByUser, LockInfo.LockDepth.ZERO );
+        token.info.lockedByUser = lock.lockedByUser;
+        token.timeout = lock.toToken().timeout;
+        token.tokenId = lock.getTokenId();
+        return token;
+    }
+
+    protected ExternalAPI getService() throws RuntimeException {
+               try {
+                       final Context ctx = new InitialContext();
+                       final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
+                       return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
+               } catch (final NamingException e) {
+                       log.error("Unable to retrieve the ExternalAPI EJB", e);
+                       throw new RuntimeException("An error occurred while contacting the naming service");
+               }
+       }
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssMemoryLockManager.java b/src/gr/ebs/gss/server/webdav/milton/GssMemoryLockManager.java
new file mode 100644 (file)
index 0000000..bfe95f4
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.LockInfo;
+import com.bradmcevoy.http.LockResult;
+import com.bradmcevoy.http.LockTimeout;
+import com.bradmcevoy.http.LockToken;
+import com.bradmcevoy.http.LockableResource;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.ettrema.http.fs.LockManager;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssMemoryLockManager implements LockManager {
+
+    private static final Logger log = LoggerFactory.getLogger( GssMemoryLockManager.class );
+    /**
+     * maps current locks by the file associated with the resource
+     */
+    Map<String, CurrentLock> locksByFile;
+    Map<String, CurrentLock> locksByToken;
+
+    public GssMemoryLockManager() {
+        locksByFile = new HashMap<String, CurrentLock>();
+        locksByToken = new HashMap<String, CurrentLock>();
+    }
+
+    public synchronized LockResult lock( LockTimeout timeout, LockInfo lockInfo, LockableResource r ) {
+        GssResource resource = (GssResource) r;
+        LockToken currentLock = currentLock( resource );
+        if( currentLock != null ) {
+            return LockResult.failed( LockResult.FailureReason.ALREADY_LOCKED );
+        }
+
+        LockToken newToken = new LockToken( UUID.randomUUID().toString(), lockInfo, timeout );
+        CurrentLock newLock = new CurrentLock( resource.getUniqueId(), newToken, lockInfo.lockedByUser );
+        locksByFile.put( resource.getUniqueId(), newLock );
+        locksByToken.put( newToken.tokenId, newLock );
+        return LockResult.success( newToken );
+    }
+
+    public synchronized LockResult refresh( String tokenId, LockableResource resource ) {
+        CurrentLock curLock = locksByToken.get( tokenId );
+        if( curLock == null ) {
+            log.debug( "can't refresh because no lock");
+            return LockResult.failed( LockResult.FailureReason.PRECONDITION_FAILED );
+        } else {
+            curLock.token.setFrom( new Date() );
+            return LockResult.success( curLock.token );
+        }
+    }
+
+    public synchronized void unlock( String tokenId, LockableResource r ) throws NotAuthorizedException {
+       GssResource resource = (GssResource) r;
+        LockToken lockToken = currentLock( resource );
+        if( lockToken == null ) {
+            log.debug( "not locked" );
+            return;
+        }
+        if( lockToken.tokenId.equals( tokenId ) ) {
+            removeLock( lockToken );
+        } else {
+            throw new NotAuthorizedException( resource );
+        }
+    }
+
+    private LockToken currentLock( GssResource resource ) {
+        CurrentLock curLock = locksByFile.get( resource.getUniqueId() );
+        if( curLock == null ) return null;
+        LockToken token = curLock.token;
+        if( token.isExpired() ) {
+            removeLock( token );
+            return null;
+        } else {
+            return token;
+        }
+    }
+
+    private void removeLock( LockToken token ) {
+        log.debug( "removeLock: " + token.tokenId );
+        CurrentLock currentLock = locksByToken.get( token.tokenId );
+        if( currentLock != null ) {
+            locksByFile.remove( currentLock.file );
+            locksByToken.remove( currentLock.token.tokenId );
+        } else {
+            log.warn( "couldnt find lock: " + token.tokenId );
+        }
+    }
+
+    public LockToken getCurrentToken( LockableResource r ) {
+       GssResource resource = (GssResource) r;
+        CurrentLock lock = locksByFile.get( resource.getUniqueId() );
+        if( lock == null ) return null;
+        LockToken token = new LockToken();
+        token.info = new LockInfo( LockInfo.LockScope.EXCLUSIVE, LockInfo.LockType.WRITE, lock.lockedByUser, LockInfo.LockDepth.ZERO );
+        token.info.lockedByUser = lock.lockedByUser;
+        token.timeout = lock.token.timeout;
+        token.tokenId = lock.token.tokenId;
+        return token;
+    }
+
+    class CurrentLock {
+
+        final String file;
+        final LockToken token;
+        final String lockedByUser;
+
+        public CurrentLock( String file, LockToken token, String lockedByUser ) {
+            this.file = file;
+            this.token = token;
+            this.lockedByUser = lockedByUser;
+        }
+    }
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java b/src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java
new file mode 100644 (file)
index 0000000..063464b
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import java.util.Arrays;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.AuthenticationService;
+import com.bradmcevoy.http.CompressingResponseHandler;
+import com.bradmcevoy.http.MiltonServlet;
+import com.bradmcevoy.http.ServletHttpManager;
+import com.bradmcevoy.http.http11.auth.PreAuthenticationFilter;
+import com.bradmcevoy.http.webdav.DefaultWebDavResponseHandler;
+import com.ettrema.console.ConsoleResourceFactory;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssMiltonServlet extends MiltonServlet {
+       private Logger log = LoggerFactory.getLogger( GssMiltonServlet.class );
+       private ServletConfig config;
+       
+       public void init( ServletConfig config ) throws ServletException {
+        try {
+            this.config = config;
+            GssLockManager lockManager = new GssLockManager();
+            //SimpleMemoryNonceProvider nonce = new SimpleMemoryNonceProvider( 60*60*24 );
+            GssNonceProvider nonce = new GssNonceProvider( 60*60*24 );
+            GssSecurityManager securityManager = new GssSecurityManager("Pithos WebDAV");
+            AuthenticationService authService = new AuthenticationService(nonce);
+            authService.setDisableBasic(true);
+            authService.setDisableDigest(false);
+            DefaultWebDavResponseHandler responseHandler = new DefaultWebDavResponseHandler(authService);
+            CompressingResponseHandler compressHandler = new CompressingResponseHandler(responseHandler);
+            GSSResourceFactory resourceFactory = new GSSResourceFactory();
+            resourceFactory.setSecurityManager(securityManager);
+            resourceFactory.setLockManager(lockManager);
+            resourceFactory.setMaxAgeSeconds(3600l);
+            resourceFactory.setContextPath("webdav");
+            //PreAuthenticationFilter filter = new PreAuthenticationFilter(compressHandler, securityManager,nonce);
+            ConsoleResourceFactory consoleResourceFactory = new ConsoleResourceFactory(resourceFactory, "/console", "/webdav", Arrays.asList(new com.ettrema.console.LsFactory(),
+                        new com.ettrema.console.CdFactory(),
+                        new com.ettrema.console.RmFactory(),
+                        new com.ettrema.console.HelpFactory(),
+                        new com.ettrema.console.CpFactory(),
+                        new com.ettrema.console.MkFactory(),
+                        new com.ettrema.console.MkdirFactory()), "webdav");
+            
+            httpManager = new ServletHttpManager(consoleResourceFactory,compressHandler,authService);
+            /*if(httpManager.getFilters()==null)
+               httpManager.setFilters(new ArrayList<Filter>());
+            httpManager.getFilters().add(filter);*/
+            //List<AuthenticationHandler> list = new ArrayList();
+            //list.add(new DigestAuthenticationHandler(authService));
+           // httpManager.addFilter(0, filter);
+            
+        }catch( Throwable ex ) {
+            log.error( "Exception starting milton servlet", ex );
+            throw new RuntimeException( ex );
+        }
+    }
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssNonceProvider.java b/src/gr/ebs/gss/server/webdav/milton/GssNonceProvider.java
new file mode 100644 (file)
index 0000000..7e716a2
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.WebDavNonce;
+import gr.ebs.gss.server.ejb.ExternalAPI;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.http11.auth.ExpiredNonceRemover;
+import com.bradmcevoy.http.http11.auth.Nonce;
+import com.bradmcevoy.http.http11.auth.NonceProvider;
+import com.bradmcevoy.http.http11.auth.SimpleMemoryNonceProvider;
+import com.bradmcevoy.http.http11.auth.NonceProvider.NonceValidity;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssNonceProvider implements NonceProvider {
+
+    private static final Logger log = LoggerFactory.getLogger( GssNonceProvider.class );
+    private final int nonceValiditySeconds;
+    private boolean enableNonceCountChecking;
+    public GssNonceProvider( int nonceValiditySeconds ) {
+        this.nonceValiditySeconds = nonceValiditySeconds;
+    }
+    
+       @Override
+       public String createNonce(Resource resource, Request request ) {
+               UUID id = UUID.randomUUID();
+        Date now = new Date();
+        Nonce n = new Nonce( id, now );
+        createOrUpdateGssNonce(n);
+        return n.getValue().toString();
+       }
+
+       @Override
+       public NonceValidity getNonceValidity( String nonce, Long nc ) {
+        log.trace( "getNonceValidity: " + nonce );
+        UUID value = null;
+        try {
+            value = UUID.fromString( nonce );
+        } catch( Exception e ) {
+            log.warn( "couldnt parse nonce" );
+            return NonceValidity.INVALID;
+        }
+        Nonce n = getNonce( nonce );
+        if( n == null ) {
+            log.debug( "not found");
+            return NonceValidity.INVALID;
+        } else {
+            if( isExpired( n.getIssued() ) ) {
+                log.debug( "nonce has expired" );
+                return NonceValidity.EXPIRED;
+            } else {
+                if( nc == null ) {
+                    log.trace( "nonce ok" );
+                    return NonceValidity.OK;
+                } else {
+                    if( enableNonceCountChecking && nc <= n.getNonceCount() ) {
+                        log.warn( "nonce-count was not greater then previous, possible replay attack. new: " + nc + " old:" + n.getNonceCount() );
+                        return NonceValidity.INVALID;
+                    } else {
+                        log.trace( "nonce and nonce-count ok" );
+                        Nonce newNonce = n.increaseNonceCount( nc );
+                        createOrUpdateGssNonce(newNonce);
+                        return NonceValidity.OK;
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean isExpired( Date issued ) {
+        long dif = ( System.currentTimeMillis() - issued.getTime() ) / 1000;
+        return dif > nonceValiditySeconds;
+    }
+    
+    private void createOrUpdateGssNonce(Nonce nonce){
+       try{
+               WebDavNonce non = getService().getWebDavNonce(nonce.getValue().toString());
+               if(non==null){
+                       non = new WebDavNonce();
+                       non.setId(nonce.getValue().toString());
+               }
+               non.setIssued(nonce.getIssued());
+               non.setNonceCount(nonce.getNonceCount());
+               getService().saveOrUpdateWebDavNonce(non);
+       }
+       catch(Exception ex){
+               throw new RuntimeException("Unable to save or update nonce",ex);
+       }
+    }
+    
+    private Nonce getNonce(String id){
+       try{
+               WebDavNonce non = getService().getWebDavNonce(id);
+               if(non!=null){
+                       Nonce nonce = new Nonce(UUID.fromString(id), non.getIssued());
+                       nonce.increaseNonceCount(non.getNonceCount());
+                       return nonce;
+               }
+       }
+       catch(Exception ex){
+               throw new RuntimeException("Unable to retrieve nonce",ex);
+       }
+       return null;
+    }
+    
+    /**
+        * A helper method that retrieves a reference to the ExternalAPI bean and
+        * stores it for future use.
+        *
+        * @return an ExternalAPI instance
+        * @throws RpcException in case an error occurs
+        */
+       protected ExternalAPI getService() throws RpcException {
+               try {
+                       final Context ctx = new InitialContext();
+                       final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
+                       return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
+               } catch (final NamingException e) {
+                       log.error("Unable to retrieve the ExternalAPI EJB", e);
+                       throw new RpcException("An error occurred while contacting the naming service");
+               }
+       }
+       /**
+     * IE seems to send nc (nonce count) parameters out of order. To correctly
+     * implement checking we need to record which nonces have been sent, and not
+     * assume they will be sent in a monotonically increasing sequence.
+     *
+     * The quick fix here is to disable checking of the nc param, since other
+     * common servers seem to do so to.
+     *
+     * Note that this will allow replay attacks.
+     *
+     * @return
+     */
+    public boolean isEnableNonceCountChecking() {
+        return enableNonceCountChecking;
+    }
+
+   public void setEnableNonceCountChecking( boolean enableNonceCountChecking ) {
+       this.enableNonceCountChecking = enableNonceCountChecking;
+   }
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssOtherUserResource.java b/src/gr/ebs/gss/server/webdav/milton/GssOtherUserResource.java
new file mode 100644 (file)
index 0000000..331bcdc
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.server.domain.User;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.CollectionResource;
+import com.bradmcevoy.http.DigestResource;
+import com.bradmcevoy.http.GetableResource;
+import com.bradmcevoy.http.PropFindableResource;
+import com.bradmcevoy.http.Range;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.exceptions.BadRequestException;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.bradmcevoy.http.http11.auth.DigestResponse;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssOtherUserResource implements PropFindableResource,  GetableResource, DigestResource, CollectionResource{
+       private static final Logger log = LoggerFactory.getLogger(GssOthersResource.class);
+    String host;
+    GSSResourceFactory factory;
+    User currentUser;
+    User resource;
+       /**
+        * 
+        */
+       public GssOtherUserResource(String host, GSSResourceFactory factory, User resource) {
+               this.host=host;
+               this.factory=factory;
+               this.resource=resource;
+               
+       }
+       
+       @Override
+       public Date getCreateDate() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       
+       @Override
+       public String checkRedirect(Request arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Date getModifiedDate() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String getName() {
+               return resource.getName();
+       }
+
+       @Override
+       public String getUniqueId() {
+               return "user:"+resource.getId();
+       }
+
+       @Override
+       public Long getContentLength() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String getContentType(String arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Long getMaxAgeSeconds(Auth arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public void sendContent(OutputStream arg0, Range arg1, Map<String, String> arg2, String arg3) throws IOException, NotAuthorizedException, BadRequestException {
+               // TODO Auto-generated method stub
+               
+       }
+       @Override
+       public Object authenticate(String user, String password) {
+        return factory.getSecurityManager().authenticate(user, password);
+    }
+       @Override
+    public Object authenticate( DigestResponse digestRequest ) {
+        return (User) factory.getSecurityManager().authenticate(digestRequest);
+        
+        
+    }
+
+    @Override
+    public boolean authorise(Request request, Method method, Auth auth) {
+        return factory.getSecurityManager().authorise(request, method, auth, this);
+    }
+    @Override
+    public String getRealm() {
+        return factory.getRealm(this.host);
+    }
+
+       @Override
+       public boolean isDigestAllowed() {
+               // TODO Auto-generated method stub
+               return true;
+       }
+
+       @Override
+       public Resource child(String arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public List<? extends Resource> getChildren() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssOthersResource.java b/src/gr/ebs/gss/server/webdav/milton/GssOthersResource.java
new file mode 100644 (file)
index 0000000..6fe7e72
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.User;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.CollectionResource;
+import com.bradmcevoy.http.DigestResource;
+import com.bradmcevoy.http.GetableResource;
+import com.bradmcevoy.http.HttpManager;
+import com.bradmcevoy.http.PropFindableResource;
+import com.bradmcevoy.http.Range;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.exceptions.BadRequestException;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.bradmcevoy.http.http11.auth.DigestResponse;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssOthersResource implements PropFindableResource,  GetableResource, DigestResource, CollectionResource{
+       private static final Logger log = LoggerFactory.getLogger(GssOthersResource.class);
+    String host;
+    GSSResourceFactory factory;
+    User currentUser;
+    
+       /**
+        * 
+        */
+       public GssOthersResource(String host, GSSResourceFactory factory) {
+               this.host=host;
+               this.factory=factory;
+               
+               
+       }
+       
+       @Override
+       public Date getCreateDate() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       
+       @Override
+       public String checkRedirect(Request arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Date getModifiedDate() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String getName() {
+               return "OthersShared";
+       }
+
+       @Override
+       public String getUniqueId() {
+               return "OthersShared";
+       }
+
+       @Override
+       public Long getContentLength() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String getContentType(String arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Long getMaxAgeSeconds(Auth arg0) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public void sendContent(OutputStream arg0, Range arg1, Map<String, String> arg2, String arg3) throws IOException, NotAuthorizedException, BadRequestException {
+               // TODO Auto-generated method stub
+               
+       }
+       @Override
+       public Object authenticate(String user, String password) {
+        return factory.getSecurityManager().authenticate(user, password);
+    }
+       @Override
+    public Object authenticate( DigestResponse digestRequest ) {
+        return factory.getSecurityManager().authenticate(digestRequest);
+        
+        
+    }
+
+    @Override
+    public boolean authorise(Request request, Method method, Auth auth) {
+        return factory.getSecurityManager().authorise(request, method, auth, this);
+    }
+    @Override
+    public String getRealm() {
+        return factory.getRealm(this.host);
+    }
+
+       @Override
+       public boolean isDigestAllowed() {
+               // TODO Auto-generated method stub
+               return true;
+       }
+
+       @Override
+       public Resource child(String arg0) {
+               for(Resource r : getChildren()){
+                       if(r.getName().equals(arg0))
+                               return r;
+               }
+               return null;
+       }
+
+       @Override
+       public List<? extends Resource> getChildren() {
+               List<GssOtherUserResource> result = new ArrayList<GssOtherUserResource>();
+               List<User> users;
+               try {
+                       users = factory.getService().getUsersSharingFoldersForUser(getCurrentUser().getId());
+                       log.info("USERS:"+users);
+                       for(User u : users){
+                               result.add(new GssOtherUserResource(host, factory, u));
+                       }
+               } catch (ObjectNotFoundException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               
+               return result;
+       }
+       
+       /**
+        * Retrieve the currentUser.
+        *
+        * @return the currentUser
+        */
+       public User getCurrentUser() {
+               if(currentUser!=null)
+                       return currentUser;
+               String username = HttpManager.request().getHeaders().get("authorization");
+       if(username!=null){
+               username=GSSResourceFactory.getUsernameFromAuthHeader(username);
+               try {
+                               currentUser = factory.getService().getUserByUserName(username);
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               return null;
+                       }
+       }
+       return currentUser;
+       }
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssPathResource.java b/src/gr/ebs/gss/server/webdav/milton/GssPathResource.java
new file mode 100644 (file)
index 0000000..df24272
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssPathResource {
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssResource.java b/src/gr/ebs/gss/server/webdav/milton/GssResource.java
new file mode 100644 (file)
index 0000000..c911707
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.User;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.CopyableResource;
+import com.bradmcevoy.http.DigestResource;
+import com.bradmcevoy.http.HttpManager;
+import com.bradmcevoy.http.LockInfo;
+import com.bradmcevoy.http.LockResult;
+import com.bradmcevoy.http.LockTimeout;
+import com.bradmcevoy.http.LockToken;
+import com.bradmcevoy.http.LockableResource;
+import com.bradmcevoy.http.MoveableResource;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.bradmcevoy.http.http11.auth.DigestResponse;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class GssResource implements Resource, MoveableResource, CopyableResource, LockableResource, DigestResource {
+    private static final Logger log = LoggerFactory.getLogger(GssResource.class);
+    String host;
+    GSSResourceFactory factory;
+    Object resource;
+    User currentUser;
+    
+       /**
+        * 
+        */
+       public GssResource(String host, GSSResourceFactory factory, Object resource) {
+               this.host=host;
+               this.factory=factory;
+               this.resource=resource;
+               
+       }
+       
+       public Object authenticate(String user, String password) {
+        return factory.getSecurityManager().authenticate(user, password);
+    }
+
+    public Object authenticate( DigestResponse digestRequest ) {
+        return  factory.getSecurityManager().authenticate(digestRequest);
+        
+    }
+
+    public boolean isDigestAllowed() {
+        return true;
+    }
+
+
+
+
+    public boolean authorise(Request request, Method method, Auth auth) {
+        return factory.getSecurityManager().authorise(request, method, auth, this);
+    }
+
+    public String getRealm() {
+        return factory.getRealm(this.host);
+    }
+    
+    public LockResult lock(LockTimeout timeout, LockInfo lockInfo) throws NotAuthorizedException {
+        return factory.getLockManager().lock(timeout, lockInfo, this);
+    }
+
+    public LockResult refreshLock(String token) throws NotAuthorizedException {
+        return factory.getLockManager().refresh(token, this);
+    }
+
+    public void unlock(String tokenId) throws NotAuthorizedException {
+        factory.getLockManager().unlock(tokenId, this);
+    }
+
+    public LockToken getCurrentLock() {
+        if( factory.getLockManager() != null ) {
+            return factory.getLockManager().getCurrentToken( this );
+        } else {
+            log.warn("getCurrentLock called, but no lock manager: file: " + resource);
+            return null;
+        }
+    }
+    
+    
+       /**
+        * Retrieve the currentUser.
+        *
+        * @return the currentUser
+        */
+       public User getCurrentUser() {
+               if(currentUser!=null)
+                       return currentUser;
+               if(HttpManager.request().getAuthorization()!=null && HttpManager.request().getAuthorization().getTag()==null){
+                       String username = HttpManager.request().getAuthorization().getUser();
+                       //log.info("username is:"+username);
+                       if(username !=null)
+                               try {
+                                       currentUser = factory.getService().getUserByUserName(username);
+                               } catch (RpcException e) {
+                                       // TODO Auto-generated catch block
+                                       e.printStackTrace();
+                               }
+               }
+               else if(HttpManager.request().getAuthorization()!=null&&HttpManager.request().getAuthorization().getTag()!=null){
+                       //log.info(HttpManager.request().getAuthorization().getUser());
+                       currentUser =(User) HttpManager.request().getAuthorization().getTag();//getService().getUserByUserName("past@ebs.gr");
+               }
+               return currentUser;
+       }
+       
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java b/src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java
new file mode 100644 (file)
index 0000000..4a313b0
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
+import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.User;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.LockInfo;
+import com.bradmcevoy.http.LockResult;
+import com.bradmcevoy.http.LockTimeout;
+import com.bradmcevoy.http.LockToken;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.exceptions.NotAuthorizedException;
+import com.bradmcevoy.http.http11.auth.DigestResponse;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssRootFolderResource extends GssFolderResource{
+       private static final Logger log = LoggerFactory.getLogger(GssFolderResource.class);
+       String path;
+       /**
+        * @param host
+        * @param factory
+        * @param resource
+        */
+       public GssRootFolderResource(String host, GSSResourceFactory factory, Object resource,String path) {
+               super(host, factory, resource,null);
+               this.path=path;
+               try {
+                       this.folder = (Folder) factory.getResourceGss(path,getCurrentUser());
+                       //log.info("ROOT FOLDER:"+folder);
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+       
+       @Override
+       public boolean authorise(Request request, Method method, Auth auth) {
+               // TODO Auto-generated method stub
+               boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
+        if(result){
+               User user = getCurrentUser();
+               if(user==null)
+                       //log.info("AUTH USER NULL");
+               if(this.folder==null){
+                       try {
+                                       this.folder= (Folder) factory.getResourceGss(path,getCurrentUser());//getService().getFolder(user.getId(), folder.getId());
+                               } catch (RpcException e) {
+                                       //log.info("*****AUTH1:"+false+" "+getCurrentUser());
+                                       return false;
+                               }
+               }
+                       //log.info("*****AUTH2:"+true+" "+getCurrentUser());
+                       return true;
+        }
+        //log.info("*****AUTH3:"+result+" "+getCurrentUser()+" "+method);
+        return result;
+    }
+       
+       
+       @Override
+       public Object authenticate(DigestResponse digestRequest) {
+               // TODO Auto-generated method stub
+               return super.authenticate(digestRequest);
+       }
+       
+       @Override
+       public String getName() {
+               return path;
+       }
+       @Override
+       public String getUniqueId() {
+               if(folder!=null)
+                       return "folder:"+folder.getId().toString();
+               return "folder:"+path;
+       }
+       @Override
+       public Resource child(String name) {
+               log.info("CALLING ROOT GET CHILD:"+getCurrentUser());
+               if(this.folder==null)
+                       try {
+                               this.folder = (Folder) factory.getResourceGss(path,getCurrentUser());
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               return super.child(name);
+       }
+       @Override
+       public List<? extends Resource> getChildren() {
+               //log.info("CALLING ROOT GET CHILDREN:"+getCurrentUser());
+               if(this.folder==null)
+                       try {
+                               this.folder = (Folder) factory.getResourceGss(path,getCurrentUser());
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               List<Resource> result = new ArrayList<Resource>();
+               for(Folder f : folder.getSubfolders())
+                       if(!f.isDeleted())
+                               result.add(new GssFolderResource(host, factory, f,getCurrentUser()));
+               try {
+                       for(FileHeader f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
+                               result.add(new GssFileResource(host, factory, f,getCurrentUser()));
+               } catch (ObjectNotFoundException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (InsufficientPermissionsException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               //result.add(new GssOthersResource(host, factory));
+               return result;
+       }
+       
+       /*Disable Locks if folder is null*/
+       public LockResult lock(LockTimeout timeout, LockInfo lockInfo) throws NotAuthorizedException {
+               if(folder==null)
+                       throw new NotAuthorizedException(this);
+        return factory.getLockManager().lock(timeout, lockInfo, this);
+    }
+
+    public LockResult refreshLock(String token) throws NotAuthorizedException {
+       if(folder==null)
+                       throw new NotAuthorizedException(this);
+        return factory.getLockManager().refresh(token, this);
+    }
+
+    public void unlock(String tokenId) throws NotAuthorizedException {
+       if(folder==null)
+                       throw new NotAuthorizedException(this);
+        factory.getLockManager().unlock(tokenId, this);
+    }
+
+    public LockToken getCurrentLock() {
+       if(folder==null)
+                       return null;
+        if( factory.getLockManager() != null ) {
+            return factory.getLockManager().getCurrentToken( this );
+        } else {
+            log.warn("getCurrentLock called, but no lock manager: file: " + resource);
+            return null;
+        }
+    }
+
+}
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java b/src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java
new file mode 100644 (file)
index 0000000..cb1add7
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 General Public License
+ * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.User;
+import gr.ebs.gss.server.ejb.ExternalAPI;
+import gr.ebs.gss.server.ejb.TransactionHelper;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.http11.auth.DigestGenerator;
+import com.bradmcevoy.http.http11.auth.DigestResponse;
+import com.ettrema.http.fs.SimpleSecurityManager;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssSecurityManager  implements com.bradmcevoy.http.SecurityManager{
+
+       private static final Logger log = LoggerFactory.getLogger(SimpleSecurityManager.class);
+
+    private String realm;
+    private DigestGenerator digestGenerator;
+
+    public GssSecurityManager() {
+        digestGenerator = new DigestGenerator();
+    }
+
+    public GssSecurityManager( DigestGenerator digestGenerator ) {
+        this.digestGenerator = digestGenerator;
+    }
+
+   
+    public GssSecurityManager( String realm) {
+        this.realm = realm;
+        this.digestGenerator = new DigestGenerator();
+    }
+    /*
+    public Object getUserByName( String name ) {
+        String actualPassword = nameAndPasswords.get( name );
+        if( actualPassword != null ) return name;
+        return null;
+    }*/
+
+
+
+    public Object authenticate( String user, String password ) {
+        //log.info( "authenticate: " + user + " - " + password);
+        // user name will include domain when coming form ftp. we just strip it off
+        if( user.contains( "@")) {
+            user = user.substring( 0, user.indexOf( "@"));
+        }
+        String actualPassword=null;
+               try {
+                       actualPassword = getUsersPassword( user );
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       return null;
+               }
+        if( actualPassword == null ) {
+            log.debug( "user not found: " + user);
+            return null;
+        } else {
+            boolean ok;
+            if( actualPassword == null ) {
+                ok = password == null || password.length()==0;
+            } else {
+                ok = actualPassword.equals( password);
+            }
+            return ok ? user : null;
+        }
+    }
+
+    public Object authenticate( DigestResponse digestRequest ) {
+       //log.info( "DIGEST authenticate: " + digestRequest);
+        String actualPassword=null;
+               try {
+                       actualPassword = getUsersPassword( digestRequest.getUser() );
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+                       return null;
+               }
+               
+        String serverResponse = digestGenerator.generateDigest( digestRequest, actualPassword );
+        String clientResponse = digestRequest.getResponseDigest();
+
+        if( serverResponse.equals( clientResponse ) ) {
+            try {
+                               return getService().getUserByUserName(digestRequest.getUser());
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               return null;
+                       }
+        } else {
+            return null;
+        }
+    }
+
+
+
+    public boolean authorise( Request request, Method method, Auth auth, Resource resource ) {
+        return auth != null && auth.getTag() != null;
+    }
+
+    public String getRealm(String host) {
+        return realm;
+    }
+
+    /**
+     * @param realm the realm to set
+     */
+    public void setRealm( String realm ) {
+        this.realm = realm;
+    }
+    
+    private ExternalAPI getService() throws RpcException {
+               try {
+                       final Context ctx = new InitialContext();
+                       final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
+                       return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
+               } catch (final NamingException e) {
+                       log.error("Unable to retrieve the ExternalAPI EJB", e);
+                       throw new RpcException("An error occurred while contacting the naming service");
+               }
+       }
+
+       
+       protected String getUsersPassword(String username) throws Exception {
+               
+               try {
+                       final User user = getService().findUser(username);
+                       if (user == null) throw new FailedLoginException("User '" + username + "' not found.");
+                       if (!user.isActive()) throw new FailedLoginException("User '" + username + "' is disabled.");
+                       if (user.getWebDAVPassword() != null && user.getWebDAVPassword().length() > 0)
+                               return user.getWebDAVPassword();
+                       // If no password has ever been generated, use token instead
+                       String tokenEncoded = new String(Base64.encodeBase64(user.getAuthToken()), "US-ASCII");
+                       user.setWebDAVPassword(tokenEncoded);
+                       new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
+                               @Override
+                               public Void call() throws Exception {
+                                       getService().updateUser(user);
+                                       return null;
+                               }
+                       });
+                       return tokenEncoded;
+               } catch (RpcException e) {
+                       String error = "An error occurred while communicating with the service";
+                       log.error(error, e);
+                       throw new Exception(e.getMessage());
+               } catch (UnsupportedEncodingException e) {
+            log.error("", e);
+            throw new Exception(e.getMessage());
+               } catch (Exception e) {
+            log.error("", e);
+                       throw new Exception(e.getMessage());
+               }
+       }
+
+    
+
+
+}
\ No newline at end of file
index b632d5a..334db10 100644 (file)
@@ -22,10 +22,10 @@ import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfigu
 import gr.ebs.gss.client.exceptions.DuplicateNameException;
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.UserDTO;
+import gr.ebs.gss.server.domain.FileHeader;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.User;
 
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -81,7 +81,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetRootFolderNormal() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final FolderDTO f = service.getRootFolder(Long.valueOf(1));
+                       final Folder f = service.getRootFolder(Long.valueOf(1));
                        Assert.assertNotNull(f);
                } catch (final Exception e) {
                        e.printStackTrace();
@@ -152,7 +152,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetFilesNormal() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<FileHeaderDTO> files = service.getFiles(new Long(1L), Long.valueOf(1), true);
+                       final List<FileHeader> files = service.getFiles(new Long(1L), Long.valueOf(1), true);
                        Assert.assertNotNull(files);
                        Assert.assertFalse(files.isEmpty());
                } catch (final Exception e) {
@@ -170,7 +170,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetFilesWithEmptyFolder() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<FileHeaderDTO> files = service.getFiles(new Long(1L), Long.valueOf(2), true);
+                       final List<FileHeader> files = service.getFiles(new Long(1L), Long.valueOf(2), true);
                        Assert.assertNotNull(files);
                        Assert.assertTrue(files.isEmpty());
                } catch (final Exception e) {
@@ -207,7 +207,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetFilesWithNonExistentFolder() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<FileHeaderDTO> files = service.getFiles(new Long(1L), Long.valueOf(-1), true);
+                       final List<FileHeader> files = service.getFiles(new Long(1L), Long.valueOf(-1), true);
                        Assert.assertNotNull(files);
                        Assert.assertTrue(files.isEmpty());
                } catch (final Exception e) {
@@ -223,7 +223,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetGroupsNormal() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<GroupDTO> groups = service.getGroups(Long.valueOf(1));
+                       final List<Group> groups = service.getGroups(Long.valueOf(1));
                        Assert.assertNotNull(groups);
                        Assert.assertFalse(groups.isEmpty());
                } catch (final Exception e) {
@@ -239,7 +239,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetGroupsForUserWithNoGroups() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<GroupDTO> groups = service.getGroups(Long.valueOf(2));
+                       final List<Group> groups = service.getGroups(Long.valueOf(2));
                        Assert.assertNotNull(groups);
                        Assert.assertTrue(groups.isEmpty());
                } catch (final Exception e) {
@@ -272,7 +272,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetGroupsForNonExistentUser() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<GroupDTO> groups = service.getGroups(Long.valueOf(-1));
+                       final List<Group> groups = service.getGroups(Long.valueOf(-1));
                        Assert.assertNotNull(groups);
                        Assert.assertTrue(groups.isEmpty());
                } catch (final Exception e) {
@@ -288,7 +288,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetUsersNormal() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<UserDTO> users = service.getUsers(Long.valueOf(1), Long.valueOf(1));
+                       final List<User> users = service.getUsers(Long.valueOf(1), Long.valueOf(1));
                        Assert.assertNotNull(users);
                        Assert.assertFalse(users.isEmpty());
                } catch (final Exception e) {
@@ -304,7 +304,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetUsersForEmptyGroup() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<UserDTO> users = service.getUsers(Long.valueOf(1L), Long.valueOf(2));
+                       final List<User> users = service.getUsers(Long.valueOf(1L), Long.valueOf(2));
                        Assert.assertNotNull(users);
                        Assert.assertTrue(users.isEmpty());
                } catch (final Exception e) {
@@ -320,7 +320,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetUsersNonExistentGroup() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final List<UserDTO> users = service.getUsers(Long.valueOf(1L), Long.valueOf(-1));
+                       final List<User> users = service.getUsers(Long.valueOf(1L), Long.valueOf(-1));
                        Assert.assertNotNull(users);
                        Assert.assertTrue(users.isEmpty());
                } catch (final Exception e) {
@@ -361,7 +361,7 @@ public class ExternalAPITest extends TestCase {
                                final Iterator i = rootSubfolders.iterator();
                                ok = true;
                                while (i.hasNext()) {
-                                       final FolderDTO f = (FolderDTO) i.next();
+                                       final Folder f = (Folder) i.next();
                                        if (f.getName().equals(name)) {
                                                name = name + "!";
                                                ok = false;
@@ -372,7 +372,7 @@ public class ExternalAPITest extends TestCase {
                        service.createFolder(Long.valueOf(1), Long.valueOf(1), name);
                        final Iterator i = service.getRootFolder(Long.valueOf(1)).getSubfolders().iterator();
                        while (i.hasNext()) {
-                               final FolderDTO f = (FolderDTO) i.next();
+                               final Folder f = (Folder) i.next();
                                if (f.getName().equals(name))
                                        return;
                        }
@@ -392,7 +392,7 @@ public class ExternalAPITest extends TestCase {
                try {
                        final ExternalAPIRemote service = getService();
                        final List rootSubfolders = service.getRootFolder(Long.valueOf(1)).getSubfolders();
-                       service.createFolder(Long.valueOf(1), Long.valueOf(1), ((FolderDTO) rootSubfolders.get(0)).getName());
+                       service.createFolder(Long.valueOf(1), Long.valueOf(1), ((Folder) rootSubfolders.get(0)).getName());
                        Assert.fail();
                } catch (final Exception e) {
                        if (!(e instanceof DuplicateNameException)) {
@@ -503,7 +503,7 @@ public class ExternalAPITest extends TestCase {
                        final ExternalAPIRemote service = getService();
                        final Iterator i = service.getRootFolder(Long.valueOf(1)).getSubfolders().iterator();
                        while (i.hasNext()) {
-                               final FolderDTO f = (FolderDTO) i.next();
+                               final Folder f = (Folder) i.next();
                                if (f.getName().equals(name))
                                        service.deleteFolder(Long.valueOf(1), f.getId());
                        }
@@ -527,7 +527,7 @@ public class ExternalAPITest extends TestCase {
                                service.createFolder(Long.valueOf(1), Long.valueOf(1), name);
                                final Iterator i = service.getRootFolder(Long.valueOf(1)).getSubfolders().iterator();
                                while (i.hasNext()) {
-                                       final FolderDTO f = (FolderDTO) i.next();
+                                       final Folder f = (Folder) i.next();
                                        if (f.getName().equals(name)) {
                                                folderId = f.getId();
                                                service.deleteFolder(null, f.getId());
@@ -561,7 +561,7 @@ public class ExternalAPITest extends TestCase {
                                service.createFolder(Long.valueOf(1), Long.valueOf(1), name);
                                final Iterator i = service.getRootFolder(Long.valueOf(1)).getSubfolders().iterator();
                                while (i.hasNext()) {
-                                       final FolderDTO f = (FolderDTO) i.next();
+                                       final Folder f = (Folder) i.next();
                                        if (f.getName().equals(name)) {
                                                folderId = f.getId();
                                                service.deleteFolder(Long.valueOf(-1), f.getId());
@@ -631,7 +631,7 @@ public class ExternalAPITest extends TestCase {
                                service.createFolder(Long.valueOf(1), Long.valueOf(1), name);
                                final Iterator i = service.getRootFolder(Long.valueOf(1)).getSubfolders().iterator();
                                while (i.hasNext()) {
-                                       final FolderDTO f = (FolderDTO) i.next();
+                                       final Folder f = (Folder) i.next();
                                        if (f.getName().equals(name)) {
                                                folderId = f.getId();
                                                service.deleteFolder(Long.valueOf(2), f.getId());
@@ -652,12 +652,12 @@ public class ExternalAPITest extends TestCase {
        }
 
        /**
-        * Tests {@link ExternalAPIBean#getUserDTO(Long)} with normal parameters
+        * Tests {@link ExternalAPIBean#getUser(Long)} with normal parameters
         */
        public final void testGetUserNormal() {
                try {
                        final ExternalAPIRemote service = getService();
-                       final UserDTO user = service.getUserDTO(Long.valueOf(1));
+                       final User user = service.getUser(Long.valueOf(1));
                        assertNotNull(user);
                        assertNotNull(user.getId());
                        assertEquals(user.getId().longValue(), 1L);
@@ -673,7 +673,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetUserNullId() {
                try {
                        final ExternalAPIRemote service = getService();
-                       service.getUserDTO(null);
+                       service.getUser(null);
                        Assert.fail();
                } catch (final NamingException e) {
                        e.printStackTrace();
@@ -692,7 +692,7 @@ public class ExternalAPITest extends TestCase {
        public final void testGetUserNonExistentId() {
                try {
                        final ExternalAPIRemote service = getService();
-                       service.getUserDTO(Long.valueOf(-1));
+                       service.getUser(Long.valueOf(-1));
                        Assert.fail();
                } catch (final NamingException e) {
                        e.printStackTrace();
index c75ccf3..bbfd4fa 100644 (file)
@@ -21,6 +21,8 @@ package gr.ebs.gss.server.ejb;
 import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.server.domain.Folder;
+import gr.ebs.gss.server.domain.Permission;
 import gr.ebs.gss.server.domain.User;
 import gr.ebs.gss.server.domain.dto.FolderDTO;
 import gr.ebs.gss.server.domain.dto.PermissionDTO;
@@ -102,10 +104,10 @@ public class ScenarioTest extends TestCase {
         */
        public void testGetRootFolder() {
                try {
-                       FolderDTO root = getService().getRootFolder(user1.getId());
+                       Folder root = getService().getRootFolder(user1.getId());
                        Assert.assertNotNull(root);
-                       List<FolderDTO> subfolders = getService().getSubfolders(user1.getId(), root.getId());
-                       for(FolderDTO f : subfolders)
+                       List<Folder> subfolders = getService().getSubfolders(user1.getId(), root.getId());
+                       for(Folder f : subfolders)
                                getService().deleteFolder(user1.getId(), f.getId());
 
                } catch (Exception e) {
@@ -118,30 +120,30 @@ public class ScenarioTest extends TestCase {
        //test create folder , folder permissions, copySharedFolders
        public void testFolderOperations(){
                try{
-                       FolderDTO root = getService().getRootFolder(user1.getId());
+                       Folder root = getService().getRootFolder(user1.getId());
                        Assert.assertNotNull(root);
                        getService().createFolder(user1.getId(), root.getId(), "subfolder1");
-                       List<FolderDTO> subfolders = getService().getSubfolders(user1.getId(), root.getId());
+                       List<Folder> subfolders = getService().getSubfolders(user1.getId(), root.getId());
                        Assert.assertTrue(subfolders.size() == 1);
-                       FolderDTO subFolder1 = subfolders.get(0);
+                       Folder subFolder1 = subfolders.get(0);
                        getService().createFolder(user1.getId(), subFolder1.getId(), "subfolder2");
-                       PermissionDTO permission = new PermissionDTO();
-                       permission.setUser(user2.getDTO());
+                       Permission permission = new Permission();
+                       permission.setUser(user2);
                        permission.setRead(true);
                        permission.setWrite(true);
-                       Set<PermissionDTO> perms = getService().getFolderPermissions(user1.getId(), subFolder1.getId());
+                       Set<Permission> perms = getService().getFolderPermissions(user1.getId(), subFolder1.getId());
                        perms.add(permission);
                        getService().updateFolder(user1.getId(), subFolder1.getId(), null, subFolder1.isReadForAll(), perms);
-                       List<FolderDTO> sharedFolders = getService().getSharedRootFolders(user1.getId());
+                       List<Folder> sharedFolders = getService().getSharedRootFolders(user1.getId());
                        assertTrue(sharedFolders.size() == 1 && sharedFolders.get(0).getId().equals(subFolder1.getId()));
-                       List<FolderDTO> sharedForUser2 = getService().getSharedRootFolders(user1.getId(), user2.getId());
+                       List<Folder> sharedForUser2 = getService().getSharedRootFolders(user1.getId(), user2.getId());
                        assertTrue(sharedFolders.get(0).getId().equals(sharedForUser2.get(0).getId()));
 
-                       FolderDTO root2 = getService().getRootFolder(user2.getId());
+                       Folder root2 = getService().getRootFolder(user2.getId());
                        getService().copyFolderStructure(user2.getId(), subFolder1.getId(), root2.getId(), subFolder1.getName());
-                       List<FolderDTO> subfolders2 = getService().getSubfolders(user2.getId(), root2.getId());
+                       List<Folder> subfolders2 = getService().getSubfolders(user2.getId(), root2.getId());
                        Assert.assertTrue(subfolders2.size() == 1);
-                       FolderDTO subFolder2 = subfolders2.get(0);
+                       Folder subFolder2 = subfolders2.get(0);
                        assertTrue(subFolder2.getSubfolders().get(0).getName().equals("subfolder2"));
                        perms.remove(permission);
                        getService().updateFolder(user1.getId(), subFolder1.getId(), null, subFolder1.isReadForAll(), perms);
diff --git a/webdav/WEB-INF/jboss-web.xml b/webdav/WEB-INF/jboss-web.xml
deleted file mode 100644 (file)
index 43d37af..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>\r
-\r
-<jboss-web>\r
-  <!-- Specify the security domain for authentication/authorization and\r
-   require that the domain's cache be flushed when the session invalidates.\r
-   -->\r
-   <security-domain flushOnSessionInvalidation="true">\r
-       java:/jaas/gssWebDAVSecurity\r
-   </security-domain>\r
-</jboss-web>\r
diff --git a/webdav/WEB-INF/lib/commons-fileupload-1.2.1.jar b/webdav/WEB-INF/lib/commons-fileupload-1.2.1.jar
new file mode 100644 (file)
index 0000000..7db423e
Binary files /dev/null and b/webdav/WEB-INF/lib/commons-fileupload-1.2.1.jar differ
diff --git a/webdav/WEB-INF/lib/milton-console-1.5.7-SNAPSHOT.jar b/webdav/WEB-INF/lib/milton-console-1.5.7-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..98106fb
Binary files /dev/null and b/webdav/WEB-INF/lib/milton-console-1.5.7-SNAPSHOT.jar differ
diff --git a/webdav/WEB-INF/lib/milton-servlet-1.5.7-SNAPSHOT.jar b/webdav/WEB-INF/lib/milton-servlet-1.5.7-SNAPSHOT.jar
new file mode 100644 (file)
index 0000000..2414580
Binary files /dev/null and b/webdav/WEB-INF/lib/milton-servlet-1.5.7-SNAPSHOT.jar differ
index 98b4092..462b205 100644 (file)
@@ -1,75 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<web-app>
-        <servlet>
-                               <servlet-name>Webdav</servlet-name>
-                       <servlet-class>gr.ebs.gss.server.webdav.Webdav</servlet-class>
-                               <init-param>
-                                       <param-name>input</param-name>
-                                       <param-value>4096</param-value>
-                               </init-param>
-                               <init-param>
-                                       <param-name>output</param-name>
-                                       <param-value>4096</param-value>
-                               </init-param>
-               </servlet>
-
-               <servlet-mapping>
-                               <servlet-name>Webdav</servlet-name>
-                               <url-pattern>/*</url-pattern>
-               </servlet-mapping>
-               
-               <security-constraint>
-               <!-- Protect /, but leave OPTIONS unauthenticated to get around Windows client bug with DIGEST authentication -->
-                       <web-resource-collection>
-                               <web-resource-name>GSS</web-resource-name>
-                               <description>GSS WebDAV</description>
-                               <url-pattern>/</url-pattern>
-                               <http-method>HEAD</http-method>
-                               <http-method>GET</http-method>
-                               <http-method>POST</http-method>
-                               <http-method>PUT</http-method>
-                               <http-method>DELETE</http-method>
-                               <http-method>PROPFIND</http-method>
-                               <http-method>PROPPATCH</http-method>
-                               <http-method>MKCOL</http-method>
-                               <http-method>COPY</http-method>
-                               <http-method>MOVE</http-method>
-                               <http-method>LOCK</http-method>
-                               <http-method>UNLOCK</http-method>
-                       </web-resource-collection>
-                       <auth-constraint>
-                               <role-name>simpleUser</role-name>
-                       </auth-constraint>
-                       <user-data-constraint>
-                               <description>no description</description>
-                               <transport-guarantee>NONE</transport-guarantee>
-                       </user-data-constraint>
-               </security-constraint>
-               
-               <security-constraint>
-               <!-- Protect everything for every other path -->
-                       <web-resource-collection>
-                               <web-resource-name>GSS</web-resource-name>
-                               <description>GSS WebDAV</description>
-                               <url-pattern>/*</url-pattern>
-                       </web-resource-collection>
-                       <auth-constraint>
-                               <role-name>simpleUser</role-name>
-                       </auth-constraint>
-                       <user-data-constraint>
-                               <description>no description</description>
-                               <transport-guarantee>NONE</transport-guarantee>
-                       </user-data-constraint>
-               </security-constraint>
-               
-               <login-config>
-                       <auth-method>DIGEST</auth-method>
-                       <realm-name>Pithos WebDAV</realm-name>
-               </login-config>
 
-               <security-role>
-                       <description>A plain WebDAV user</description>
-                       <role-name>simpleUser</role-name>
-               </security-role>
-               
-</web-app> 
\ No newline at end of file
+<web-app>
+        <servlet>
+        <servlet-name>milton_webdav</servlet-name>
+        <servlet-class>gr.ebs.gss.server.webdav.milton.GssMiltonServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    
+    <servlet-mapping>
+        <servlet-name>milton_webdav</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>