exo-jcr SVN: r3826 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/protocols.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-01-21 03:05:23 -0500 (Fri, 21 Jan 2011)
New Revision: 3826
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml
Log:
EXOJCR-1032: docbook info updated
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml 2011-01-21 08:01:45 UTC (rev 3825)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/protocols/webdav.xml 2011-01-21 08:05:23 UTC (rev 3826)
@@ -355,6 +355,12 @@
<entry>Workspace.getQueryManager(); QueryManager.createQuery();
Query.execute()</entry>
</row>
+
+ <row>
+ <entry>ACL</entry>
+
+ <entry>Node.setPermission(...)</entry>
+ </row>
</tbody>
</tgroup>
</table>
@@ -394,19 +400,5 @@
</listitem>
</orderedlist>
</section>
-
- <section>
- <title>Mac OS 10.5.3 and higher </title>
-
- <para>There is a known Finder bug started from Mac OS v.10.5.3 and not
- yet fixed.</para>
-
- <para>When you upload file to webdav server, the file will appear with 0
- kb. size. </para>
-
- <para>For more details follow: <ulink
- url="http://discussions.apple.com/thread.jspa?threadID=1538882&start=0&...">Apple
- Disscussion thread.</ulink></para>
- </section>
</section>
</chapter>
13 years, 4 months
exo-jcr SVN: r3825 - in jcr/trunk/exo.jcr.component.webdav/src: main/java/org/exoplatform/services/jcr/webdav/command and 5 other directories.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-01-21 03:01:45 -0500 (Fri, 21 Jan 2011)
New Revision: 3825
Added:
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/AclCommand.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/acl/
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/acl/ACLProperties.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestAclCommand.java
Modified:
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavService.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/CollectionResource.java
jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/WebDavConstants.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java
jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/utils/TestUtils.java
Log:
EXOJCR-1032: Limited support WedDav ACL specification
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavService.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavService.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavService.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -256,4 +256,17 @@
* @return the instance of javax.ws.rs.core.Response
*/
Response search(String repoName, String repoPath, UriInfo baseURI, HierarchicalProperty body);
+
+ /**
+ * WebDAV ACL method according to protocol extension - Access Control Protocol: RFC3744
+ * More details here: <a href='http://www.webdav.org/specs/rfc3744.html'>Web Distributed
+ * Authoring and Versioning (WebDAV) Access Control Protocol</a>
+ * @param repoName repository name
+ * @param repoPath path in repository
+ * @param lockTokenHeader Lock-Token HTTP header
+ * @param ifHeader If- HTTP Header
+ * @param body Request body
+ * @return the instance of javax.ws.rs.core.Response
+ */
+ Response acl(String repoName, String repoPath, String lockTokenHeader, String ifHeader, HierarchicalProperty body);
}
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -27,6 +27,7 @@
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.app.ThreadLocalSessionProviderService;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
+import org.exoplatform.services.jcr.webdav.command.AclCommand;
import org.exoplatform.services.jcr.webdav.command.CopyCommand;
import org.exoplatform.services.jcr.webdav.command.DeleteCommand;
import org.exoplatform.services.jcr.webdav.command.GetCommand;
@@ -51,6 +52,7 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.ExtHttpHeaders;
+import org.exoplatform.services.rest.ext.webdav.method.ACL;
import org.exoplatform.services.rest.ext.webdav.method.CHECKIN;
import org.exoplatform.services.rest.ext.webdav.method.CHECKOUT;
import org.exoplatform.services.rest.ext.webdav.method.COPY;
@@ -935,7 +937,7 @@
+ "<exo:xpath xmlns:exo=\"http://exoplatform.com/jcr\"/>";
return Response.ok().header(ExtHttpHeaders.ALLOW, /* allowCommands */ALLOW).header(ExtHttpHeaders.DAV,
- "1, 2, ordered-collections").header(ExtHttpHeaders.DASL, DASL_VALUE).header(ExtHttpHeaders.MSAUTHORVIA, "DAV")
+ "1, 2, ordered-collections, access-control").header(ExtHttpHeaders.DASL, DASL_VALUE).header(ExtHttpHeaders.MSAUTHORVIA, "DAV")
.build();
}
@@ -1261,6 +1263,41 @@
}
/**
+ * {@inheritDoc}
+ */
+ @ACL
+ @Path("/{repoName}/{repoPath:.*}/")
+ public Response acl(@PathParam("repoName") String repoName, @PathParam("repoPath") String repoPath,
+ @HeaderParam(ExtHttpHeaders.LOCKTOKEN) String lockTokenHeader, @HeaderParam(ExtHttpHeaders.IF) String ifHeader,
+ HierarchicalProperty body)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("ACL " + repoName + "/" + repoPath);
+ }
+
+ repoPath = normalizePath(repoPath);
+
+ try
+ {
+ List<String> lockTokens = lockTokens(lockTokenHeader, ifHeader);
+ Session session = session(repoName, workspaceName(repoPath), lockTokens);
+ return new AclCommand().acl(session, path(repoPath), body);
+ }
+
+ catch (NoSuchWorkspaceException exc)
+ {
+ log.error("NoSuchWorkspace. " + exc.getMessage());
+ return Response.status(HTTPStatus.NOT_FOUND).entity(exc.getMessage()).build();
+ }
+ catch (Exception exc)
+ {
+ log.error(exc.getMessage(), exc);
+ return Response.status(HTTPStatus.INTERNAL_ERROR).entity(exc.getMessage()).build();
+ }
+ }
+
+ /**
* Gives access to the current session.
*
* @param repoName repository name
Added: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/AclCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/AclCommand.java (rev 0)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/AclCommand.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -0,0 +1,317 @@
+/**
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package org.exoplatform.services.jcr.webdav.command;
+
+import org.exoplatform.common.http.HTTPStatus;
+import org.exoplatform.common.util.HierarchicalProperty;
+import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.webdav.command.acl.ACLProperties;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.security.IdentityConstants;
+
+import java.security.AccessControlException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * Created by The eXo Platform SAS.
+ * ACL method implementation for Web Distributed Authoring and Versioning (WebDAV)
+ * protocol extension - Access Control Protocol: RFC3744.
+ *
+ * @author <a href="mailto:gavrikvetal@gmail.com">Vitaliy Gulyy</a>
+ * @version $
+ */
+
+public class AclCommand
+{
+
+ /**
+ * logger.
+ */
+ private static Log log = ExoLogger.getLogger(AclCommand.class);
+
+ /**
+ * Applies changes for JCR node's {@link AccessControlList}
+ * according to WebDAV ACL method request body represented by {@link HierarchicalProperty}
+ * @param session - actual session
+ * @param path - absolute path to jcr node
+ * @param requestBody - tree like structure to contain ACL method request body
+ * @return response - http response for ACL method request
+ */
+ public Response acl(Session session, String path, HierarchicalProperty requestBody)
+ {
+ NodeImpl node;
+ try
+ {
+ node = (NodeImpl)session.getItem(path);
+
+ boolean isSessionToBeSaved = false;
+
+ boolean nodeIsNotCheckedOut = node.isNodeType("mix:versionable") && !node.isCheckedOut();
+
+ // to set ACL the node necessarily must be exo:owneable
+ if (!node.isNodeType("exo:owneable"))
+ {
+ if (nodeIsNotCheckedOut)
+ {
+ node.checkout();
+ }
+ node.addMixin("exo:owneable");
+ isSessionToBeSaved = true;
+ }
+
+ // to set ACL the node necessarily must be exo:privilegeable
+ if (!node.isNodeType("exo:privilegeable"))
+ {
+ if (nodeIsNotCheckedOut)
+ {
+ node.checkout();
+ }
+ node.addMixin("exo:privilegeable");
+ isSessionToBeSaved = true;
+ }
+
+ if (isSessionToBeSaved)
+ {
+ session.save();
+ if (nodeIsNotCheckedOut)
+ {
+ node.checkin();
+ session.save();
+ }
+ }
+
+
+ changeNodeACL(node, requestBody);
+
+ }
+ catch (PathNotFoundException e)
+ {
+ return Response.status(HTTPStatus.NOT_FOUND).entity(e.getMessage()).build();
+ }
+ catch (RepositoryException exc)
+ {
+ log.error(exc.getMessage(), exc);
+ return Response.status(HTTPStatus.INTERNAL_ERROR).entity(exc.getMessage()).build();
+ }
+ catch (AccessControlException exc)
+ {
+ log.error(exc.getMessage(), exc);
+ return Response.status(HTTPStatus.FORBIDDEN).entity(exc.getMessage()).build();
+ }
+ catch (IllegalArgumentException exc)
+ {
+ log.error(exc.getMessage(), exc);
+ return Response.status(HTTPStatus.BAD_REQUEST).entity(exc.getMessage()).build();
+ }
+ catch (Exception exc)
+ {
+ log.error(exc.getMessage(), exc);
+ return Response.status(HTTPStatus.BAD_REQUEST).build();
+ }
+
+ return Response.status(HTTPStatus.OK).build();
+ }
+
+ /**
+ * Changes JCR node ACL by addition or removal mentioned in {@link HierarchicalProperty} requestBody permissions.
+ * @param node - node to change its ACL
+ * @param requestBody - tree like structure to contain ACL method request body
+ * @throws AccessControlException
+ * @throws RepositoryException
+ */
+ private void changeNodeACL(NodeImpl node, HierarchicalProperty requestBody) throws AccessControlException,
+ RepositoryException
+ {
+ Map<String, String[]> permissionsToGrant = new HashMap<String, String[]>();
+ Map<String, String[]> permissionsToDeny = new HashMap<String, String[]>();
+
+ for (HierarchicalProperty ace : requestBody.getChildren())
+ {
+
+ HierarchicalProperty principalProperty = ace.getChild(ACLProperties.PRINCIPAL);
+ // each ace element must contain principal element
+ // TODO invert element is not implemented
+ // <!ELEMENT ace ((principal | invert), (grant|deny), protected?, inherited?)>
+ if (principalProperty == null)
+ {
+ throw new IllegalArgumentException("Malformed ace element (seems that no principal element specified)");
+ }
+
+ String principal;
+
+ if (principalProperty.getChild(ACLProperties.HREF) != null)
+ {
+ principal = principalProperty.getChild(ACLProperties.HREF).getValue();
+ }
+ else if (principalProperty.getChild(ACLProperties.ALL) != null)
+ {
+ principal = IdentityConstants.ANY;
+ }
+
+ // each principal must contain either href or all element
+ // TODO authenticated, unauthenticated, property, self are not implemented
+ // <!ELEMENT principal (href | all | authenticated | unauthenticated | property | self)>
+ else
+ {
+ throw new IllegalArgumentException("Malformed principal element");
+ }
+
+ HierarchicalProperty denyProperty = ace.getChild(ACLProperties.DENY);
+ HierarchicalProperty grantProperty = ace.getChild(ACLProperties.GRANT);
+
+ // each ace element must contain at least one grant or deny property
+ // <!ELEMENT ace ((principal | invert), (grant|deny), protected?, inherited?)>
+ if (denyProperty == null && grantProperty == null)
+ {
+ throw new IllegalArgumentException("Malformed ace element (seems that no deny|grant element specified)");
+ }
+
+ if (denyProperty != null)
+ {
+ permissionsToDeny.put(principal, getPermissions(denyProperty));
+ }
+
+ if (grantProperty != null)
+ {
+ permissionsToGrant.put(principal, getPermissions(grantProperty));
+ }
+
+ // request must not grant and deny the same privilege in a single ace
+ // http://www.webdav.org/specs/rfc3744.html#rfc.section.8.1.5
+ if (permissionsToDeny.size() != 0 && permissionsToGrant.size() != 0)
+ {
+ for (String denyPermission : permissionsToDeny.get(principal))
+ {
+ for (String grantPermission : permissionsToGrant.get(principal))
+ {
+ if (denyPermission.equals(grantPermission))
+ {
+ throw new IllegalArgumentException(
+ "Malformed ace element (seems that a client is trying to grant and denay the same privilege in a single ace)");
+
+ }
+ }
+ }
+ }
+ }
+ if (permissionsToDeny.size() != 0)
+ {
+ for (Entry<String, String[]> entry : permissionsToDeny.entrySet())
+ {
+ for (String p : entry.getValue())
+ {
+ node.removePermission(entry.getKey(), p);
+ }
+ }
+ node.getSession().save();
+ }
+ if (permissionsToGrant.size() != 0)
+ {
+ for (Entry<String, String[]> entry : permissionsToGrant.entrySet())
+ {
+ node.setPermission(entry.getKey(), entry.getValue());
+ }
+ node.getSession().save();
+ }
+ }
+
+ /**
+ * Processes {@link HierarchicalProperty} instance, representing grant or deny
+ * element of ACL request body, to pull out permissions set represented as {@link String} array.
+ * @param property
+ * @return String[] - permissions set
+ */
+ private String[] getPermissions(HierarchicalProperty property)
+ {
+ Set<String> permissionsToBeChanged = new HashSet<String>();
+
+ // grant|deny element must have at least one privilege element
+ // <!ELEMENT grant (privilege+)>
+ // <!ELEMENT deny (privilege+)>
+ if (property.getChildren().size() == 0)
+ {
+ throw new IllegalArgumentException("Malformed grant|deny element (seems that no privilige is specified)");
+ }
+
+ for (HierarchicalProperty propertyRunner : property.getChildren())
+ {
+ HierarchicalProperty permissionProperty;
+
+ // obviously privilege must be single named
+ // <!ELEMENT privilege ANY>
+ if (ACLProperties.PRIVILEGE.equals(propertyRunner.getName()))
+ {
+ if (propertyRunner.getChildren().size() > 1)
+ {
+ throw new IllegalArgumentException(
+ "Malformed privilege name (element privilege must contain only one element)");
+ }
+ permissionProperty = propertyRunner.getChild(0);
+ }
+ else
+ {
+ permissionProperty = propertyRunner;
+ }
+
+ if (ACLProperties.READ.equals(permissionProperty.getName()))
+ {
+ permissionsToBeChanged.add(PermissionType.READ);
+
+ }
+ else if (ACLProperties.WRITE.equals(permissionProperty.getName()))
+ {
+ permissionsToBeChanged.add(PermissionType.ADD_NODE);
+ permissionsToBeChanged.add(PermissionType.SET_PROPERTY);
+ permissionsToBeChanged.add(PermissionType.REMOVE);
+
+ }
+ else if (ACLProperties.ALL.equals(permissionProperty.getName()))
+ {
+ permissionsToBeChanged.add(PermissionType.READ);
+ permissionsToBeChanged.add(PermissionType.ADD_NODE);
+ permissionsToBeChanged.add(PermissionType.SET_PROPERTY);
+ permissionsToBeChanged.add(PermissionType.REMOVE);
+ }
+ // in case privilege with specified name is unsupported
+ // or simply incorrect privilege name
+ else
+ {
+ throw new IllegalArgumentException("Malformed privilege element (unsupported privilege name)");
+ }
+ }
+ return permissionsToBeChanged.toArray(new String[0]);
+
+ }
+
+}
Added: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/acl/ACLProperties.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/acl/ACLProperties.java (rev 0)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/acl/ACLProperties.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -0,0 +1,236 @@
+/**
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package org.exoplatform.services.jcr.webdav.command.acl;
+
+import org.exoplatform.common.util.HierarchicalProperty;
+import org.exoplatform.services.jcr.access.AccessControlEntry;
+import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.webdav.util.PropertyConstants;
+import org.exoplatform.services.security.IdentityConstants;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.xml.namespace.QName;
+
+/**
+ * Created by The eXo Platform SAS.
+ * Utility class to simplify operations with ACL properties of JCR nodes
+ * for PROPFIND method.
+ *
+ * @author <a href="mailto:gavrikvetal@gmail.com">Vitaliy Gulyy</a>
+ * @version $
+ */
+
+public class ACLProperties
+{
+ /**
+ * Defines the name of the element corresponding to a protected property that specifies
+ * the list of access control entries.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl">here</a>.
+ */
+ public final static QName ACL = new QName("DAV:", "acl");
+
+ /**
+ * Defines the name of the element corresponding to a property that the set of privileges
+ * to be either granted or denied to a single principal.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl">here</a>.
+ */
+ public final static QName ACE = new QName("DAV:", "ace");
+
+ /**
+ * Defines the name of the element corresponding to a property which identifies the principal
+ * to which this ACE applies.
+ * More details can be found <a href='http://www.webdav.org/specs/rfc3744.html#principals'>here</a>
+ * and <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl">here</a>.
+ */
+ public final static QName PRINCIPAL = new QName("DAV:", "principal");
+
+ /**
+ * Defines the name of the element corresponding to a property that can be either an aggregate
+ * privilege that contains the entire set of privileges that can be applied to the resource or
+ * an aggregate principal that contains the entire set of principals.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PRIVILEGE_all">here</a>.
+ */
+ public final static QName ALL = new QName("DAV:", "all");
+
+ /**
+ * Defines the name of the element corresponding to a property which is used to uniquely
+ * identify a principal.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_principal-URL">here</a>.
+ */
+ public final static QName HREF = new QName("DAV:", "href");
+
+ /**
+ * Defines the name of the element containing privilege's name.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#privileges">here</a>.
+ */
+ public final static QName PRIVILEGE = new QName("DAV:", "privilege");
+
+ /**
+ * Defines the name of the element containing privileges to be granted.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#rfc.section.5.5.2">here</a>.
+ */
+ public final static QName GRANT = new QName("DAV:", "grant");
+
+ /**
+ * Defines the name of the element containing privileges to be denied.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#rfc.section.5.5.2">here</a>.
+ */
+ public final static QName DENY = new QName("DAV:", "deny");
+
+ /**
+ * Defines the name of the element corresponding to write privilege
+ * which in current implementation aggregate:
+ * ADD_NODE, SET_PROPERTY, REMOVE permissions.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#privileges">here</a>.
+ */
+ public final static QName WRITE = new QName("DAV:", "write");
+
+ /**
+ * Defines the name of the element corresponding to read privilege
+ * which in current implementation aggregate:
+ * READ permission.
+ * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#privileges">here</a>.
+ */
+ public final static QName READ = new QName("DAV:", "read");
+
+ /**
+ * Gets {@link AccessControlList} and transform it to DAV:acl property view
+ * represented by a {@link HierarchicalProperty} instance.
+ * @param node - {@link NodeImpl} from which we are to get an ACL
+ * @return HierarchicalProperty - tree like structure corresponding to an DAV:acl property
+ * @throws RepositoryException
+ */
+ public static HierarchicalProperty getACL(NodeImpl node) throws RepositoryException
+ {
+ HierarchicalProperty property = new HierarchicalProperty(ACL);
+
+ AccessControlList acl = node.getACL();
+
+ HashMap<String, List<String>> principals = new HashMap<String, List<String>>();
+
+ List<AccessControlEntry> entryList = acl.getPermissionEntries();
+ for (AccessControlEntry entry : entryList)
+ {
+ String principal = entry.getIdentity();
+ String grant = entry.getPermission();
+
+ List<String> grantList = principals.get(principal);
+ if (grantList == null)
+ {
+ grantList = new ArrayList<String>();
+ principals.put(principal, grantList);
+ }
+
+ grantList.add(grant);
+ }
+
+ Iterator<String> principalIter = principals.keySet().iterator();
+ while (principalIter.hasNext())
+ {
+ HierarchicalProperty aceProperty = new HierarchicalProperty(ACE);
+
+ String curPrincipal = principalIter.next();
+
+ aceProperty.addChild(getPrincipalProperty(curPrincipal));
+
+ aceProperty.addChild(getGrantProperty(principals.get(curPrincipal)));
+
+ property.addChild(aceProperty);
+ }
+
+ return property;
+ }
+
+ /**
+ * Transform owner got from node's {@link AccessControlList}
+ * to tree like {@link HierarchicalProperty} instance to use in PROPFIND response body
+ * @param node
+ * @return {@link HierarchicalProperty} representation of node owner
+ * @throws RepositoryException
+ */
+ public static HierarchicalProperty getOwner(NodeImpl node) throws RepositoryException
+ {
+ HierarchicalProperty ownerProperty = new HierarchicalProperty(PropertyConstants.OWNER);
+
+ HierarchicalProperty href = new HierarchicalProperty(new QName("DAV:", "href"));
+ href.setValue(node.getACL().getOwner());
+
+ ownerProperty.addChild(href);
+
+ return ownerProperty;
+ }
+
+ // TODO support for DAV:supported-privilege-set property
+ // specified here: http://www.webdav.org/specs/rfc3744.html#PROPERTY_supported-privilege-set
+ // TODO support for DAV:acl-restrictions property
+ // specified here: http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl-restrictions
+ // TODO support for DAV:current-user-privilege-set property
+ // specified here: http://www.webdav.org/specs/rfc3744.html#PROPERTY_current-user-privilege-set
+
+ private static HierarchicalProperty getPrincipalProperty(String principal)
+ {
+ HierarchicalProperty principalProperty = new HierarchicalProperty(PRINCIPAL);
+
+ if (IdentityConstants.ANY.equals(principal))
+ {
+ HierarchicalProperty all = new HierarchicalProperty(ALL);
+ principalProperty.addChild(all);
+ }
+ else
+ {
+ HierarchicalProperty href = new HierarchicalProperty(HREF);
+ href.setValue(principal);
+ principalProperty.addChild(href);
+ }
+
+ return principalProperty;
+ }
+
+ private static HierarchicalProperty getGrantProperty(List<String> grantList)
+ {
+ HierarchicalProperty grant = new HierarchicalProperty(GRANT);
+
+ if (grantList.contains(PermissionType.ADD_NODE) || grantList.contains(PermissionType.SET_PROPERTY)
+ || grantList.contains(PermissionType.REMOVE))
+ {
+ HierarchicalProperty privilege = new HierarchicalProperty(PRIVILEGE);
+ privilege.addChild(new HierarchicalProperty(WRITE));
+ grant.addChild(privilege);
+ }
+
+ if (grantList.contains(PermissionType.READ))
+ {
+ HierarchicalProperty privilege = new HierarchicalProperty(PRIVILEGE);
+ privilege.addChild(new HierarchicalProperty(READ));
+ grant.addChild(privilege);
+ }
+
+ return grant;
+ }
+
+}
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/CollectionResource.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/CollectionResource.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/CollectionResource.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -20,6 +20,8 @@
import org.exoplatform.common.util.HierarchicalProperty;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.webdav.command.acl.ACLProperties;
import org.exoplatform.services.jcr.webdav.util.TextUtil;
import org.exoplatform.services.jcr.webdav.xml.WebDavNamespaceContext;
import org.exoplatform.services.log.ExoLogger;
@@ -311,6 +313,14 @@
throw new PathNotFoundException();
}
+ else if (name.equals(ACLProperties.ACL))
+ {
+ return ACLProperties.getACL((NodeImpl)node);
+ }
+ else if (name.equals(OWNER))
+ {
+ return ACLProperties.getOwner((NodeImpl)node);
+ }
else
{
Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -19,7 +19,9 @@
package org.exoplatform.services.jcr.webdav.resource;
import org.exoplatform.common.util.HierarchicalProperty;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.webdav.WebDavConst;
+import org.exoplatform.services.jcr.webdav.command.acl.ACLProperties;
import org.exoplatform.services.jcr.webdav.xml.WebDavNamespaceContext;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -292,6 +294,14 @@
{
return supportedMethodSet();
}
+ else if (name.equals(ACLProperties.ACL))
+ {
+ return ACLProperties.getACL((NodeImpl)node);
+ }
+ else if (name.equals(OWNER))
+ {
+ return ACLProperties.getOwner((NodeImpl)node);
+ }
else
{
try
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/WebDavConstants.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/WebDavConstants.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/WebDavConstants.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -208,6 +208,8 @@
public static final String ORDERPATCH = "ORDERPATCH";
+ public static final String ACL = "ACL";
+
}
}
Added: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestAclCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestAclCommand.java (rev 0)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestAclCommand.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -0,0 +1,780 @@
+/**
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+package org.exoplatform.services.jcr.webdav.command;
+
+import org.exoplatform.common.http.HTTPStatus;
+import org.exoplatform.services.jcr.access.AccessControlEntry;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.webdav.BaseStandaloneTest;
+import org.exoplatform.services.jcr.webdav.WebDavConstants;
+import org.exoplatform.services.rest.impl.ContainerResponse;
+import org.exoplatform.services.rest.impl.EnvironmentContext;
+import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
+import org.exoplatform.services.rest.impl.RequestHandlerImpl;
+import org.exoplatform.services.rest.tools.DummySecurityContext;
+import org.exoplatform.services.rest.tools.ResourceLauncher;
+import org.exoplatform.services.security.IdentityConstants;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.SecurityContext;
+
+
+/**
+ *
+ * Created by The eXo Platform SAS .
+ *
+ * @author <a href="mailto:gavrikvetal@gmail.com">Vitaliy Gulyy</a>
+ * @version $
+ */
+
+public class TestAclCommand extends BaseStandaloneTest
+{
+
+ private final String USER_ONE = "Oksana";
+
+ private final String USER_TWO = "Anya";
+
+ private final String USER_ROOT = "root";
+
+ private final String BASE_URI = "http://localhost";
+
+ private final String TEST_NODE_NAME = "test_node" + System.currentTimeMillis();
+
+ /**
+ * Here we check for correct addition of privileges to users,
+ * besides, we check for correct addition of mix:pribilegeable.
+ * @throws Exception
+ */
+ public void testSetACLForTwoUsersOnNonPrivilegeableResource() throws Exception
+ {
+
+
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + USER_ONE + "</D:href>" + "</D:principal>" + "<D:grant>"
+ + "<D:privilege><D:write/></D:privilege>" + "</D:grant>" + "</D:ace>" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + USER_TWO + "</D:href>" + "</D:principal>" + "<D:grant>" + "<D:write/>" + "</D:grant>"
+ + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.OK, response.getStatus());
+
+ session.refresh(false);
+ testNode = (NodeImpl)root.getNode(TEST_NODE_NAME);
+ testNode.setPermission(USER_ROOT, new String[]{"read", "add_node", "set_property", "remove"});
+ testNode.removePermission(IdentityConstants.ANY);
+ session.save();
+
+ checkPermissionSet(testNode, USER_ONE, PermissionType.ADD_NODE);
+ checkPermissionSet(testNode, USER_ONE, PermissionType.SET_PROPERTY);
+ checkPermissionSet(testNode, USER_ONE, PermissionType.REMOVE);
+
+ checkPermissionSet(testNode, USER_TWO, PermissionType.ADD_NODE);
+ checkPermissionSet(testNode, USER_TWO, PermissionType.SET_PROPERTY);
+ checkPermissionSet(testNode, USER_TWO, PermissionType.REMOVE);
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct write permission removal from
+ * the mix:versionable and exo:privelegeable node. We add permissions manually
+ * and then remove them via ACL method. After this operation they are expected
+ * to be removed from node ACL
+ * @throws Exception
+ */
+ public void testDenyPermissionOnPrivilegeableResource() throws Exception
+ {
+
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ testNode.addMixin("mix:versionable");
+ testNode.addMixin("exo:privilegeable");
+ testNode.setPermission(USER_ROOT, new String[]{"read", "add_node", "set_property", "remove"});
+ testNode.setPermission(USER_ONE, new String[]{"add_node", "set_property", "remove"});
+ testNode.removePermission(IdentityConstants.ANY);
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + USER_ONE + "</D:href>" + "</D:principal>" + "<D:deny>" + "<D:privilege><D:write/></D:privilege>"
+ + "</D:deny>" + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.OK, response.getStatus());
+
+ session.refresh(false);
+ testNode = (NodeImpl)root.getNode(TEST_NODE_NAME);
+
+ checkPermissionRemoved(testNode, USER_ONE, PermissionType.ADD_NODE);
+ checkPermissionRemoved(testNode, USER_ONE, PermissionType.SET_PROPERTY);
+ checkPermissionRemoved(testNode, USER_ONE, PermissionType.REMOVE);
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct processing of knowingly malformed request.
+ * We are trying to grant and deny the same privilege and expect
+ * BAD_REQUEST status.
+ * @throws Exception
+ */
+ public void testDenyAndGrantInASingleACE() throws Exception
+ {
+
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ testNode.addMixin("mix:versionable");
+ testNode.addMixin("exo:privilegeable");
+ testNode.setPermission(USER_ROOT, new String[]{"read", "add_node", "set_property", "remove"});
+ testNode.removePermission(IdentityConstants.ANY);
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + USER_ONE + "</D:href>" + "</D:principal>" + "<D:deny>"
+ + "<D:privilege><D:write/></D:privilege>" + "</D:deny>" + "<D:grant>"
+ + "<D:privilege><D:write/></D:privilege>" + "</D:grant>" + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we test for correct setting all permissions for ANY user.
+ * We create a node without all permissions for ANY user and expect
+ * them to appear after receiving a response.
+ * @throws Exception
+ */
+ public void testSetAllPermissionsForAllUsersOnPrivilegeableResource() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ session.save();
+
+ Map<String, String[]> defaultPermissions = new HashMap<String, String[]>();
+ String[] initPermissions =
+ new String[]{PermissionType.ADD_NODE, PermissionType.READ, PermissionType.SET_PROPERTY};
+ defaultPermissions.put(USER_TWO, initPermissions);
+ testNode.setPermissions(defaultPermissions);
+ session.save();
+
+ System.out.println("Node before: " + testNode);
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant>" + "<D:privilege><D:all/></D:privilege>" + "</D:grant>"
+ + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI,
+ headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.OK, response.getStatus());
+
+ session.refresh(false);
+ testNode = (NodeImpl)root.getNode(TEST_NODE_NAME);
+
+ System.out.println("Node after: " + testNode);
+
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.ADD_NODE);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.SET_PROPERTY);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.REMOVE);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.READ);
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct processing of knowingly malformed grant element
+ * in ACL request body.
+ * @throws Exception
+ */
+ public void testWrongGrantElementAceElementInAclBody() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ testNode.setPermission(USER_ROOT, new String[]{"read", "add_node", "set_property", "remove"});
+ testNode.removePermission(IdentityConstants.ANY);
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant>" + "<D:privilege><D:read /><D:write /></D:privilege>"
+ + "</D:grant>" + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant></D:grant>" + "</D:ace>" + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant><D:privilege></D:privilege></D:grant>" + "</D:ace>"
+ + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct processing of knowingly malformed ace element
+ * in ACL request body.
+ * @throws Exception
+ */
+ public void testWrongAceElementInAclBody() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ session.save();
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ session.save();
+
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI,
+ headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:grant>" + "<D:privilege><D:read /><D:write /></D:privilege>"
+ + "</D:grant>" + "</D:ace>" + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI,
+ headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "</D:ace>" + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI,
+ headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct processing of knowingly malformed principal element
+ * in ACL request body.
+ * @throws Exception
+ */
+ public void testWrongPrincipalElementInAclBody() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ session.save();
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "</D:principal>" + "<D:grant>" + "<D:privilege><D:read /><D:write /></D:privilege>" + "</D:grant>"
+ + "</D:ace>" + "</D:acl>";
+
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant>" + "<D:privilege><D:read /><D:write /></D:privilege>"
+ + "</D:grant>" + "</D:ace>" + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + "</D:href>" + "</D:principal>" + "<D:grant>"
+ + "<D:privilege><D:read /><D:write /></D:privilege>" + "</D:grant>" + "</D:ace>" + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + USER_ONE + "</D:href>" + "<href>" + USER_TWO + "</href>" + "</D:principal>" + "<D:grant>"
+ + "<D:privilege><D:read /><D:write /></D:privilege>" + "</D:grant>" + "</D:ace>" + "</D:acl>";
+
+ response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.BAD_REQUEST, response.getStatus());
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct ACL setting for mix:versionable, exo:owneable, exo:privilegeable,
+ * checked out node. Node is manually set to have any permission for user "root". Node expected
+ * to have any permission for any user
+ * after ACL method completion.
+ * @throws Exception
+ */
+ public void testSetAclForVersionableOwneablePrivilegeableCheckedOutNode() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ session.save();
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ testNode.addMixin("mix:versionable");
+ testNode.setPermission(USER_ROOT, new String[]{"read", "add_node", "set_property", "remove"});
+ testNode.removePermission(IdentityConstants.ANY);
+ session.save();
+
+ //let us make node version
+ testNode.checkin();
+ testNode.checkout();
+
+ session.save();
+
+ //now let us try to grant all permissions for any user
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant>" + "<D:privilege><D:all/></D:privilege>" + "</D:grant>"
+ + "</D:ace>" + "</D:acl>";
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.OK, response.getStatus());
+
+ session.refresh(false);
+ testNode = (NodeImpl)root.getNode(TEST_NODE_NAME);
+
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.ADD_NODE);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.SET_PROPERTY);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.REMOVE);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.READ);
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct ACL setting for mix:versionable, checkedin node. Node is manually set
+ * to have any permission for user USER_ONE. Node expected to get checked out, added corresponding mixins,
+ * and to set any permission for any user.
+ * after ACL method completion.
+ * @throws Exception
+ */
+ public void testSetAclForVersionableCheckedInNode() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ session.save();
+ testNode.addMixin("mix:versionable");
+ session.save();
+
+ //let us make node version
+ testNode.checkin();
+ testNode.checkout();
+ testNode.checkin();
+ session.save();
+
+ //now let us try to grant all permissions for user USER_ONE
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:href>" + USER_ONE + "</D:href>" + "</D:principal>" + "<D:grant>"
+ + "<D:privilege><D:all/></D:privilege>" + "</D:grant>"
+ + "</D:ace>" + "</D:acl>";
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.OK, response.getStatus());
+
+ session.refresh(false);
+ testNode = (NodeImpl)root.getNode(TEST_NODE_NAME);
+
+ checkPermissionSet(testNode, USER_ONE, PermissionType.ADD_NODE);
+ checkPermissionSet(testNode, USER_ONE, PermissionType.SET_PROPERTY);
+ checkPermissionSet(testNode, USER_ONE, PermissionType.REMOVE);
+ checkPermissionSet(testNode, USER_ONE, PermissionType.READ);
+
+ testNode.remove();
+ session.save();
+ }
+
+ /**
+ * Here we check for correct ACL setting for mix:versionable, exo:owneable, exo:privilegeable,
+ * checked in node. Node is manually set to have any permission for user "root". Node expected
+ * to have any permission for any user
+ * after ACL method completion.
+ * @throws Exception
+ */
+ public void testSetAclForVersionableOwneablePrivilegeableCheckedInNode() throws Exception
+ {
+ NodeImpl testNode = (NodeImpl)root.addNode(TEST_NODE_NAME, "nt:folder");
+ session.save();
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ testNode.addMixin("mix:versionable");
+ testNode.setPermission(USER_ROOT, new String[]{"read", "add_node", "set_property", "remove"});
+ testNode.removePermission(IdentityConstants.ANY);
+ session.save();
+
+ //let us make node version
+ testNode.checkin();
+ testNode.checkout();
+ testNode.checkin();
+
+ session.save();
+
+ //now let us try to grant all permissions for any user
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:acl xmlns:D=\"DAV:\">" + "<D:ace>" + "<D:principal>"
+ + "<D:all />" + "</D:principal>" + "<D:grant>" + "<D:privilege><D:all/></D:privilege>" + "</D:grant>"
+ + "</D:ace>" + "</D:acl>";
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+ ContainerResponse response =
+ launcher.service(WebDavConstants.WebDAVMethods.ACL, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.OK, response.getStatus());
+
+ session.refresh(false);
+ testNode = (NodeImpl)root.getNode(TEST_NODE_NAME);
+
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.ADD_NODE);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.SET_PROPERTY);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.REMOVE);
+ checkPermissionSet(testNode, IdentityConstants.ANY, PermissionType.READ);
+
+ testNode.remove();
+ session.save();
+ }
+
+ private void checkPermissionSet(NodeImpl node, String identity, String permission) throws RepositoryException
+ {
+ for (AccessControlEntry entry : node.getACL().getPermissionEntries())
+ {
+ if (entry.getIdentity().equals(identity) && entry.getPermission().equals(permission))
+ {
+ return;
+ }
+ }
+
+ fail();
+ }
+
+ private void checkPermissionRemoved(NodeImpl node, String identity, String permission) throws RepositoryException
+ {
+ for (AccessControlEntry entry : node.getACL().getPermissionEntries())
+ {
+ if (entry.getIdentity().equals(identity) && entry.getPermission().equals(permission))
+ {
+ fail();
+ }
+ }
+ }
+
+ @Override
+ protected String getRepositoryName()
+ {
+ return null;
+ }
+
+}
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -20,22 +20,37 @@
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.common.util.HierarchicalProperty;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.webdav.BaseStandaloneTest;
import org.exoplatform.services.jcr.webdav.Depth;
import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods;
+import org.exoplatform.services.jcr.webdav.command.acl.ACLProperties;
import org.exoplatform.services.jcr.webdav.command.propfind.PropFindResponseEntity;
import org.exoplatform.services.jcr.webdav.utils.TestUtils;
+import org.exoplatform.services.rest.ext.provider.HierarchicalPropertyEntityProvider;
import org.exoplatform.services.rest.impl.ContainerResponse;
+import org.exoplatform.services.rest.impl.EnvironmentContext;
import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
+import org.exoplatform.services.rest.impl.RequestHandlerImpl;
+import org.exoplatform.services.rest.tools.DummySecurityContext;
+import org.exoplatform.services.rest.tools.ResourceLauncher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import javax.jcr.Node;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-
+import javax.ws.rs.core.SecurityContext;
+import javax.xml.namespace.QName;
/**
* Created by The eXo Platform SAS Author : Dmytro Katayev
* work.visor.ck(a)gmail.com Aug 13, 2008
@@ -51,6 +66,12 @@
private final String nt_webdave_file = "webdav:file";
+ private final String USER_ROOT = "root";
+
+ private final String USER_JOHN = "john";
+
+ private final String BASE_URI = "http://localhost";
+
private String propFindXML =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?><D:propfind xmlns:D=\"DAV:\">"
+ "<D:prop xmlns:webdav=\"http://www.exoplatform.org/jcr/webdav\">"
@@ -239,7 +260,178 @@
assertTrue(find.contains(authorValue));
}
+ /**
+ * Here we check for correct response for PROPFIND request.
+ * Response should not only contain an acl element with its properties
+ * (ace, principle, privelege, grant, etc.) but also be correctly composed and contain
+ * ACL information about user root.
+ * @throws Exception
+ */
+ public void testPropfindPermissionsOnRoot() throws Exception
+ {
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "0");
+ EnvironmentContext ctx = new EnvironmentContext();
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:propfind xmlns:D=\"DAV:\">" + "<D:prop>" + "<D:owner/>"
+ + "<D:acl/>" + "</D:prop>" + "</D:propfind>";
+
+ ContainerResponse response =
+ launcher.service(WebDAVMethods.PROPFIND, getPathWS(), BASE_URI, headers, request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.MULTISTATUS, response.getStatus());
+ assertNotNull(response.getEntity());
+
+ HierarchicalPropertyEntityProvider provider = new HierarchicalPropertyEntityProvider();
+ InputStream inputStream = TestUtils.getResponseAsStream(response);
+ HierarchicalProperty multistatus = provider.readFrom(null, null, null, null, null, inputStream);
+
+ assertEquals(new QName("DAV:", "multistatus"), multistatus.getName());
+ assertEquals(1, multistatus.getChildren().size());
+
+ HierarchicalProperty resourceProp = multistatus.getChildren().get(0);
+
+ HierarchicalProperty resourceHref = resourceProp.getChild(new QName("DAV:", "href"));
+ assertNotNull(resourceHref);
+ assertEquals(BASE_URI + getPathWS() + "/", resourceHref.getValue());
+
+ HierarchicalProperty propstatProp = resourceProp.getChild(new QName("DAV:", "propstat"));
+ HierarchicalProperty propProp = propstatProp.getChild(new QName("DAV:", "prop"));
+
+ HierarchicalProperty ownerProp = propProp.getChild(new QName("DAV:", "owner"));
+ HierarchicalProperty ownerHrefProp = ownerProp.getChild(new QName("DAV:", "href"));
+
+ assertEquals("__system", ownerHrefProp.getValue());
+
+ HierarchicalProperty aclProp = propProp.getChild(ACLProperties.ACL);
+ assertEquals(1, aclProp.getChildren().size());
+
+ HierarchicalProperty aceProp = aclProp.getChild(ACLProperties.ACE);
+ assertEquals(2, aceProp.getChildren().size());
+
+ HierarchicalProperty principalProp = aceProp.getChild(ACLProperties.PRINCIPAL);
+ assertEquals(1, principalProp.getChildren().size());
+
+ HierarchicalProperty allProp = principalProp.getChild(ACLProperties.ALL);
+ assertNotNull(allProp);
+
+ HierarchicalProperty grantProp = aceProp.getChild(ACLProperties.GRANT);
+ assertEquals(2, grantProp.getChildren().size());
+
+ HierarchicalProperty writeProp = grantProp.getChild(0).getChild(ACLProperties.WRITE);
+ assertNotNull(writeProp);
+ HierarchicalProperty readProp = grantProp.getChild(1).getChild(ACLProperties.READ);
+ assertNotNull(readProp);
+ }
+
+ /**
+ * Here we check for correct response for PROPFIND request.
+ * Response should contain all available acl information on current node, i.e.
+ * ace for user "__system", "john" etc.
+ * @throws Exception
+ */
+ public void testPropfindPropOwnerAndAclOnNode() throws Exception
+ {
+
+ NodeImpl testNode = (NodeImpl)root.addNode("test_acl_property", "nt:folder");
+ testNode.addMixin("exo:owneable");
+ testNode.addMixin("exo:privilegeable");
+ session.save();
+
+ Map<String, String[]> permissions = new HashMap<String, String[]>();
+
+ String userName = USER_JOHN;
+ permissions.put(userName, PermissionType.ALL);
+
+ testNode.setPermissions(permissions);
+ testNode.getSession().save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.putSingle("Depth", "1");
+ headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/xml; charset=\"utf-8\"");
+
+ EnvironmentContext ctx = new EnvironmentContext();
+
+ Set<String> adminRoles = new HashSet<String>();
+ adminRoles.add("administrators");
+
+ DummySecurityContext adminSecurityContext = new DummySecurityContext(new Principal()
+ {
+ public String getName()
+ {
+ return USER_ROOT;
+ }
+ }, adminRoles);
+
+ ctx.put(SecurityContext.class, adminSecurityContext);
+
+ RequestHandlerImpl handler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
+ ResourceLauncher launcher = new ResourceLauncher(handler);
+
+ String request =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "<D:propfind xmlns:D=\"DAV:\">" + "<D:prop>" + "<D:owner/>"
+ + "<D:acl/>" + "</D:prop>" + "</D:propfind>";
+
+ ContainerResponse cres =
+ launcher.service(WebDAVMethods.PROPFIND, getPathWS() + testNode.getPath(), BASE_URI, headers,
+ request.getBytes(), null, ctx);
+
+ assertEquals(HTTPStatus.MULTISTATUS, cres.getStatus());
+
+ HierarchicalPropertyEntityProvider provider = new HierarchicalPropertyEntityProvider();
+ InputStream inputStream = TestUtils.getResponseAsStream(cres);
+ HierarchicalProperty multistatus = provider.readFrom(null, null, null, null, null, inputStream);
+
+ assertEquals(new QName("DAV:", "multistatus"), multistatus.getName());
+ assertEquals(1, multistatus.getChildren().size());
+
+ HierarchicalProperty resourceProp = multistatus.getChildren().get(0);
+
+ HierarchicalProperty resourceHref = resourceProp.getChild(new QName("DAV:", "href"));
+ assertNotNull(resourceHref);
+ assertEquals(BASE_URI + getPathWS() + testNode.getPath() + "/", resourceHref.getValue());
+
+ HierarchicalProperty propstatProp = resourceProp.getChild(new QName("DAV:", "propstat"));
+ HierarchicalProperty propProp = propstatProp.getChild(new QName("DAV:", "prop"));
+
+ HierarchicalProperty aclProp = propProp.getChild(ACLProperties.ACL);
+ assertEquals(1, aclProp.getChildren().size());
+
+ HierarchicalProperty aceProp = aclProp.getChild(ACLProperties.ACE);
+ assertEquals(2, aceProp.getChildren().size());
+
+ HierarchicalProperty principalProp = aceProp.getChild(ACLProperties.PRINCIPAL);
+ assertEquals(1, principalProp.getChildren().size());
+
+ assertEquals(userName, principalProp.getChildren().get(0).getValue());
+
+ HierarchicalProperty grantProp = aceProp.getChild(ACLProperties.GRANT);
+ assertEquals(2, grantProp.getChildren().size());
+
+ HierarchicalProperty writeProp = grantProp.getChild(0).getChild(ACLProperties.WRITE);
+ assertNotNull(writeProp);
+ HierarchicalProperty readProp = grantProp.getChild(1).getChild(ACLProperties.READ);
+ assertNotNull(readProp);
+
+ }
+
@Override
protected String getRepositoryName()
{
Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/utils/TestUtils.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/utils/TestUtils.java 2011-01-21 07:52:30 UTC (rev 3824)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/utils/TestUtils.java 2011-01-21 08:01:45 UTC (rev 3825)
@@ -21,10 +21,13 @@
import org.exoplatform.common.http.client.HTTPConnection;
import org.exoplatform.services.jcr.webdav.WebDavConst;
import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDav;
+import org.exoplatform.services.jcr.webdav.command.propfind.PropFindResponseEntity;
import org.exoplatform.services.jcr.webdav.util.TextUtil;
+import org.exoplatform.services.rest.impl.ContainerResponse;
import org.w3c.dom.Document;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -227,4 +230,16 @@
return content.getMixinNodeTypes();
}
+ public static InputStream getResponseAsStream(ContainerResponse response) throws IOException
+ {
+ if (response.getEntity() instanceof PropFindResponseEntity)
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ((PropFindResponseEntity)response.getEntity()).write(outputStream);
+ return new ByteArrayInputStream(outputStream.toByteArray());
+ }
+
+ return null;
+ }
+
}
13 years, 4 months
exo-jcr SVN: r3824 - ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/webdav/method.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2011-01-21 02:52:30 -0500 (Fri, 21 Jan 2011)
New Revision: 3824
Added:
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java
Log:
EXOJCR-1032: Limited support WedDav ACL specification
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java 2011-01-21 07:52:30 UTC (rev 3824)
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+
+
+package org.exoplatform.services.rest.ext.webdav.method;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.ws.rs.HttpMethod;
+
+/**
+ *
+ * Created by The eXo Platform SAS .
+ *
+ * @author <a href="mailto:gavrikvetal@gmail.com">Vitaliy Gulyy</a>
+ * @version $
+ */
+
+(a)Target(ElementType.METHOD)
+(a)Retention(RetentionPolicy.RUNTIME)
+@HttpMethod("ACL")
+public @interface ACL {
+
+}
13 years, 4 months
exo-jcr SVN: r3823 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-01-20 11:18:10 -0500 (Thu, 20 Jan 2011)
New Revision: 3823
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
Log:
EXOJCR-1166 : The document Repository or Workspace initialization from backup over BackupWokspaceInitializer was added.
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2011-01-20 14:21:42 UTC (rev 3822)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/backup/exojcr-backup-service.xml 2011-01-20 16:18:10 UTC (rev 3823)
@@ -380,6 +380,168 @@
</itemizedlist></para>
</section>
</section>
+
+ <section>
+ <title>Repository and Workspace initialization from backup</title>
+
+ <para>Repository and Workspace initialization from backup can use the
+ BackupWorkspaceInitializer.</para>
+
+ <para>Will be configured BackupWorkspaceInitializer in configuration of
+ workspace to restore the Workspace from backup over initializer.</para>
+
+ <para>Will be configured BackupWorkspaceInitializer in all
+ configurations workspaces of the Repository to restore the Repository
+ from backup over initializer. </para>
+
+ <para></para>
+
+ <para>Restoring the repository or workspace requires to shutdown the
+ repository.</para>
+
+ <para>Follow these steps : <itemizedlist>
+ <listitem>
+ <para>Stop repository (will be skipped this step if repository or
+ workace is not exists)</para>
+ </listitem>
+
+ <listitem>
+ <para>Clean database, value storage, index; (will be skipped this
+ step if repository or worksace is new)</para>
+ </listitem>
+
+ <listitem>
+ <para>In configuration, the workspace/-s set
+ BackupWorkspaceInitializer to refer to your backup.</para>
+ </listitem>
+
+ <listitem>
+ <para>Start repository</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para></para>
+
+ <para>Example of configuration initializer to restore workspace "backup"
+ over BackupWorkspaceInitializer:</para>
+
+ <programlisting><workspaces>
+ <workspace name="backup" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_backup-20110120_044734"/>
+ </properties>
+ </initializer>
+ ...
+</workspace></programlisting>
+
+ <section>
+ <title>Restore the Workspace over BackupWorksaceInitializer</title>
+
+ <para>Example of configuration initializer to resore the workspace
+ "backup" over BackupWorkspaceInitializer :<itemizedlist>
+ <listitem>
+ <para>Stop repository (will be skipped this step if workspace is
+ not exists)</para>
+ </listitem>
+
+ <listitem>
+ <para>Clean database, value storage, index; (will be skipped
+ this step if workspace is new)</para>
+ </listitem>
+
+ <listitem>
+ <para>In configuration, the workspace/-s set
+ BackupWorkspaceInitializer to refer to your
+ backup<programlisting><workspaces>
+ <workspace name="backup" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_backup-20110120_044734"/>
+ </properties>
+ </initializer>
+ ...
+</workspace></programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>Start repository</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section>
+ <title>Restore the Repository over BackupWorksaceInitializer</title>
+
+ <para>Example of configuration initializers to restore the repository
+ "repository" over BackupWorkspaceInitializer : <itemizedlist>
+ <listitem>
+ <para>Stop repository (will be skipped this step if repository
+ is not exists)</para>
+ </listitem>
+
+ <listitem>
+ <para>Clean database, value storage, index; (will be skipped
+ this step if repository is new)</para>
+ </listitem>
+
+ <listitem>
+ <para>In configuration of repository will be configured
+ initializers of workspace to refer to your backup.</para>
+
+ <para>For example :<programlisting>...
+<workspaces>
+ <workspace name="system" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_system-20110120_052334"/>
+ </properties>
+ </initializer>
+ ...
+ </workspace>
+
+ <workspace name="collaboration" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_collaboration-20110120_052341"/>
+ </properties>
+ </initializer>
+ ...
+ </workspace>
+
+ <workspace name="backup" ... >
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+ ...
+ </container>
+
+ <initializer class="org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer">
+ <properties>
+ <property name="restore-path" value="D:\java\exo-working\backup\repository_backup-20110120_052417"/>
+ </properties>
+ </initializer>
+ ...
+ </workspace>
+</workspaces></programlisting></para>
+ </listitem>
+
+ <listitem>
+ <para>Start repository.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+ </section>
</section>
<section>
13 years, 4 months
exo-jcr SVN: r3822 - jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2011-01-20 09:21:42 -0500 (Thu, 20 Jan 2011)
New Revision: 3822
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
Log:
EXOJCR-1164
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java 2011-01-20 11:20:33 UTC (rev 3821)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java 2011-01-20 14:21:42 UTC (rev 3822)
@@ -19,7 +19,10 @@
package org.exoplatform.services.jcr.ext.script.groovy;
import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyResourceLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.ErrorCollector;
@@ -33,17 +36,15 @@
import org.exoplatform.services.rest.ext.groovy.SourceFolder;
import java.io.File;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
/**
* @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey Parfonov</a>
@@ -74,56 +75,57 @@
return new JcrCompilationUnit(config, cs, this);
}
- @SuppressWarnings("rawtypes")
- public Class[] parseClasses(SourceFile[] files, boolean includeLoadedClasses)
+ public URL[] findDependencies(final SourceFolder[] sources, final SourceFile[] files) throws IOException
{
- return doParseClasses(files, Phases.CLASS_GENERATION, null, includeLoadedClasses);
+ return findDependencies(sources, files, Phases.SEMANTIC_ANALYSIS, null);
}
@SuppressWarnings("rawtypes")
- private Class[] doParseClasses(SourceFile[] sources, int phase, CompilerConfiguration config,
- boolean includeLoadedClasses)
+ private URL[] findDependencies(SourceFolder[] sources, SourceFile[] files, int phase, CompilerConfiguration config)
+ throws IOException
{
- synchronized (classCache)
+ CodeSource cs = new CodeSource(getCodeSource(), (java.security.cert.Certificate[])null);
+ JcrGroovyResourceLoader actualLoader = null;
+ URL[] roots = null;
+ if (sources != null && sources.length > 0)
{
- CodeSource cs = new CodeSource(getCodeSource(), (java.security.cert.Certificate[])null);
- CompilationUnit cunit = createCompilationUnit(config, cs);
- Set<SourceUnit> setSunit = new HashSet<SourceUnit>();
+ roots = new URL[sources.length];
for (int i = 0; i < sources.length; i++)
- setSunit.add(cunit.addSource(sources[i].getPath()));
- MultipleClassCollector collector = createMultipleCollector(cunit, setSunit);
- cunit.setClassgenCallback(collector);
- cunit.compile(phase);
+ roots[i] = sources[i].getPath();
+ actualLoader = new JcrGroovyResourceLoader(roots);
+ }
- for (Iterator iter = collector.getLoadedClasses().iterator(); iter.hasNext();)
- {
- Class clazz = (Class)iter.next();
- String classname = clazz.getName();
- int i = classname.lastIndexOf('.');
- if (i != -1)
+ final HierarchicalResourceLoader loader =
+ new HierarchicalResourceLoader(actualLoader, JcrGroovyClassLoader.this.getResourceLoader());
+
+ CompilationUnit cunit =
+ new JcrCompilationUnit(config, cs, new JcrGroovyClassLoader(
+ JcrGroovyClassLoaderProvider.class.getClassLoader()) {
+ public GroovyResourceLoader getResourceLoader()
{
- String pkgname = classname.substring(0, i);
- Package pkg = getPackage(pkgname);
- if (pkg == null)
- definePackage(pkgname, null, null, null, null, null, null, null);
+ return loader;
}
- setClassCacheEntry(clazz);
- }
- List<Class> compiledClasses;
- if (includeLoadedClasses)
+ });
+
+ for (int i = 0; i < files.length; i++)
+ cunit.addSource(files[i].getPath());
+ cunit.compile(phase);
+
+ List classNodes = cunit.getAST().getClasses();
+ List<URL> dependencies = new ArrayList<URL>(classNodes.size());
+ for (Iterator iter = classNodes.iterator(); iter.hasNext();)
+ {
+ ClassNode classNode = (ClassNode)iter.next();
+ ModuleNode module = classNode.getModule();
+ if (module != null)
{
-System.out.println("+++++++++++++++++++++++++ " + cunit.getClasses());
- Collection loadedClasses = collector.getLoadedClasses();
- compiledClasses = new ArrayList<Class>(loadedClasses.size());
- for (Iterator iter = loadedClasses.iterator(); iter.hasNext();)
- compiledClasses.add((Class)iter.next());
+ SourceUnit currentSunit = module.getContext();
+ if (currentSunit instanceof JcrSourceUnit)
+ dependencies.add(((JcrSourceUnit)currentSunit).getUrl());
}
- else
- {
- compiledClasses = collector.getCompiledClasses();
- }
- return compiledClasses.toArray(new Class[compiledClasses.size()]);
}
+
+ return dependencies.toArray(new URL[dependencies.size()]);
}
}
@@ -169,6 +171,8 @@
/** Adapter for JCR like URLs. */
public static class JcrSourceUnit extends SourceUnit
{
+ private URL url;
+
public JcrSourceUnit(File source, CompilerConfiguration configuration, GroovyClassLoader loader, ErrorCollector er)
{
super(source, configuration, loader, er);
@@ -192,9 +196,40 @@
* jcr://repository/workspace#/path */
super("jcr".equals(source.getProtocol()) ? source.getRef() : source.getPath(), new URLReaderSource(source,
configuration), configuration, loader, er);
+ this.url = source;
}
+
+ public URL getUrl()
+ {
+ return url;
+ }
}
+ private static class HierarchicalResourceLoader implements GroovyResourceLoader
+ {
+ private final GroovyResourceLoader actual;
+ private final GroovyResourceLoader parent;
+
+ HierarchicalResourceLoader(GroovyResourceLoader actual, GroovyResourceLoader parent)
+ throws MalformedURLException
+ {
+ this.actual = actual;
+ this.parent = parent;
+ }
+
+ public URL loadGroovySource(String filename) throws MalformedURLException
+ {
+ URL resource = null;
+ if (actual != null)
+ resource = actual.loadGroovySource(filename);
+ if (resource == null && parent != null)
+ resource = parent.loadGroovySource(filename);
+ return resource;
+ }
+ }
+
+ /* ========================================================================== */
+
public JcrGroovyClassLoaderProvider()
{
super(AccessController.doPrivileged(new PrivilegedAction<JcrGroovyClassLoader>() {
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2011-01-20 11:20:33 UTC (rev 3821)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2011-01-20 14:21:42 UTC (rev 3822)
@@ -36,6 +36,8 @@
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -77,30 +79,12 @@
*/
public Class<?>[] compile(UnifiedNodeReference... sourceReferences) throws IOException
{
- return compile(false, sourceReferences);
+ return compile(null, sourceReferences);
}
/**
* Compile Groovy source that located in <code>sourceReferences</code>.
* Compiled sources can be dependent to each other and dependent to Groovy
- * sources that are accessible for this compiler.
- *
- * @param includeLoadedClasses if <code>true</code> then array of classes
- * which method method return contains all loaded classes. If
- * <code>false</code> then only classes created from
- * <code>sourceReferences</code> included in result array
- * @param sourceReferences references to Groovy sources to be compiled
- * @return result of compilation
- * @throws IOException if any i/o errors occurs
- */
- public Class<?>[] compile(boolean includeLoadedClasses, UnifiedNodeReference... sourceReferences) throws IOException
- {
- return compile(includeLoadedClasses, null, sourceReferences);
- }
-
- /**
- * Compile Groovy source that located in <code>sourceReferences</code>.
- * Compiled sources can be dependent to each other and dependent to Groovy
* sources that are accessible for this compiler and with additional Groovy
* sources <code>src</code>. <b>NOTE</b> To be able load Groovy source files
* from specified folders the following rules must be observed:
@@ -138,58 +122,10 @@
*/
public Class<?>[] compile(SourceFolder[] src, UnifiedNodeReference... sourceReferences) throws IOException
{
- return compile(false, src, sourceReferences);
- }
-
- /**
- * Compile Groovy source that located in <code>sourceReferences</code>.
- * Compiled sources can be dependent to each other and dependent to Groovy
- * sources that are accessible for this compiler and with additional Groovy
- * sources <code>src</code>. <b>NOTE</b> To be able load Groovy source files
- * from specified folders the following rules must be observed:
- * <ul>
- * <li>Groovy source files must be located in folder with respect to package
- * structure</li>
- * <li>Name of Groovy source files must be the same as name of class located
- * in file</li>
- * <li>Groovy source file must have extension '.groovy'</li>
- * </ul>
- * <br/>
- * Example: If source stream that we want compile contains the following
- * code:
- *
- * <pre>
- * package c.b.a
- *
- * import a.b.c.A
- *
- * class B extends A {
- * // Do something.
- * }
- * </pre>
- *
- * Assume we store dependencies in JCR then URL of folder with Groovy sources
- * may be like this: <code>jcr://repository/workspace#/groovy-library</code>.
- * Then absolute path to JCR node that contains Groovy source must be as
- * following: <code>/groovy-library/a/b/c/A.groovy</code>
- *
- * @param includeLoadedClasses if <code>true</code> then array of classes
- * which method method return contains all loaded classes. If
- * <code>false</code> then only classes created from
- * <code>sourceReferences</code> included in result array
- * @param src additional Groovy source location that should be added in
- * class-path when compile <code>sourceReferences</code>
- * @param sourceReferences references to Groovy sources to be compiled
- * @return result of compilation
- * @throws IOException if any i/o errors occurs
- */
- public Class<?>[] compile(boolean includeLoadedClasses, SourceFolder[] src, UnifiedNodeReference... sourceReferences)
- throws IOException
- {
SourceFile[] files = new SourceFile[sourceReferences.length];
for (int i = 0; i < sourceReferences.length; i++)
files[i] = new SourceFile(sourceReferences[i].getURL());
- return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files, includeLoadedClasses);
+ return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files);
}
/**
@@ -214,41 +150,12 @@
*/
public Class<?>[] compile(SourceFolder[] src, SourceFile[] files) throws IOException
{
- return compile(false, src, files);
+ return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files);
}
/**
* Compile Groovy source that located in <code>files</code>. Compiled sources
* can be dependent to each other and dependent to Groovy sources that are
- * accessible for this compiler and with additional Groovy sources
- * <code>src</code>. <b>NOTE</b> To be able load Groovy source files from
- * specified folders the following rules must be observed:
- * <ul>
- * <li>Groovy source files must be located in folder with respect to package
- * structure</li>
- * <li>Name of Groovy source files must be the same as name of class located
- * in file</li>
- * <li>Groovy source file must have extension '.groovy'</li>
- * </ul>
- *
- * @param includeLoadedClasses if <code>true</code> then array of classes
- * which method method return contains all loaded classes. If
- * <code>false</code> then only classes created from
- * <code>sourceReferences</code> included in result array
- * @param src additional Groovy source location that should be added in
- * class-path when compile <code>files</code>
- * @param files Groovy sources to be compiled
- * @return result of compilation
- * @throws IOException if any i/o errors occurs
- */
- public Class<?>[] compile(boolean includeLoadedClasses, SourceFolder[] src, SourceFile[] files) throws IOException
- {
- return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files, includeLoadedClasses);
- }
-
- /**
- * Compile Groovy source that located in <code>files</code>. Compiled sources
- * can be dependent to each other and dependent to Groovy sources that are
* accessible for this compiler.
*
* @param files Groovy sources to be compiled
@@ -257,40 +164,40 @@
*/
public Class<?>[] compile(SourceFile[] files) throws IOException
{
- return compile(false, files);
+ return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(), files);
}
- /**
- * Compile Groovy source that located in <code>files</code>. Compiled sources
- * can be dependent to each other and dependent to Groovy sources that are
- * accessible for this compiler.
- *
- * @param includeLoadedClasses if <code>true</code> then array of classes
- * which method method return contains all loaded classes. If
- * <code>false</code> then only classes created from
- * <code>sourceReferences</code> included in result array
- * @param files Groovy sources to be compiled
- * @return result of compilation
- * @throws IOException if any i/o errors occurs
- */
- public Class<?>[] compile(boolean includeLoadedClasses, SourceFile[] files) throws IOException
- {
- return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(), files, includeLoadedClasses);
- }
-
@SuppressWarnings("rawtypes")
- private Class<?>[] doCompile(final JcrGroovyClassLoader cl, final SourceFile[] files,
- final boolean includeLoadedClasses) throws IOException
+ private Class<?>[] doCompile(final JcrGroovyClassLoader cl, final SourceFile[] files) throws IOException
{
Class[] classes = AccessController.doPrivileged(new PrivilegedAction<Class[]>() {
public Class[] run()
{
- return cl.parseClasses(files, includeLoadedClasses);
+ return cl.parseClasses(files);
}
});
return classes;
}
+ public URL[] getDependencies(final SourceFolder[] sources, final SourceFile[] files) throws IOException
+ {
+ try
+ {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<URL[]>() {
+ public URL[] run() throws IOException
+ {
+ return ((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader()).findDependencies(sources,
+ files);
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ Throwable cause = e.getCause();
+ throw (IOException)cause;
+ }
+ }
+
/**
* @return get underling groovy class loader
*/
13 years, 4 months
exo-jcr SVN: r3821 - in jcr/trunk: exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl and 1 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-01-20 06:20:33 -0500 (Thu, 20 Jan 2011)
New Revision: 3821
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JcrRestoreWiFilter.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestJcrRestoreWiFilter.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
Log:
EXOJCR-1165 : The problem with "temporary jcrrestorewi*.tmp files not deleted" was fixed.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java 2011-01-20 10:12:08 UTC (rev 3820)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SysViewWorkspaceInitializer.java 2011-01-20 11:20:33 UTC (rev 3821)
@@ -222,7 +222,7 @@
@Override
void close() throws IOException
{
- this.decoder.flush();
+ this.decoder.close();
}
@Override
@@ -297,7 +297,9 @@
super.flush();
if (buff != null)
+ {
buff.close();
+ }
}
File getFile() throws IOException
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-01-20 10:12:08 UTC (rev 3820)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-01-20 11:20:33 UTC (rev 3821)
@@ -805,6 +805,13 @@
*/
public void start()
{
+ //remove if exists all old jcrrestorewi*.tmp files.
+ File[] files = PrivilegedFileHelper.listFiles(tempDir, new JcrRestoreWiFilter());
+ for (int i = 0; i < files.length; i++)
+ {
+ PrivilegedFileHelper.delete(files[i]);
+ }
+
// start all scheduled before tasks
if (registryService != null && !registryService.getForceXMLConfigurationValue(initParams))
Added: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JcrRestoreWiFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JcrRestoreWiFilter.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JcrRestoreWiFilter.java 2011-01-20 11:20:33 UTC (rev 3821)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2003-2011 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.ext.backup.impl;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: JcrRestoreWiFilter.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class JcrRestoreWiFilter
+ implements FilenameFilter
+{
+
+ public boolean accept(File dir, String name)
+ {
+ return name.endsWith(".tmp") && name.startsWith("jcrrestorewi");
+ }
+
+}
Added: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestJcrRestoreWiFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestJcrRestoreWiFilter.java (rev 0)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestJcrRestoreWiFilter.java 2011-01-20 11:20:33 UTC (rev 3821)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2003-2011 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.ext.backup;
+
+import junit.framework.TestCase;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.PrivilegedSystemHelper;
+import org.exoplatform.services.jcr.ext.backup.impl.JcrRestoreWiFilter;
+
+import java.io.File;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: TestJcrREstoreWiFilter.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class TestJcrRestoreWiFilter
+ extends TestCase
+{
+
+ public void testListFiles() throws Exception
+ {
+ File tempDir = new File(PrivilegedSystemHelper.getProperty("java.io.tmpdir") + File.separator + Math.random());
+ PrivilegedFileHelper.mkdirs(tempDir);
+ PrivilegedFileHelper.deleteOnExit(tempDir);
+
+ for (int i = 0; i < 7; i++)
+ {
+ File f = PrivilegedFileHelper.createTempFile("jcrrestorewi", ".tmp", tempDir);
+ PrivilegedFileHelper.deleteOnExit(f);
+ }
+
+ File[] files = PrivilegedFileHelper.listFiles(tempDir, new JcrRestoreWiFilter());
+
+ assertEquals(7, files.length);
+ }
+}
13 years, 4 months
exo-jcr SVN: r3820 - jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2011-01-20 05:12:08 -0500 (Thu, 20 Jan 2011)
New Revision: 3820
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
Log:
EXOJCR-1164
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java 2011-01-19 08:16:34 UTC (rev 3819)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyClassLoaderProvider.java 2011-01-20 10:12:08 UTC (rev 3820)
@@ -23,11 +23,13 @@
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.Phases;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.io.ReaderSource;
import org.codehaus.groovy.control.io.URLReaderSource;
import org.exoplatform.services.rest.ext.groovy.ExtendedGroovyClassLoader;
import org.exoplatform.services.rest.ext.groovy.GroovyClassLoaderProvider;
+import org.exoplatform.services.rest.ext.groovy.SourceFile;
import org.exoplatform.services.rest.ext.groovy.SourceFolder;
import java.io.File;
@@ -36,6 +38,12 @@
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
/**
* @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey Parfonov</a>
@@ -65,6 +73,58 @@
{
return new JcrCompilationUnit(config, cs, this);
}
+
+ @SuppressWarnings("rawtypes")
+ public Class[] parseClasses(SourceFile[] files, boolean includeLoadedClasses)
+ {
+ return doParseClasses(files, Phases.CLASS_GENERATION, null, includeLoadedClasses);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private Class[] doParseClasses(SourceFile[] sources, int phase, CompilerConfiguration config,
+ boolean includeLoadedClasses)
+ {
+ synchronized (classCache)
+ {
+ CodeSource cs = new CodeSource(getCodeSource(), (java.security.cert.Certificate[])null);
+ CompilationUnit cunit = createCompilationUnit(config, cs);
+ Set<SourceUnit> setSunit = new HashSet<SourceUnit>();
+ for (int i = 0; i < sources.length; i++)
+ setSunit.add(cunit.addSource(sources[i].getPath()));
+ MultipleClassCollector collector = createMultipleCollector(cunit, setSunit);
+ cunit.setClassgenCallback(collector);
+ cunit.compile(phase);
+
+ for (Iterator iter = collector.getLoadedClasses().iterator(); iter.hasNext();)
+ {
+ Class clazz = (Class)iter.next();
+ String classname = clazz.getName();
+ int i = classname.lastIndexOf('.');
+ if (i != -1)
+ {
+ String pkgname = classname.substring(0, i);
+ Package pkg = getPackage(pkgname);
+ if (pkg == null)
+ definePackage(pkgname, null, null, null, null, null, null, null);
+ }
+ setClassCacheEntry(clazz);
+ }
+ List<Class> compiledClasses;
+ if (includeLoadedClasses)
+ {
+System.out.println("+++++++++++++++++++++++++ " + cunit.getClasses());
+ Collection loadedClasses = collector.getLoadedClasses();
+ compiledClasses = new ArrayList<Class>(loadedClasses.size());
+ for (Iterator iter = loadedClasses.iterator(); iter.hasNext();)
+ compiledClasses.add((Class)iter.next());
+ }
+ else
+ {
+ compiledClasses = collector.getCompiledClasses();
+ }
+ return compiledClasses.toArray(new Class[compiledClasses.size()]);
+ }
+ }
}
public static class JcrCompilationUnit extends CompilationUnit
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2011-01-19 08:16:34 UTC (rev 3819)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/JcrGroovyCompiler.java 2011-01-20 10:12:08 UTC (rev 3820)
@@ -77,12 +77,30 @@
*/
public Class<?>[] compile(UnifiedNodeReference... sourceReferences) throws IOException
{
- return compile(null, sourceReferences);
+ return compile(false, sourceReferences);
}
/**
* Compile Groovy source that located in <code>sourceReferences</code>.
* Compiled sources can be dependent to each other and dependent to Groovy
+ * sources that are accessible for this compiler.
+ *
+ * @param includeLoadedClasses if <code>true</code> then array of classes
+ * which method method return contains all loaded classes. If
+ * <code>false</code> then only classes created from
+ * <code>sourceReferences</code> included in result array
+ * @param sourceReferences references to Groovy sources to be compiled
+ * @return result of compilation
+ * @throws IOException if any i/o errors occurs
+ */
+ public Class<?>[] compile(boolean includeLoadedClasses, UnifiedNodeReference... sourceReferences) throws IOException
+ {
+ return compile(includeLoadedClasses, null, sourceReferences);
+ }
+
+ /**
+ * Compile Groovy source that located in <code>sourceReferences</code>.
+ * Compiled sources can be dependent to each other and dependent to Groovy
* sources that are accessible for this compiler and with additional Groovy
* sources <code>src</code>. <b>NOTE</b> To be able load Groovy source files
* from specified folders the following rules must be observed:
@@ -94,7 +112,7 @@
* <li>Groovy source file must have extension '.groovy'</li>
* </ul>
* <br/>
- * Example: If source stream that we want validate contains the following
+ * Example: If source stream that we want compile contains the following
* code:
*
* <pre>
@@ -120,10 +138,58 @@
*/
public Class<?>[] compile(SourceFolder[] src, UnifiedNodeReference... sourceReferences) throws IOException
{
+ return compile(false, src, sourceReferences);
+ }
+
+ /**
+ * Compile Groovy source that located in <code>sourceReferences</code>.
+ * Compiled sources can be dependent to each other and dependent to Groovy
+ * sources that are accessible for this compiler and with additional Groovy
+ * sources <code>src</code>. <b>NOTE</b> To be able load Groovy source files
+ * from specified folders the following rules must be observed:
+ * <ul>
+ * <li>Groovy source files must be located in folder with respect to package
+ * structure</li>
+ * <li>Name of Groovy source files must be the same as name of class located
+ * in file</li>
+ * <li>Groovy source file must have extension '.groovy'</li>
+ * </ul>
+ * <br/>
+ * Example: If source stream that we want compile contains the following
+ * code:
+ *
+ * <pre>
+ * package c.b.a
+ *
+ * import a.b.c.A
+ *
+ * class B extends A {
+ * // Do something.
+ * }
+ * </pre>
+ *
+ * Assume we store dependencies in JCR then URL of folder with Groovy sources
+ * may be like this: <code>jcr://repository/workspace#/groovy-library</code>.
+ * Then absolute path to JCR node that contains Groovy source must be as
+ * following: <code>/groovy-library/a/b/c/A.groovy</code>
+ *
+ * @param includeLoadedClasses if <code>true</code> then array of classes
+ * which method method return contains all loaded classes. If
+ * <code>false</code> then only classes created from
+ * <code>sourceReferences</code> included in result array
+ * @param src additional Groovy source location that should be added in
+ * class-path when compile <code>sourceReferences</code>
+ * @param sourceReferences references to Groovy sources to be compiled
+ * @return result of compilation
+ * @throws IOException if any i/o errors occurs
+ */
+ public Class<?>[] compile(boolean includeLoadedClasses, SourceFolder[] src, UnifiedNodeReference... sourceReferences)
+ throws IOException
+ {
SourceFile[] files = new SourceFile[sourceReferences.length];
for (int i = 0; i < sourceReferences.length; i++)
files[i] = new SourceFile(sourceReferences[i].getURL());
- return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files);
+ return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files, includeLoadedClasses);
}
/**
@@ -140,7 +206,7 @@
* <li>Groovy source file must have extension '.groovy'</li>
* </ul>
*
- * @param srcadditional Groovy source location that should be added in
+ * @param src additional Groovy source location that should be added in
* class-path when compile <code>files</code>
* @param files Groovy sources to be compiled
* @return result of compilation
@@ -148,12 +214,41 @@
*/
public Class<?>[] compile(SourceFolder[] src, SourceFile[] files) throws IOException
{
- return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files);
+ return compile(false, src, files);
}
/**
* Compile Groovy source that located in <code>files</code>. Compiled sources
* can be dependent to each other and dependent to Groovy sources that are
+ * accessible for this compiler and with additional Groovy sources
+ * <code>src</code>. <b>NOTE</b> To be able load Groovy source files from
+ * specified folders the following rules must be observed:
+ * <ul>
+ * <li>Groovy source files must be located in folder with respect to package
+ * structure</li>
+ * <li>Name of Groovy source files must be the same as name of class located
+ * in file</li>
+ * <li>Groovy source file must have extension '.groovy'</li>
+ * </ul>
+ *
+ * @param includeLoadedClasses if <code>true</code> then array of classes
+ * which method method return contains all loaded classes. If
+ * <code>false</code> then only classes created from
+ * <code>sourceReferences</code> included in result array
+ * @param src additional Groovy source location that should be added in
+ * class-path when compile <code>files</code>
+ * @param files Groovy sources to be compiled
+ * @return result of compilation
+ * @throws IOException if any i/o errors occurs
+ */
+ public Class<?>[] compile(boolean includeLoadedClasses, SourceFolder[] src, SourceFile[] files) throws IOException
+ {
+ return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(src), files, includeLoadedClasses);
+ }
+
+ /**
+ * Compile Groovy source that located in <code>files</code>. Compiled sources
+ * can be dependent to each other and dependent to Groovy sources that are
* accessible for this compiler.
*
* @param files Groovy sources to be compiled
@@ -162,16 +257,35 @@
*/
public Class<?>[] compile(SourceFile[] files) throws IOException
{
- return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(), files);
+ return compile(false, files);
}
+ /**
+ * Compile Groovy source that located in <code>files</code>. Compiled sources
+ * can be dependent to each other and dependent to Groovy sources that are
+ * accessible for this compiler.
+ *
+ * @param includeLoadedClasses if <code>true</code> then array of classes
+ * which method method return contains all loaded classes. If
+ * <code>false</code> then only classes created from
+ * <code>sourceReferences</code> included in result array
+ * @param files Groovy sources to be compiled
+ * @return result of compilation
+ * @throws IOException if any i/o errors occurs
+ */
+ public Class<?>[] compile(boolean includeLoadedClasses, SourceFile[] files) throws IOException
+ {
+ return doCompile((JcrGroovyClassLoader)classLoaderProvider.getGroovyClassLoader(), files, includeLoadedClasses);
+ }
+
@SuppressWarnings("rawtypes")
- private Class<?>[] doCompile(final JcrGroovyClassLoader cl, final SourceFile[] files) throws IOException
+ private Class<?>[] doCompile(final JcrGroovyClassLoader cl, final SourceFile[] files,
+ final boolean includeLoadedClasses) throws IOException
{
Class[] classes = AccessController.doPrivileged(new PrivilegedAction<Class[]>() {
public Class[] run()
{
- return cl.parseClasses(files);
+ return cl.parseClasses(files, includeLoadedClasses);
}
});
return classes;
13 years, 4 months
exo-jcr SVN: r3819 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-19 03:16:34 -0500 (Wed, 19 Jan 2011)
New Revision: 3819
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
Log:
EXOJCR-1078: fix suspend MulitIndex
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-19 08:00:16 UTC (rev 3818)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-01-19 08:16:34 UTC (rev 3819)
@@ -2582,8 +2582,20 @@
*/
protected void suspend() throws IOException
{
- flush();
- merger.dispose();
+ if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
+ {
+ try
+ {
+ indexUpdateMonitor.setUpdateInProgress(true, true);
+ flush();
+
+ merger.dispose();
+ }
+ finally
+ {
+ indexUpdateMonitor.setUpdateInProgress(false, true);
+ }
+ }
}
/**
@@ -2593,8 +2605,11 @@
*/
protected void resume() throws IOException
{
- merger = doInitIndexMerger();
- merger.start();
+ if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
+ {
+ merger = doInitIndexMerger();
+ merger.start();
+ }
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-01-19 08:00:16 UTC (rev 3818)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2011-01-19 08:16:34 UTC (rev 3819)
@@ -2815,17 +2815,14 @@
*/
public void suspend() throws SuspendException
{
- if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
+ try
{
- try
- {
- index.suspend();
- }
- catch (IOException e)
- {
- throw new SuspendException(e);
- }
+ index.suspend();
}
+ catch (IOException e)
+ {
+ throw new SuspendException(e);
+ }
}
/**
@@ -2833,16 +2830,13 @@
*/
public void resume() throws ResumeException
{
- if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
+ try
{
- try
- {
- index.resume();
- }
- catch (IOException e)
- {
- throw new ResumeException(e);
- }
+ index.resume();
}
+ catch (IOException e)
+ {
+ throw new ResumeException(e);
+ }
}
}
13 years, 4 months
exo-jcr SVN: r3818 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-01-19 03:00:16 -0500 (Wed, 19 Jan 2011)
New Revision: 3818
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java
Log:
EXOJCR-1134: fixed memory leak by removing from cache stale data.
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java 2011-01-19 07:40:16 UTC (rev 3817)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java 2011-01-19 08:00:16 UTC (rev 3818)
@@ -62,7 +62,9 @@
final boolean debugEnabled = log.isDebugEnabled();
if (debugEnabled)
+ {
log.debug("start pushing in-memory state to cache cacheLoader collection");
+ }
// merging all lists stored in memory
Collection<NodeSPI> children = cache.getRoot().getChildren();
@@ -89,13 +91,21 @@
parentRemovedNodes.addAll(listsWrapper.getParentAddedNodes());
}
}
- //TODO: recover logic is here, lists are: removedNodes and addedNodes String id = IdGenerator.generate();
String id = IdGenerator.generate();
cache.put(Fqn.fromRelativeElements(wsChildren.getFqn(), id), JBossCacheIndexChangesFilter.LISTWRAPPER, new ChangesFilterListsWrapper(addedNodes,
removedNodes, parentAddedNodes, parentRemovedNodes));
+ // Once we put the merged changes into the cache we can remove other changes from the cache
+ for (NodeSPI aChildren : children)
+ {
+ // Remove the node from the cache and do it asynchronously
+ cache.getInvocationContext().getOptionOverrides().setForceAsynchronous(true);
+ cache.removeNode(aChildren.getFqn());
+ }
}
if (debugEnabled)
+ {
log.debug("in-memory state passed to cache cacheLoader successfully");
+ }
return null;
}
};
13 years, 4 months
exo-jcr SVN: r3817 - in jcr/trunk/exo.jcr.component.ext/src: main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-01-19 02:40:16 -0500 (Wed, 19 Jan 2011)
New Revision: 3817
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java
Log:
EXOJCR-1146: DBCleanerService should not relate on AbstractCacheableLockManager
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java 2011-01-19 07:39:43 UTC (rev 3816)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedRepositoryRestore.java 2011-01-19 07:40:16 UTC (rev 3817)
@@ -16,11 +16,6 @@
*/
package org.exoplatform.services.jcr.ext.backup.impl;
-import java.util.ArrayList;
-import java.util.Map;
-
-import javax.jcr.RepositoryException;
-
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
@@ -32,8 +27,15 @@
import org.exoplatform.services.jcr.ext.backup.RepositoryRestoreExeption;
import org.exoplatform.services.jcr.impl.RepositoryServiceImpl;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerService;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SAS.
*
@@ -46,11 +48,6 @@
{
/**
- * Database cleaner.
- */
- private final DBCleanerService dbCleanerService;
-
- /**
* Value storage cleaner.
*/
private final ValueStorageCleanHelper valueStorageCleanHelper;
@@ -69,7 +66,6 @@
{
super(repoService, backupManagerImpl, repositoryEntry, workspacesMapping, backupChainLog);
- this.dbCleanerService = new DBCleanerService();
this.valueStorageCleanHelper = new ValueStorageCleanHelper();
this.indexCleanHelper = new IndexCleanHelper();
}
@@ -105,6 +101,24 @@
forceCloseSession(repositoryEntry.getName(), wEntry.getName());
}
+ List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
+
+ // collect all DataCleaners
+ for (WorkspaceEntry wEntry : workspaceList)
+ {
+ forceCloseSession(repositoryEntry.getName(), wEntry.getName());
+
+ List<Backupable> backupable =
+ repositoryService.getRepository(this.repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+
+ for (Backupable component : backupable)
+ {
+ dataCleaners.add(component.getDataCleaner());
+ }
+ }
+
//remove repository
if (isDefault)
{
@@ -116,9 +130,10 @@
}
//clean database
- RepositoryEntry re = new RepositoryEntry();
- re.setWorkspaceEntries(workspaceList);
- dbCleanerService.cleanRepositoryData(re);
+ for (DataCleaner cleaner : dataCleaners)
+ {
+ cleaner.clean();
+ }
//clean index
for (WorkspaceEntry wEntry : workspaceList)
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java 2011-01-19 07:39:43 UTC (rev 3816)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobExistedWorkspaceRestore.java 2011-01-19 07:40:16 UTC (rev 3817)
@@ -25,10 +25,14 @@
import org.exoplatform.services.jcr.ext.backup.BackupManager;
import org.exoplatform.services.jcr.ext.backup.WorkspaceRestoreException;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerService;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.jcr.RepositoryException;
/**
@@ -47,11 +51,6 @@
private static Log log = ExoLogger.getLogger("exo.jcr.component.ext.JobExistedWorkspaceRestore");
/**
- * Database cleaner.
- */
- private final DBCleanerService dbCleanerService;
-
- /**
* Value storage cleaner.
*/
private final ValueStorageCleanHelper valueStorageCleaner;
@@ -69,7 +68,6 @@
{
super(repositoryService, backupManager, repositoryName, log, wEntry);
- this.dbCleanerService = new DBCleanerService();
this.valueStorageCleaner = new ValueStorageCleanHelper();
this.indexCleanHelper = new IndexCleanHelper();
}
@@ -104,13 +102,27 @@
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName()
.equals(wEntry.getName());
+ List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
+
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ for (Backupable component : backupable)
+ {
+ dataCleaners.add(component.getDataCleaner());
+ }
+
//close all session
forceCloseSession(repositoryName, wEntry.getName());
repositoryService.getRepository(repositoryName).removeWorkspace(wEntry.getName());
//clean database
- dbCleanerService.cleanWorkspaceData(wEntry);
+ for (DataCleaner cleaner : dataCleaners)
+ {
+ cleaner.clean();
+ }
//clean index
indexCleanHelper.removeWorkspaceIndex(wEntry, isSystem);
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java 2011-01-19 07:39:43 UTC (rev 3816)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java 2011-01-19 07:40:16 UTC (rev 3817)
@@ -28,8 +28,8 @@
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerException;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -98,7 +98,7 @@
{
log.error("Can't rollback changes", e1);
}
- catch (DBCleanerException e1)
+ catch (CleanException e1)
{
log.error("Can't rollback changes", e1);
}
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java 2011-01-19 07:39:43 UTC (rev 3816)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java 2011-01-19 07:40:16 UTC (rev 3817)
@@ -41,11 +41,10 @@
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.CleanException;
import org.exoplatform.services.jcr.impl.storage.jdbc.backup.RestoreException;
import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerException;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -118,7 +117,7 @@
{
log.error("Can't rollback changes", e1);
}
- catch (DBCleanerException e1)
+ catch (CleanException e1)
{
log.error("Can't rollback changes", e1);
}
@@ -239,10 +238,10 @@
*
* @throws RepositoryConfigurationException
* @throws RepositoryException
- * @throws DBCleanerException
+ * @throws CleanException
* @throws IOException
*/
- protected void rollback() throws RepositoryException, RepositoryConfigurationException, DBCleanerException,
+ protected void rollback() throws RepositoryException, RepositoryConfigurationException, CleanException,
IOException
{
boolean isSystem =
@@ -252,8 +251,15 @@
//close all session
forceCloseSession(repositoryEntry.getName(), workspaceEntry.getName());
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryEntry.getName()).getWorkspaceContainer(workspaceEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
//clean database
- new DBCleanerService().cleanWorkspaceData(workspaceEntry);
+ for (Backupable component : backupable)
+ {
+ component.getDataCleaner().clean();
+ }
//clean index
new IndexCleanHelper().removeWorkspaceIndex(workspaceEntry, isSystem);
Modified: jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java 2011-01-19 07:39:43 UTC (rev 3816)
+++ jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/AbstractBackupTestCase.java 2011-01-19 07:40:16 UTC (rev 3817)
@@ -37,7 +37,8 @@
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
-import org.exoplatform.services.jcr.impl.util.jdbc.cleaner.DBCleanerService;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.Backupable;
+import org.exoplatform.services.jcr.impl.storage.jdbc.backup.DataCleaner;
import java.io.File;
import java.io.FileFilter;
@@ -47,6 +48,7 @@
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import javax.jcr.ItemExistsException;
@@ -67,8 +69,7 @@
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
* @version $Id: AbstractBackupTestCase.java 760 2008-02-07 15:08:07Z pnedonosko $
*/
-public abstract class AbstractBackupTestCase
- extends BaseStandaloneTest
+public abstract class AbstractBackupTestCase extends BaseStandaloneTest
{
protected SessionImpl ws1Session;
@@ -94,11 +95,6 @@
protected String workspaceNameToRestore = "ws1backup";
/**
- * Database cleaner.
- */
- private DBCleanerService dbCleanerService = new DBCleanerService();
-
- /**
* Value storage cleaner.
*/
private ValueStorageCleanHelper valueStorageCleanHelper = new ValueStorageCleanHelper();
@@ -499,7 +495,6 @@
repositoryService.getRepository(repositoryName).removeWorkspace(wEntry.getName());
//clean database
- // dbCleanerService.cleanWorkspaceData(wEntry);
DataSource ds =
(DataSource)new InitialContext().lookup(wEntry.getContainer().getParameterValue(
JDBCWorkspaceDataContainer.SOURCE_NAME));
@@ -557,13 +552,27 @@
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName()
.equals(wEntry.getName());
+ List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
+
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryName).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ for (Backupable component : backupable)
+ {
+ dataCleaners.add(component.getDataCleaner());
+ }
+
//close all session
forceCloseSession(repositoryName, wEntry.getName());
repositoryService.getRepository(repositoryName).removeWorkspace(wEntry.getName());
//clean database
- dbCleanerService.cleanWorkspaceData(wEntry);
+ for (DataCleaner cleaner : dataCleaners)
+ {
+ cleaner.clean();
+ }
//clean index
indexCleanHelper.removeWorkspaceIndex(wEntry, isSystem);
@@ -595,6 +604,23 @@
forceCloseSession(repositoryEntry.getName(), wEntry.getName());
}
+ List<DataCleaner> dataCleaners = new ArrayList<DataCleaner>();
+
+ // collect all DataCleaners
+ for (WorkspaceEntry wEntry : workspaceList)
+ {
+ forceCloseSession(repositoryEntry.getName(), wEntry.getName());
+
+ List<Backupable> backupable =
+ repositoryService.getRepository(repositoryEntry.getName()).getWorkspaceContainer(wEntry.getName())
+ .getComponentInstancesOfType(Backupable.class);
+
+ for (Backupable component : backupable)
+ {
+ dataCleaners.add(component.getDataCleaner());
+ }
+ }
+
//remove repository
if (isDefault)
{
@@ -606,9 +632,10 @@
}
//clean database
- RepositoryEntry re = new RepositoryEntry();
- re.setWorkspaceEntries(workspaceList);
- dbCleanerService.cleanRepositoryData(re);
+ for (DataCleaner cleaner : dataCleaners)
+ {
+ cleaner.clean();
+ }
//clean index
for (WorkspaceEntry wEntry : workspaceList)
13 years, 4 months