exo-jcr SVN: r4353 - in core/branches/2.3.x: patch/2.3.9/COR-235 and 1 other directory.
by do-not-reply@jboss.org
Author: paristote
Date: 2011-05-10 05:16:39 -0400 (Tue, 10 May 2011)
New Revision: 4353
Added:
core/branches/2.3.x/patch/2.3.9/COR-235/readme.txt
Modified:
core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/SimpleLdapUserListAccess.java
Log:
COR-235
What is the problem to fix?
org.exoplatform.services.organization.ldap.LDAPUserPageList#getAll() returns only the list of usernames
How is the problem fixed?
Add to returned attributes others fields such as Display Name, Last Name, First Name, email, password
Modified: core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/SimpleLdapUserListAccess.java
===================================================================
--- core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/SimpleLdapUserListAccess.java 2011-05-10 04:34:27 UTC (rev 4352)
+++ core/branches/2.3.x/exo.core.component.organization.ldap/src/main/java/org/exoplatform/services/organization/ldap/SimpleLdapUserListAccess.java 2011-05-10 09:16:39 UTC (rev 4353)
@@ -59,6 +59,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected User[] load(LdapContext ctx, int index, int length) throws Exception
{
User[] users = new User[length];
@@ -69,7 +70,14 @@
SortControl sctl = new SortControl(new String[]{ldapAttrMapping.userUsernameAttr}, Control.NONCRITICAL);
ctx.setRequestControls(new Control[]{sctl});
+ // returns only needed attributes for creation UserImpl in
+ // LDAPAttributeMapping.attributesToUser() method
+ String[] returnedAtts =
+ {ldapAttrMapping.userUsernameAttr, ldapAttrMapping.userFirstNameAttr, ldapAttrMapping.userLastNameAttr,
+ ldapAttrMapping.userDisplayNameAttr, ldapAttrMapping.userMailAttr, ldapAttrMapping.userPassword};
+
SearchControls constraints = new SearchControls();
+ constraints.setReturningAttributes(returnedAtts);
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
results = ctx.search(searchBase, filter, constraints);
@@ -101,6 +109,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int getSize(LdapContext ctx) throws Exception
{
if (size < 0)
@@ -109,8 +118,12 @@
try
{
+ String[] returnedAtts = {ldapAttrMapping.userUsernameAttr};
+
SearchControls constraints = new SearchControls();
+ constraints.setReturningAttributes(returnedAtts);
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
results = ctx.search(searchBase, filter, constraints);
size = 0;
while (results.hasMoreElements())
Added: core/branches/2.3.x/patch/2.3.9/COR-235/readme.txt
===================================================================
--- core/branches/2.3.x/patch/2.3.9/COR-235/readme.txt (rev 0)
+++ core/branches/2.3.x/patch/2.3.9/COR-235/readme.txt 2011-05-10 09:16:39 UTC (rev 4353)
@@ -0,0 +1,69 @@
+Summary
+
+ Status: Only User names are returned with UIUserSelector Using LDAP
+ CCP Issue: CCP-911, Product Jira Issue: COR-235. Backport of COR-234.
+ Complexity: Low
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+org.exoplatform.services.organization.ldap.LDAPUserPageList#getAll() returns only the list of usernames
+Fix description
+
+How is the problem fixed?
+
+ Add to returned attributes others fields such as Display Name, Last Name, First Name, email, password
+
+Patch information:
+Patch files: COR-235.patch
+
+Tests to perform
+
+Reproduction test
+* Steps to reproduce using Allinone 1.6.8 :
+
+ Go to Community Management Portlet
+ Open group Management
+ Click on select user
+ The list will show only usernames
+
+Tests performed at DevLevel
+
+ Manual testing: tomcat + LDAP Organization services + AD
+
+Tests performed at QA/Support Level
+*
+
+Documentation changes
+
+Documentation changes:
+ No
+
+Configuration changes
+
+Configuration changes:
+ No
+
+Will previous configuration continue to work?
+ Yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+ No
+
+Is there a performance risk/cost?
+ No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Validated
+
+Support Comment
+* Validated
+
+QA Feedbacks
+*
+
13 years
exo-jcr SVN: r4352 - in jcr/branches/1.12.x: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query and 1 other directories.
by do-not-reply@jboss.org
Author: paristote
Date: 2011-05-10 00:34:27 -0400 (Tue, 10 May 2011)
New Revision: 4352
Added:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestUpdateProperty.java
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1594/readme.txt
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexerChangesFilter.java
Log:
JCR-1594
What is the problem to fix?
Renaming folder in WebDAV takes a lot of time.
How is the problem fixed?
Avoid unnecessary re-indexing operations for children nodes
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexerChangesFilter.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexerChangesFilter.java 2011-05-10 04:16:39 UTC (rev 4351)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexerChangesFilter.java 2011-05-10 04:34:27 UTC (rev 4352)
@@ -163,66 +163,36 @@
private void acceptChanges(final Set<String> removedNodes, final Set<String> addedNodes,
final Map<String, List<ItemState>> updatedNodes, ItemState itemState)
{
- {
- String uuid =
- itemState.isNode() ? itemState.getData().getIdentifier() : itemState.getData().getParentIdentifier();
+ String uuid =
+ itemState.isNode() ? itemState.getData().getIdentifier() : itemState.getData().getParentIdentifier();
+ if (itemState.isNode())
+ {
if (itemState.isAdded())
{
- if (itemState.isNode())
- {
- addedNodes.add(uuid);
- }
- else
- {
- if (!addedNodes.contains(uuid))
- {
- createNewOrAdd(uuid, itemState, updatedNodes);
- }
- }
+ addedNodes.add(uuid);
}
- else if (itemState.isRenamed())
+ else if (itemState.isRenamed() || itemState.isUpdated() || itemState.isMixinChanged())
{
- if (itemState.isNode())
- {
- addedNodes.add(uuid);
- }
- else
- {
- createNewOrAdd(uuid, itemState, updatedNodes);
- }
- }
- else if (itemState.isUpdated())
- {
createNewOrAdd(uuid, itemState, updatedNodes);
}
- else if (itemState.isMixinChanged())
+ else if (itemState.isDeleted())
{
- createNewOrAdd(uuid, itemState, updatedNodes);
+ addedNodes.remove(uuid);
+ removedNodes.add(uuid);
+
+ // remove all changes after node remove
+ updatedNodes.remove(uuid);
}
- else if (itemState.isDeleted())
+ }
+ else
+ {
+ if (itemState.isAdded() || itemState.isUpdated() || itemState.isDeleted())
{
- if (itemState.isNode())
+ if (!addedNodes.contains(uuid) && !removedNodes.contains(uuid) && !updatedNodes.containsKey(uuid))
{
- if (addedNodes.contains(uuid))
- {
- addedNodes.remove(uuid);
- removedNodes.remove(uuid);
- }
- else
- {
- removedNodes.add(uuid);
- }
- // remove all changes after node remove
- updatedNodes.remove(uuid);
+ createNewOrAdd(uuid, itemState, updatedNodes);
}
- else
- {
- if (!removedNodes.contains(uuid) && !addedNodes.contains(uuid))
- {
- createNewOrAdd(uuid, itemState, updatedNodes);
- }
- }
}
}
}
Added: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestUpdateProperty.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestUpdateProperty.java (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/usecases/query/TestUpdateProperty.java 2011-05-10 04:34:27 UTC (rev 4352)
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2003-2007 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.usecases.query;
+
+import org.exoplatform.services.jcr.usecases.BaseUsecasesTest;
+
+import javax.jcr.Node;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy Bazko</a>
+ * @version $Id: TestUpdateProperty.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class TestUpdateProperty extends BaseUsecasesTest
+{
+
+ public void testAddUpdateRemoveProperty() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ node.setProperty("prop2", "value2");
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value2')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ // the main issue that the last state is property deleting
+ node.setProperty("prop1", "value1-2");
+ node.setProperty("prop3", "value3");
+ node.getProperty("prop2").remove();
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1-2')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value2')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value3')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ // remove node
+ node.remove();
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1-2')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value3')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+ }
+
+ public void testMoveNode() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ node.setProperty("prop2", "value2");
+
+ node = node.addNode("subNode");
+ node.setProperty("prop21", "value21");
+ node.setProperty("prop22", "value22");
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value2')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value21')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value22')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ session.move("/testNode", "/testNode2");
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value2')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value21')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value22')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+ }
+
+ public void testSetRemovePropertyImmediatly() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ node.getProperty("prop1").remove();
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+ }
+
+ public void testSetRemoveProperty() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ node.getProperty("prop1").remove();
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+ }
+
+ public void testRemoveNodeUpdateProperty() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ node.setProperty("prop1", "value2");
+ node.remove();
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value2')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+ }
+
+ public void testRemoveNodeSetProperty() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ node.setProperty("prop2", "valu2");
+ node.remove();
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value2')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+ }
+
+ public void testRemoveNodeRemoveProperty() throws Exception
+ {
+
+ Node node = root.addNode("testNode");
+ node.setProperty("prop1", "value1");
+ root.save();
+
+ QueryManager manager = session.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(1, query.execute().getNodes().getSize());
+
+ node.getProperty("prop1").remove();
+ node.remove();
+ root.save();
+
+ query = manager.createQuery("SELECT * FROM nt:base " + " WHERE CONTAINS(., 'value1')", Query.SQL);
+ assertEquals(0, query.execute().getNodes().getSize());
+ }
+
+}
Added: jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1594/readme.txt
===================================================================
--- jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1594/readme.txt (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1594/readme.txt 2011-05-10 04:34:27 UTC (rev 4352)
@@ -0,0 +1,67 @@
+Summary
+
+ Status: Problem of renaming large folder in Webdav
+ CCP Issue: CCP-812, Product Jira Issue: JCR-1594. Backport of JCR-1591.
+ Complexity: Low
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+
+ Renaming folder in WebDAV takes a lot of time.
+
+Fix description
+
+How is the problem fixed?
+
+ Avoid unnecessary re-indexing operations for children nodes
+
+Patch information:
+Patch files: JCR-1594.patch
+
+Tests to perform
+
+Reproduction test
+
+ Run Tomcat AS and mount WebDAV folder. Create folder and copy pdf-files (more than 200mb). Try to rename folder, you can see that it takes a lot of time due to reindexing content.
+
+Tests performed at DevLevel
+
+ TCK tests, functional tests, manual testing on Tomcat AS
+
+Tests performed at QA/Support Level
+*
+
+Documentation changes
+
+Documentation changes:
+ No
+
+Configuration changes
+
+Configuration changes:
+ No
+
+Will previous configuration continue to work?
+ Yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+ No
+
+Is there a performance risk/cost?
+ No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch validated by PM
+
+Support Comment
+* Support review: Patch validated
+
+QA Feedbacks
+*
+
13 years
exo-jcr SVN: r4350 - in jcr/branches/1.12.x: exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command and 3 other directories.
by do-not-reply@jboss.org
Author: paristote
Date: 2011-05-10 00:14:43 -0400 (Tue, 10 May 2011)
New Revision: 4350
Added:
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/JCR-1593.patch
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/readme.txt
Modified:
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
Log:
JCR-1593
What is the problem to fix?
Using webdav with https, it's impossible to rename or move a file or directory. The applied Architecture is an Apache in front which manages the https and AJP connectors that transfer requests to the server JBoss
Problem analysis
This error is caused by the following line of code in WebDavServiceImpl.java:
destinationHeader = serverURI + escapePath(destinationHeader.substring(serverURI.length()));
The output of this line is https://localhost:443/rest/private/jcr/repositorylaboration/ so the workspace collaboration is not found. The consideration of the port 443 is badly done (By using Apache, we don't specify the port).
The path obtained by this line of code:
destinationHeader = TextUtil.unescape(destinationHeader, '%'); is correct (without the specification of the port 443)
There is no problem with http.
How is the problem fixed?
Change the algorithm of parsing destination URI and base URI. Now we use java.net.URI which itself does all the parsing.
Modified: jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-05-09 19:14:47 UTC (rev 4349)
+++ jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java 2011-05-10 04:14:43 UTC (rev 4350)
@@ -71,6 +71,7 @@
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
@@ -370,6 +371,9 @@
@HeaderParam(ExtHttpHeaders.OVERWRITE) String overwriteHeader, @Context UriInfo uriInfo, HierarchicalProperty body)
{
+ // to trace if an item on destination path exists
+ boolean itemExisted = false;
+
if (log.isDebugEnabled())
{
log.debug("COPY " + repoName + "/" + repoPath);
@@ -380,18 +384,27 @@
try
{
String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
+ URI dest = new URI(destinationHeader);
+ URI base = new URI(serverURI);
- destinationHeader = TextUtil.unescape(destinationHeader, '%');
+ String destPath = dest.getPath();
+ int repoIndex = destPath.indexOf(repoName);
- if (!destinationHeader.startsWith(serverURI))
+ // check if destination corresponds to base uri
+ // if the destination is on another server
+ // or destination header is malformed
+ // we return BAD_GATEWAY(502) HTTP status
+ // more info here http://www.webdav.org/specs/rfc2518.html#METHOD_COPY
+ if (!base.getHost().equals(dest.getHost()) || repoIndex == -1)
{
return Response.status(HTTPStatus.BAD_GATEWAY).entity("Bad Gateway").build();
}
+ destPath = normalizePath(dest.getPath().substring(repoIndex + repoName.length() + 1));
+
String srcWorkspace = workspaceName(repoPath);
String srcNodePath = path(repoPath);
- String destPath = destinationHeader.substring(serverURI.length() + 1);
String destWorkspace = workspaceName(destPath);
String destNodePath = path(destPath);
@@ -403,7 +416,8 @@
if (overwrite)
{
- delete(repoName, destPath, lockTokenHeader, ifHeader);
+ Response delResponse = delete(repoName, destPath, lockTokenHeader, ifHeader);
+ itemExisted = (delResponse.getStatus() == HTTPStatus.NO_CONTENT);
}
else
{
@@ -422,11 +436,11 @@
if (srcWorkspace.equals(destWorkspace))
{
Session session = session(repoName, destWorkspace, lockTokens);
- return new CopyCommand().copy(session, srcNodePath, destNodePath);
+ return new CopyCommand(itemExisted).copy(session, srcNodePath, destNodePath);
}
Session destSession = session(repoName, destWorkspace, lockTokens);
- return new CopyCommand().copy(destSession, srcWorkspace, srcNodePath, destNodePath);
+ return new CopyCommand(itemExisted).copy(destSession, srcWorkspace, srcNodePath, destNodePath);
}
else if (depth.getIntValue() == 0)
@@ -748,6 +762,9 @@
@HeaderParam(ExtHttpHeaders.OVERWRITE) String overwriteHeader, @Context UriInfo uriInfo, HierarchicalProperty body)
{
+ // to trace if an item on destination path exists
+ boolean itemExisted = false;
+
if (log.isDebugEnabled())
{
log.debug("MOVE " + repoName + "/" + repoPath);
@@ -759,14 +776,26 @@
{
String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
- destinationHeader = TextUtil.unescape(destinationHeader, '%');
+ URI dest = new URI(destinationHeader);
+ URI base = new URI(serverURI);
+ String destPath = dest.getPath();
+ int repoIndex = destPath.indexOf(repoName);
+
+ // check if destination corresponds to base uri
+ // if the destination is on another server
+ // or destination header is malformed
+ // we return BAD_GATEWAY(502) HTTP status
+ // more info here http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE
+ if (!base.getHost().equals(dest.getHost()) || repoIndex == -1)
+
if (!destinationHeader.startsWith(serverURI))
{
return Response.status(HTTPStatus.BAD_GATEWAY).entity("Bad Gateway").build();
}
- String destPath = destinationHeader.substring(serverURI.length() + 1);
+ destPath = normalizePath(dest.getPath().substring(repoIndex + repoName.length() + 1));
+
String destWorkspace = workspaceName(destPath);
String destNodePath = path(destPath);
@@ -781,7 +810,8 @@
if (overwrite)
{
- delete(repoName, destPath, lockTokenHeader, ifHeader);
+ Response delResponse = delete(repoName, destPath, lockTokenHeader, ifHeader);
+ itemExisted = (delResponse.getStatus() == HTTPStatus.NO_CONTENT);
}
else
{
@@ -801,12 +831,12 @@
if (srcWorkspace.equals(destWorkspace))
{
Session session = session(repoName, srcWorkspace, lockTokens);
- return new MoveCommand().move(session, srcNodePath, destNodePath);
+ return new MoveCommand(itemExisted).move(session, srcNodePath, destNodePath);
}
Session srcSession = session(repoName, srcWorkspace, lockTokens);
Session destSession = session(repoName, destWorkspace, lockTokens);
- return new MoveCommand().move(srcSession, destSession, srcNodePath, destNodePath);
+ return new MoveCommand(itemExisted).move(srcSession, destSession, srcNodePath, destNodePath);
}
else
{
Modified: jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-05-09 19:14:47 UTC (rev 4349)
+++ jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java 2011-05-10 04:14:43 UTC (rev 4350)
@@ -46,6 +46,31 @@
private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.CopyCommand");
/**
+ * To trace if an item on destination path existed.
+ */
+
+ final private boolean itemExisted;
+
+ public CopyCommand()
+ {
+ this.itemExisted = false;
+ }
+
+ /**
+ * Here we pass info about pre-existence of item on the move
+ * destination path If an item existed, we must respond with NO_CONTENT (204)
+ * HTTP status.
+ * If an item did not exist, we must respond with CREATED (201) HTTP status
+ * More info can be found <a
+ * href=http://www.webdav.org/specs/rfc2518.html#METHOD_COPY>here</a>.
+ *
+ */
+ public CopyCommand(boolean itemExisted)
+ {
+ this.itemExisted = itemExisted;
+ }
+
+ /**
* Webdav COPY method implementation for the same workspace.
*
* @param destSession destination session
@@ -58,7 +83,18 @@
try
{
destSession.getWorkspace().copy(sourcePath, destPath);
- return Response.status(HTTPStatus.CREATED).build();
+ // If the source resource was successfully moved
+ // to a pre-existing destination resource.
+ if (itemExisted)
+ {
+ return Response.status(HTTPStatus.NO_CONTENT).build();
+ }
+ // If the source resource was successfully moved,
+ // and a new resource was created at the destination.
+ else
+ {
+ return Response.status(HTTPStatus.CREATED).build();
+ }
}
catch (ItemExistsException e)
{
@@ -97,7 +133,18 @@
try
{
destSession.getWorkspace().copy(sourceWorkspace, sourcePath, destPath);
- return Response.status(HTTPStatus.CREATED).build();
+ // If the source resource was successfully moved
+ // to a pre-existing destination resource.
+ if (itemExisted)
+ {
+ return Response.status(HTTPStatus.NO_CONTENT).build();
+ }
+ // If the source resource was successfully moved,
+ // and a new resource was created at the destination.
+ else
+ {
+ return Response.status(HTTPStatus.CREATED).build();
+ }
}
catch (ItemExistsException e)
{
Modified: jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-05-09 19:14:47 UTC (rev 4349)
+++ jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java 2011-05-10 04:14:43 UTC (rev 4350)
@@ -44,6 +44,12 @@
private static CacheControl cacheControl = new CacheControl();
/**
+ * To trace if an item on destination path existed.
+ */
+
+ final private boolean itemExisted;
+
+ /**
* Logger.
*/
private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.MoveCommand");
@@ -54,7 +60,27 @@
cacheControl.setNoCache(true);
}
+ public MoveCommand()
+ {
+ this.itemExisted = false;
+ }
+
/**
+ * Here we pass info about pre-existence of item on the move
+ * destination path If an item existed, we must respond with NO_CONTENT (204)
+ * HTTP status.
+ * If an item did not exist, we must respond with CREATED (201) HTTP status
+ * More info can be found <a
+ * href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>here</a>.
+ * @param uriBuilder - provide data used in 'location' header
+ * @param itemExisted - indicates if an item existed on copy destination
+ */
+ public MoveCommand(boolean itemExisted)
+ {
+ this.itemExisted = itemExisted;
+ }
+
+ /**
* Webdav Move method implementation.
*
* @param session current session.
@@ -66,20 +92,17 @@
{
try
{
-
- boolean itemExisted = session.itemExists(destPath);
- if (itemExisted)
- {
- session.getItem(destPath).remove();
- }
-
session.move(srcPath, destPath);
session.save();
+ // If the source resource was successfully moved
+ // to a pre-existing destination resource.
if (itemExisted)
{
return Response.status(HTTPStatus.NO_CONTENT).cacheControl(cacheControl).build();
}
+ // If the source resource was successfully moved,
+ // and a new resource was created at the destination.
else
{
return Response.status(HTTPStatus.CREATED).cacheControl(cacheControl).build();
Modified: jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java 2011-05-09 19:14:47 UTC (rev 4349)
+++ jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java 2011-05-10 04:14:43 UTC (rev 4350)
@@ -39,6 +39,7 @@
*/
public class TestCopy extends BaseStandaloneTest
{
+ static final String host = "http://localhost:8080";
public void testeCopyForNonCollectionSingleWorkSpace() throws Exception
{
@@ -48,8 +49,8 @@
TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
String destFilename = TestUtils.getFileName();
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
- headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
- ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
assertEquals(HTTPStatus.CREATED, response.getStatus());
assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
Node nodeDest = session.getRootNode().getNode(TextUtil.relativizePath(destFilename));
@@ -78,8 +79,8 @@
TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
String destFilename = TestUtils.getFileName();
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
- headers.add(ExtHttpHeaders.DESTINATION, getPathDestWS() + destFilename);
- ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathDestWS() + destFilename);
+ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
assertEquals(HTTPStatus.CREATED, response.getStatus());
assertTrue(destSession.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
@@ -101,6 +102,101 @@
}
+ /**
+ * Testing for correct destination header parsing in COPY method.
+ * We pass a path which contains escaped space - "%20"
+ * and escaped space with quote symbol "%20'"
+ * @throws Exception
+ */
+ public void testDestinationHeaderParsing() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+ String destFilename = TestUtils.getFileName() + "%20test";
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ filename = destFilename;
+
+ destFilename = TestUtils.getFileName() + "%20'test";
+
+ // prepare headers
+ headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+ // execute the query
+ response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ }
+
+ /**
+ * Testing for correct response after COPY a resource to the destination,
+ * where another resource already existed
+ * For more info see <a href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>this</a>.
+ * @throws Exception
+ */
+ public void testNoContentResponses() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+ String destFilename = TestUtils.getFileName();
+ inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, destFilename, inputStream, defaultFileNodeType, "");
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+ headers.add(ExtHttpHeaders.OVERWRITE, "T");
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
+
+ }
+
+ /**
+ * Testing for correct destination header parsing using "https"
+ * instead of usual "http" scheme.
+ * @throws Exception
+ */
+ public void testHttpsSchemeInDestinationHeaderParsing() throws Exception
+ {
+ String httpsHost = "https://localhost:8080";
+
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+ String destFilename = TestUtils.getFileName();
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, httpsHost + getPathWS() + destFilename);
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ }
+
@Override
protected String getRepositoryName()
{
Modified: jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java 2011-05-09 19:14:47 UTC (rev 4349)
+++ jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java 2011-05-10 04:14:43 UTC (rev 4350)
@@ -40,6 +40,8 @@
public class TestMove extends BaseStandaloneTest
{
+ final static String host = "http://localhost:8080";
+
public void testMoveForNonCollectionSingleWorkspace() throws Exception
{
String content = TestUtils.getFileContent();
@@ -48,8 +50,8 @@
TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
String destFilename = TestUtils.getFileName();
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
- headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
- ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
assertEquals(HTTPStatus.CREATED, response.getStatus());
assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
Node nodeDest = session.getRootNode().getNode(TextUtil.relativizePath(destFilename));
@@ -71,8 +73,8 @@
TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
String destFilename = TestUtils.getFileName();
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
- headers.add(ExtHttpHeaders.DESTINATION, getPathDestWS() + destFilename);
- ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathDestWS() + destFilename);
+ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
assertTrue(destSession.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
Node nodeDest = destSession.getRootNode().getNode(TextUtil.relativizePath(destFilename));
@@ -85,6 +87,101 @@
assertFalse(session.getRootNode().hasNode(TextUtil.relativizePath(filename)));
}
+ /**
+ * Testing for correct destination header parsing in MOVE method.
+ * We pass a path which contains escaped space - "%20"
+ * and escaped space with quote symbol "%20'"
+ * @throws Exception
+ */
+ public void testDestinationHeaderParsing() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+ String destFilename = TestUtils.getFileName() + "%20test";
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ filename = destFilename;
+
+ destFilename = TestUtils.getFileName() + "%20'test";
+
+ // prepare headers
+ headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+ // execute the query
+ response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ }
+
+ /**
+ * Testing for correct response after MOVE a resource to the destination,
+ * where another resource already existed
+ * For more info see <a href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>this</a>.
+ * @throws Exception
+ */
+ public void testNoContentResponses() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+ String destFilename = TestUtils.getFileName();
+ inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, destFilename, inputStream, defaultFileNodeType, "");
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+ headers.add(ExtHttpHeaders.OVERWRITE, "T");
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
+
+ }
+
+ /**
+ * Testing for correct destination header parsing using "https"
+ * instead of usual "http" scheme.
+ * @throws Exception
+ */
+ public void testHttpsSchemeInDestinationHeaderParsing() throws Exception
+ {
+ String httpsHost = "https://localhost:8080";
+
+ String content = TestUtils.getFileContent();
+ String filename = TestUtils.getFileName();
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+ String destFilename = TestUtils.getFileName();
+
+ // prepare headers
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(ExtHttpHeaders.DESTINATION, httpsHost + getPathWS() + destFilename);
+
+ // execute the query
+ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+ // check if operation completed successfully, we expect a new resource to be created
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ }
+
@Override
protected String getRepositoryName()
{
Added: jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/JCR-1593.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/JCR-1593.patch (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/JCR-1593.patch 2011-05-10 04:14:43 UTC (rev 4350)
@@ -0,0 +1,560 @@
+Index: exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
+===================================================================
+--- exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java (revision 4038)
++++ exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java (working copy)
+@@ -40,6 +40,8 @@
+ public class TestMove extends BaseStandaloneTest
+ {
+
++ final static String host = "http://localhost:8080";
++
+ public void testMoveForNonCollectionSingleWorkspace() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+@@ -48,8 +50,8 @@
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+ String destFilename = TestUtils.getFileName();
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+- headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
+- ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+ assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
+ Node nodeDest = session.getRootNode().getNode(TextUtil.relativizePath(destFilename));
+@@ -71,8 +73,8 @@
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+ String destFilename = TestUtils.getFileName();
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+- headers.add(ExtHttpHeaders.DESTINATION, getPathDestWS() + destFilename);
+- ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathDestWS() + destFilename);
++ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+ assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
+ assertTrue(destSession.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
+ Node nodeDest = destSession.getRootNode().getNode(TextUtil.relativizePath(destFilename));
+@@ -85,6 +87,101 @@
+ assertFalse(session.getRootNode().hasNode(TextUtil.relativizePath(filename)));
+ }
+
++ /**
++ * Testing for correct destination header parsing in MOVE method.
++ * We pass a path which contains escaped space - "%20"
++ * and escaped space with quote symbol "%20'"
++ * @throws Exception
++ */
++ public void testDestinationHeaderParsing() throws Exception
++ {
++ String content = TestUtils.getFileContent();
++ String filename = TestUtils.getFileName();
++ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
++
++ String destFilename = TestUtils.getFileName() + "%20test";
++
++ // prepare headers
++ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++
++ // execute the query
++ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.CREATED, response.getStatus());
++
++ filename = destFilename;
++
++ destFilename = TestUtils.getFileName() + "%20'test";
++
++ // prepare headers
++ headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++
++ // execute the query
++ response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.CREATED, response.getStatus());
++
++ }
++
++ /**
++ * Testing for correct response after MOVE a resource to the destination,
++ * where another resource already existed
++ * For more info see <a href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>this</a>.
++ * @throws Exception
++ */
++ public void testNoContentResponses() throws Exception
++ {
++ String content = TestUtils.getFileContent();
++ String filename = TestUtils.getFileName();
++ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
++
++ String destFilename = TestUtils.getFileName();
++ inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, destFilename, inputStream, defaultFileNodeType, "");
++
++ // prepare headers
++ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++ headers.add(ExtHttpHeaders.OVERWRITE, "T");
++
++ // execute the query
++ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
++
++ }
++
++ /**
++ * Testing for correct destination header parsing using "https"
++ * instead of usual "http" scheme.
++ * @throws Exception
++ */
++ public void testHttpsSchemeInDestinationHeaderParsing() throws Exception
++ {
++ String httpsHost = "https://localhost:8080";
++
++ String content = TestUtils.getFileContent();
++ String filename = TestUtils.getFileName();
++ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
++
++ String destFilename = TestUtils.getFileName();
++
++ // prepare headers
++ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, httpsHost + getPathWS() + destFilename);
++
++ // execute the query
++ ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.CREATED, response.getStatus());
++
++ }
++
+ @Override
+ protected String getRepositoryName()
+ {
+Index: exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
+===================================================================
+--- exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java (revision 4038)
++++ exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java (working copy)
+@@ -39,6 +39,7 @@
+ */
+ public class TestCopy extends BaseStandaloneTest
+ {
++ static final String host = "http://localhost:8080";
+
+ public void testeCopyForNonCollectionSingleWorkSpace() throws Exception
+ {
+@@ -48,8 +49,8 @@
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+ String destFilename = TestUtils.getFileName();
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+- headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
+- ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+ assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
+ Node nodeDest = session.getRootNode().getNode(TextUtil.relativizePath(destFilename));
+@@ -78,8 +79,8 @@
+ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+ String destFilename = TestUtils.getFileName();
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+- headers.add(ExtHttpHeaders.DESTINATION, getPathDestWS() + destFilename);
+- ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathDestWS() + destFilename);
++ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+ assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+ assertTrue(destSession.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
+@@ -101,6 +102,101 @@
+
+ }
+
++ /**
++ * Testing for correct destination header parsing in COPY method.
++ * We pass a path which contains escaped space - "%20"
++ * and escaped space with quote symbol "%20'"
++ * @throws Exception
++ */
++ public void testDestinationHeaderParsing() throws Exception
++ {
++ String content = TestUtils.getFileContent();
++ String filename = TestUtils.getFileName();
++ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
++
++ String destFilename = TestUtils.getFileName() + "%20test";
++
++ // prepare headers
++ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++
++ // execute the query
++ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.CREATED, response.getStatus());
++
++ filename = destFilename;
++
++ destFilename = TestUtils.getFileName() + "%20'test";
++
++ // prepare headers
++ headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++
++ // execute the query
++ response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.CREATED, response.getStatus());
++
++ }
++
++ /**
++ * Testing for correct response after COPY a resource to the destination,
++ * where another resource already existed
++ * For more info see <a href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>this</a>.
++ * @throws Exception
++ */
++ public void testNoContentResponses() throws Exception
++ {
++ String content = TestUtils.getFileContent();
++ String filename = TestUtils.getFileName();
++ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
++
++ String destFilename = TestUtils.getFileName();
++ inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, destFilename, inputStream, defaultFileNodeType, "");
++
++ // prepare headers
++ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
++ headers.add(ExtHttpHeaders.OVERWRITE, "T");
++
++ // execute the query
++ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
++
++ }
++
++ /**
++ * Testing for correct destination header parsing using "https"
++ * instead of usual "http" scheme.
++ * @throws Exception
++ */
++ public void testHttpsSchemeInDestinationHeaderParsing() throws Exception
++ {
++ String httpsHost = "https://localhost:8080";
++
++ String content = TestUtils.getFileContent();
++ String filename = TestUtils.getFileName();
++ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
++ TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
++
++ String destFilename = TestUtils.getFileName();
++
++ // prepare headers
++ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
++ headers.add(ExtHttpHeaders.DESTINATION, httpsHost + getPathWS() + destFilename);
++
++ // execute the query
++ ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
++ // check if operation completed successfully, we expect a new resource to be created
++ assertEquals(HTTPStatus.CREATED, response.getStatus());
++
++ }
++
+ @Override
+ protected String getRepositoryName()
+ {
+Index: exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
+===================================================================
+--- exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java (revision 4038)
++++ exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java (working copy)
+@@ -71,6 +71,7 @@
+ import java.io.InputStream;
+ import java.lang.annotation.Annotation;
+ import java.lang.reflect.Method;
++import java.net.URI;
+ import java.net.URLEncoder;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+@@ -370,6 +371,9 @@
+ @HeaderParam(ExtHttpHeaders.OVERWRITE) String overwriteHeader, @Context UriInfo uriInfo, HierarchicalProperty body)
+ {
+
++ // to trace if an item on destination path exists
++ boolean itemExisted = false;
++
+ if (log.isDebugEnabled())
+ {
+ log.debug("COPY " + repoName + "/" + repoPath);
+@@ -380,18 +384,27 @@
+ try
+ {
+ String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
++ URI dest = new URI(destinationHeader);
++ URI base = new URI(serverURI);
+
+- destinationHeader = TextUtil.unescape(destinationHeader, '%');
++ String destPath = dest.getPath();
++ int repoIndex = destPath.indexOf(repoName);
+
+- if (!destinationHeader.startsWith(serverURI))
++ // check if destination corresponds to base uri
++ // if the destination is on another server
++ // or destination header is malformed
++ // we return BAD_GATEWAY(502) HTTP status
++ // more info here http://www.webdav.org/specs/rfc2518.html#METHOD_COPY
++ if (!base.getHost().equals(dest.getHost()) || repoIndex == -1)
+ {
+ return Response.status(HTTPStatus.BAD_GATEWAY).entity("Bad Gateway").build();
+ }
+
++ destPath = normalizePath(dest.getPath().substring(repoIndex + repoName.length() + 1));
++
+ String srcWorkspace = workspaceName(repoPath);
+ String srcNodePath = path(repoPath);
+
+- String destPath = destinationHeader.substring(serverURI.length() + 1);
+ String destWorkspace = workspaceName(destPath);
+ String destNodePath = path(destPath);
+
+@@ -403,7 +416,8 @@
+
+ if (overwrite)
+ {
+- delete(repoName, destPath, lockTokenHeader, ifHeader);
++ Response delResponse = delete(repoName, destPath, lockTokenHeader, ifHeader);
++ itemExisted = (delResponse.getStatus() == HTTPStatus.NO_CONTENT);
+ }
+ else
+ {
+@@ -422,11 +436,11 @@
+ if (srcWorkspace.equals(destWorkspace))
+ {
+ Session session = session(repoName, destWorkspace, lockTokens);
+- return new CopyCommand().copy(session, srcNodePath, destNodePath);
++ return new CopyCommand(itemExisted).copy(session, srcNodePath, destNodePath);
+ }
+
+ Session destSession = session(repoName, destWorkspace, lockTokens);
+- return new CopyCommand().copy(destSession, srcWorkspace, srcNodePath, destNodePath);
++ return new CopyCommand(itemExisted).copy(destSession, srcWorkspace, srcNodePath, destNodePath);
+
+ }
+ else if (depth.getIntValue() == 0)
+@@ -748,6 +762,9 @@
+ @HeaderParam(ExtHttpHeaders.OVERWRITE) String overwriteHeader, @Context UriInfo uriInfo, HierarchicalProperty body)
+ {
+
++ // to trace if an item on destination path exists
++ boolean itemExisted = false;
++
+ if (log.isDebugEnabled())
+ {
+ log.debug("MOVE " + repoName + "/" + repoPath);
+@@ -759,14 +776,26 @@
+ {
+ String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
+
+- destinationHeader = TextUtil.unescape(destinationHeader, '%');
++ URI dest = new URI(destinationHeader);
++ URI base = new URI(serverURI);
+
++ String destPath = dest.getPath();
++ int repoIndex = destPath.indexOf(repoName);
++
++ // check if destination corresponds to base uri
++ // if the destination is on another server
++ // or destination header is malformed
++ // we return BAD_GATEWAY(502) HTTP status
++ // more info here http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE
++ if (!base.getHost().equals(dest.getHost()) || repoIndex == -1)
++
+ if (!destinationHeader.startsWith(serverURI))
+ {
+ return Response.status(HTTPStatus.BAD_GATEWAY).entity("Bad Gateway").build();
+ }
+
+- String destPath = destinationHeader.substring(serverURI.length() + 1);
++ destPath = normalizePath(dest.getPath().substring(repoIndex + repoName.length() + 1));
++
+ String destWorkspace = workspaceName(destPath);
+ String destNodePath = path(destPath);
+
+@@ -781,7 +810,8 @@
+
+ if (overwrite)
+ {
+- delete(repoName, destPath, lockTokenHeader, ifHeader);
++ Response delResponse = delete(repoName, destPath, lockTokenHeader, ifHeader);
++ itemExisted = (delResponse.getStatus() == HTTPStatus.NO_CONTENT);
+ }
+ else
+ {
+@@ -801,12 +831,12 @@
+ if (srcWorkspace.equals(destWorkspace))
+ {
+ Session session = session(repoName, srcWorkspace, lockTokens);
+- return new MoveCommand().move(session, srcNodePath, destNodePath);
++ return new MoveCommand(itemExisted).move(session, srcNodePath, destNodePath);
+ }
+
+ Session srcSession = session(repoName, srcWorkspace, lockTokens);
+ Session destSession = session(repoName, destWorkspace, lockTokens);
+- return new MoveCommand().move(srcSession, destSession, srcNodePath, destNodePath);
++ return new MoveCommand(itemExisted).move(srcSession, destSession, srcNodePath, destNodePath);
+ }
+ else
+ {
+Index: exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
+===================================================================
+--- exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java (revision 4038)
++++ exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java (working copy)
+@@ -44,6 +44,12 @@
+ private static CacheControl cacheControl = new CacheControl();
+
+ /**
++ * To trace if an item on destination path existed.
++ */
++
++ final private boolean itemExisted;
++
++ /**
+ * Logger.
+ */
+ private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.MoveCommand");
+@@ -54,7 +60,27 @@
+ cacheControl.setNoCache(true);
+ }
+
++ public MoveCommand()
++ {
++ this.itemExisted = false;
++ }
++
+ /**
++ * Here we pass info about pre-existence of item on the move
++ * destination path If an item existed, we must respond with NO_CONTENT (204)
++ * HTTP status.
++ * If an item did not exist, we must respond with CREATED (201) HTTP status
++ * More info can be found <a
++ * href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>here</a>.
++ * @param uriBuilder - provide data used in 'location' header
++ * @param itemExisted - indicates if an item existed on copy destination
++ */
++ public MoveCommand(boolean itemExisted)
++ {
++ this.itemExisted = itemExisted;
++ }
++
++ /**
+ * Webdav Move method implementation.
+ *
+ * @param session current session.
+@@ -66,20 +92,17 @@
+ {
+ try
+ {
+-
+- boolean itemExisted = session.itemExists(destPath);
+- if (itemExisted)
+- {
+- session.getItem(destPath).remove();
+- }
+-
+ session.move(srcPath, destPath);
+ session.save();
+
++ // If the source resource was successfully moved
++ // to a pre-existing destination resource.
+ if (itemExisted)
+ {
+ return Response.status(HTTPStatus.NO_CONTENT).cacheControl(cacheControl).build();
+ }
++ // If the source resource was successfully moved,
++ // and a new resource was created at the destination.
+ else
+ {
+ return Response.status(HTTPStatus.CREATED).cacheControl(cacheControl).build();
+Index: exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
+===================================================================
+--- exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java (revision 4038)
++++ exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java (working copy)
+@@ -46,6 +46,31 @@
+ private static Log log = ExoLogger.getLogger("exo.jcr.component.webdav.CopyCommand");
+
+ /**
++ * To trace if an item on destination path existed.
++ */
++
++ final private boolean itemExisted;
++
++ public CopyCommand()
++ {
++ this.itemExisted = false;
++ }
++
++ /**
++ * Here we pass info about pre-existence of item on the move
++ * destination path If an item existed, we must respond with NO_CONTENT (204)
++ * HTTP status.
++ * If an item did not exist, we must respond with CREATED (201) HTTP status
++ * More info can be found <a
++ * href=http://www.webdav.org/specs/rfc2518.html#METHOD_COPY>here</a>.
++ *
++ */
++ public CopyCommand(boolean itemExisted)
++ {
++ this.itemExisted = itemExisted;
++ }
++
++ /**
+ * Webdav COPY method implementation for the same workspace.
+ *
+ * @param destSession destination session
+@@ -58,7 +83,18 @@
+ try
+ {
+ destSession.getWorkspace().copy(sourcePath, destPath);
+- return Response.status(HTTPStatus.CREATED).build();
++ // If the source resource was successfully moved
++ // to a pre-existing destination resource.
++ if (itemExisted)
++ {
++ return Response.status(HTTPStatus.NO_CONTENT).build();
++ }
++ // If the source resource was successfully moved,
++ // and a new resource was created at the destination.
++ else
++ {
++ return Response.status(HTTPStatus.CREATED).build();
++ }
+ }
+ catch (ItemExistsException e)
+ {
+@@ -97,7 +133,18 @@
+ try
+ {
+ destSession.getWorkspace().copy(sourceWorkspace, sourcePath, destPath);
+- return Response.status(HTTPStatus.CREATED).build();
++ // If the source resource was successfully moved
++ // to a pre-existing destination resource.
++ if (itemExisted)
++ {
++ return Response.status(HTTPStatus.NO_CONTENT).build();
++ }
++ // If the source resource was successfully moved,
++ // and a new resource was created at the destination.
++ else
++ {
++ return Response.status(HTTPStatus.CREATED).build();
++ }
+ }
+ catch (ItemExistsException e)
+ {
Added: jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/readme.txt
===================================================================
--- jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/readme.txt (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1593/readme.txt 2011-05-10 04:14:43 UTC (rev 4350)
@@ -0,0 +1,84 @@
+Summary
+
+ Status: Problem with the move function of webdav on https
+ CCP Issue: CCP-799, Product Jira Issue: JCR-1593. Backport of JCR-1588.
+ Complexity: low
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+
+ Using webdav with https, it's impossible to rename or move a file or directory. The applied Architecture is an Apache in front which manages the https and AJP connectors that transfer requests to the server JBoss
+
+Fix description
+
+Problem analysis
+This error is caused by the following line of code in WebDavServiceImpl.java:
+
+destinationHeader = serverURI + escapePath(destinationHeader.substring(serverURI.length()));
+
+The output of this line is https://localhost:443/rest/private/jcr/repositorylaboration/ so the workspace collaboration is not found. The consideration of the port 443 is badly done (By using Apache, we don't specify the port).
+The path obtained by this line of code:
+
+destinationHeader = TextUtil.unescape(destinationHeader, '%'); is correct (without the specification of the port 443)
+
+There is no problem with http.
+
+How is the problem fixed?
+
+ Change the algorithm of parsing destination URI and base URI. Now we use java.net.URI which itself does all the parsing.
+
+Patch information:
+
+ Final files to use should be attached to this page (Jira is for the discussion)
+
+Patch files:
+There are currently no attachments on this page.
+Tests to perform
+
+Reproduction test
+* Steps to reproduce:
+1. Create a webfolder using https:https://localhost/rest/private/jcr/repository/collaboration/
+2. In this webfolder, create or upload a repository
+3. Try to rename the directory or file. => An error
+
+Tests performed at DevLevel
+
+ Tested MOVE methods for move and rename operations with Dolphin and Nautilus webdav clients.
+
+Tests performed at QA/Support Level
+*
+
+Documentation changes
+
+Documentation changes:
+ None
+
+Configuration changes
+
+Configuration changes:
+ None
+
+Will previous configuration continue to work?
+ Yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+ No
+
+Is there a performance risk/cost?
+ No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch approved
+
+Support Comment
+* Patch validated
+
+QA Feedbacks
+*
+
13 years
exo-jcr SVN: r4349 - in jcr/branches/1.12.x/patch/1.12.9-GA: JCR-1622 and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-05-09 15:14:47 -0400 (Mon, 09 May 2011)
New Revision: 4349
Added:
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1622/
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1622/JCR-1622.patch
Log:
JCR-1622: patch proposed
Added: jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1622/JCR-1622.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1622/JCR-1622.patch (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1622/JCR-1622.patch 2011-05-09 19:14:47 UTC (rev 4349)
@@ -0,0 +1,167 @@
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java (revision 4347)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockRemoverHolder.java (working copy)
+@@ -20,6 +20,7 @@
+
+ import org.exoplatform.services.jcr.config.RepositoryEntry;
+ import org.exoplatform.services.jcr.impl.proccess.WorkerService;
++import org.picocontainer.Startable;
+
+ /**
+ * LockRemoverHolder holds is a single per-repository LockRemover container.
+@@ -27,7 +28,7 @@
+ * @author <a href="mailto:karpenko.sergiy@gmail.com">Karpenko Sergiy</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z aheritier $
+ */
+-public class LockRemoverHolder
++public class LockRemoverHolder implements Startable
+ {
+
+ /**
+@@ -80,4 +81,19 @@
+ return new LockRemover(workerService, lockManager, timeout);
+ }
+
++ /**
++ * @see org.picocontainer.Startable#start()
++ */
++ public void start()
++ {
++ }
++
++ /**
++ * @see org.picocontainer.Startable#stop()
++ */
++ public void stop()
++ {
++ workerService.stop();
++ }
++
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java (revision 4347)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java (working copy)
+@@ -33,6 +33,7 @@
+ import org.exoplatform.services.jcr.impl.Constants;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
++import org.picocontainer.Startable;
+
+ import java.util.ArrayList;
+ import java.util.Calendar;
+@@ -59,7 +60,7 @@
+ * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id: LinkedWorkspaceStorageCacheImpl.java 34801 2009-07-31 15:44:50Z dkatayev $
+ */
+-public class LinkedWorkspaceStorageCacheImpl implements WorkspaceStorageCache
++public class LinkedWorkspaceStorageCacheImpl implements WorkspaceStorageCache, Startable
+ {
+
+ /**
+@@ -763,28 +764,6 @@
+ }
+ }
+
+- /**
+- * {@inheritDoc}
+- */
+- @Override
+- protected void finalize() throws Throwable
+- {
+- try
+- {
+- workerTimer.cancel();
+- }
+- catch (Throwable e)
+- {
+- System.err.println(this.name + " cache, finalyze error " + e);
+- }
+-
+- nodesCache.clear();
+- propertiesCache.clear();
+- cache.clear();
+-
+- super.finalize();
+- }
+-
+ private void scheduleTask(TimerTask task, int start, long period)
+ {
+ Calendar firstTime = Calendar.getInstance();
+@@ -2000,4 +1979,33 @@
+ {
+ return true;
+ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public void start()
++ {
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public void stop()
++ {
++ if (workerTimer != null)
++ {
++ try
++ {
++ workerTimer.cancel();
++ }
++ catch (Throwable e)
++ {
++ LOG.warn(this.name + " cache, stop error " + e);
++ }
++ }
++
++ nodesCache.clear();
++ propertiesCache.clear();
++ cache.clear();
++ }
+ }
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java (revision 4347)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleanerHolder.java (working copy)
+@@ -18,6 +18,8 @@
+ */
+ package org.exoplatform.services.jcr.impl.util.io;
+
++import org.picocontainer.Startable;
++
+ /**
+ * Created by The eXo Platform SAS. <br/> per workspace container file cleaner holder object
+ *
+@@ -25,7 +27,7 @@
+ * @version $Id: WorkspaceFileCleanerHolder.java 11907 2008-03-13 15:36:21Z ksm $
+ */
+
+-public class FileCleanerHolder
++public class FileCleanerHolder implements Startable
+ {
+
+ private final FileCleaner fileCleaner;
+@@ -40,4 +42,19 @@
+ return fileCleaner;
+ }
+
++ /**
++ * @see org.picocontainer.Startable#start()
++ */
++ public void start()
++ {
++ }
++
++ /**
++ * @see org.picocontainer.Startable#stop()
++ */
++ public void stop()
++ {
++ fileCleaner.halt();
++ }
++
+ }
13 years
exo-jcr SVN: r4348 - in ws/branches/2.1.x/patch/2.1.9-GA: WS-265 and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-05-09 15:05:55 -0400 (Mon, 09 May 2011)
New Revision: 4348
Added:
ws/branches/2.1.x/patch/2.1.9-GA/WS-265/
ws/branches/2.1.x/patch/2.1.9-GA/WS-265/WS-265.patch
Log:
WS-265: commiting the actual patch for 2.1.9-GA
Added: ws/branches/2.1.x/patch/2.1.9-GA/WS-265/WS-265.patch
===================================================================
--- ws/branches/2.1.x/patch/2.1.9-GA/WS-265/WS-265.patch (rev 0)
+++ ws/branches/2.1.x/patch/2.1.9-GA/WS-265/WS-265.patch 2011-05-09 19:05:55 UTC (rev 4348)
@@ -0,0 +1,47 @@
+Index: exo.ws.frameworks.servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/StandaloneContainerInitializedListener.java
+===================================================================
+--- exo.ws.frameworks.servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/StandaloneContainerInitializedListener.java (revision 4346)
++++ exo.ws.frameworks.servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/StandaloneContainerInitializedListener.java (working copy)
+@@ -19,7 +19,6 @@
+ package org.exoplatform.ws.frameworks.servlet;
+
+ import org.exoplatform.container.StandaloneContainer;
+-import org.exoplatform.container.configuration.ConfigurationManagerImpl;
+ import org.exoplatform.services.log.ExoLogger;
+ import org.exoplatform.services.log.Log;
+ import org.exoplatform.services.naming.InitialContextInitializer;
+@@ -80,13 +79,25 @@
+ LOG.error("Error of configurationURL read", e);
+ }
+
++ // If no configuration in web.xml check system property.
++ if (configurationURL == null)
++ configurationURL = System.getProperty(CONF_URL_PARAMETER);
++
+ try
+ {
+ StandaloneContainer.addConfigurationURL(configurationURL);
+ }
+ catch (MalformedURLException e)
+ {
+- LOG.error("Error of addConfigurationURL", e);
++ // Try to use path, we do not need have full path (file:/path/conf) to configuration. Any relative path is OK.
++ try
++ {
++ StandaloneContainer.addConfigurationPath(configurationURL);
++ }
++ catch (MalformedURLException e2)
++ {
++ LOG.error("Error of addConfiguration", e2);
++ }
+ }
+
+ try
+@@ -116,6 +127,6 @@
+ */
+ public void contextDestroyed(ServletContextEvent event)
+ {
+- // container.stop();
++ container.stop();
+ }
+ }
13 years
exo-jcr SVN: r4347 - in kernel/trunk/exo.kernel.component.command: src/test/java/org/exoplatform/services/command and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-05-06 12:16:07 -0400 (Fri, 06 May 2011)
New Revision: 4347
Modified:
kernel/trunk/exo.kernel.component.command/pom.xml
kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/CommandServiceTest.java
kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/MultiConfigServiceTest.java
Log:
EXOJCR-1050 EXOJCR-1049 : The configuration path was wrong
Modified: kernel/trunk/exo.kernel.component.command/pom.xml
===================================================================
--- kernel/trunk/exo.kernel.component.command/pom.xml 2011-05-05 18:56:45 UTC (rev 4346)
+++ kernel/trunk/exo.kernel.component.command/pom.xml 2011-05-06 16:16:07 UTC (rev 4347)
@@ -77,10 +77,6 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
- <excludes>
- <exclude>**/CommandServiceTest.java</exclude>
- <exclude>**/MultiConfigServiceTest.java</exclude>
- </excludes>
</configuration>
</plugin>
<plugin>
Modified: kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/CommandServiceTest.java
===================================================================
--- kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/CommandServiceTest.java 2011-05-05 18:56:45 UTC (rev 4346)
+++ kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/CommandServiceTest.java 2011-05-06 16:16:07 UTC (rev 4347)
@@ -47,7 +47,7 @@
public void setUp() throws Exception
{
- StandaloneContainer.setConfigurationPath("src/java/conf/standalone/test-configuration.xml");
+ StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-configuration.xml");
container = StandaloneContainer.getInstance();
}
Modified: kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/MultiConfigServiceTest.java
===================================================================
--- kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/MultiConfigServiceTest.java 2011-05-05 18:56:45 UTC (rev 4346)
+++ kernel/trunk/exo.kernel.component.command/src/test/java/org/exoplatform/services/command/MultiConfigServiceTest.java 2011-05-06 16:16:07 UTC (rev 4347)
@@ -50,7 +50,7 @@
public void setUp() throws Exception
{
- StandaloneContainer.setConfigurationPath("src/java/conf/standalone/test-multi-configuration.xml");
+ StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-multi-configuration.xml");
container = StandaloneContainer.getInstance();
}
13 years
exo-jcr SVN: r4346 - in kernel/trunk/exo.kernel.container/src: test/java/org/exoplatform/container and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-05-05 14:56:45 -0400 (Thu, 05 May 2011)
New Revision: 4346
Modified:
kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/ExoContainer.java
kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/TestExoContainer.java
Log:
EXOJCR-1333: Provide a hasProfile method on ExoContainer
Modified: kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/ExoContainer.java
===================================================================
--- kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/ExoContainer.java 2011-05-05 12:14:47 UTC (rev 4345)
+++ kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/ExoContainer.java 2011-05-05 18:56:45 UTC (rev 4346)
@@ -55,7 +55,17 @@
private static final long serialVersionUID = -8068506531004854036L;
/**
- * Returns an unmodifable set of profiles defined by the value returned by invoking
+ * The current list of profiles
+ */
+ private static volatile String PROFILES;
+
+ /**
+ * The current set of profiles
+ */
+ private static Set<String> SET_PROFILES = Collections.unmodifiableSet(new HashSet<String>());
+
+ /**
+ * Returns an unmodifiable set of profiles defined by the value returned by invoking
* {@link PropertyManager#getProperty(String)} with the {@link org.exoplatform.commons.utils.PropertyManager#RUNTIME_PROFILES}
* property.
*
@@ -63,11 +73,40 @@
*/
public static Set<String> getProfiles()
{
- //
+ String profiles = PropertyManager.getProperty(PropertyManager.RUNTIME_PROFILES);
+ if ((profiles == null && PROFILES != null) || (profiles != null && !profiles.equals(PROFILES)))
+ {
+ synchronized (ExoContainer.class)
+ {
+ if ((profiles == null && PROFILES != null) || (profiles != null && !profiles.equals(PROFILES)))
+ {
+ SET_PROFILES = getProfiles(profiles);
+ PROFILES = profiles;
+ }
+ }
+ }
+
+ return SET_PROFILES;
+ }
+
+ /**
+ * Indicates whether or not a given profile exists
+ * @param profileName the name of the profile to check
+ * @return <code>true</code> if the profile exists, <code>false</code> otherwise.
+ */
+ public static boolean hasProfile(String profileName)
+ {
+ return getProfiles().contains(profileName);
+ }
+
+ /**
+ * Convert the list of profiles into a Set of String
+ */
+ private static Set<String> getProfiles(String profileList)
+ {
Set<String> profiles = new HashSet<String>();
// Obtain profile list by runtime properties
- String profileList = PropertyManager.getProperty(PropertyManager.RUNTIME_PROFILES);
if (profileList != null)
{
for (String profile : profileList.split(","))
@@ -77,9 +116,9 @@
}
//
- return Collections.unmodifiableSet(profiles);
+ return Collections.unmodifiableSet(profiles);
}
-
+
static Log log = ExoLogger.getLogger("exo.kernel.container.ExoContainer");
private Map<String, ComponentLifecyclePlugin> componentLifecylePlugin_ =
Modified: kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/TestExoContainer.java
===================================================================
--- kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/TestExoContainer.java 2011-05-05 12:14:47 UTC (rev 4345)
+++ kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/TestExoContainer.java 2011-05-05 18:56:45 UTC (rev 4346)
@@ -16,6 +16,7 @@
*/
package org.exoplatform.container;
+import org.exoplatform.commons.utils.PropertyManager;
import org.exoplatform.container.component.BaseComponentPlugin;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.container.jmx.AbstractTestContainer;
@@ -58,6 +59,55 @@
}
}
+ public void testHasProfile()
+ {
+ String oldValue = PropertyManager.getProperty(PropertyManager.RUNTIME_PROFILES);
+ try
+ {
+ System.clearProperty(PropertyManager.RUNTIME_PROFILES);
+ PropertyManager.refresh();
+ assertFalse(ExoContainer.hasProfile(null));
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, "foo1");
+ assertFalse(ExoContainer.hasProfile(null));
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ assertTrue(ExoContainer.hasProfile("foo1"));
+ System.clearProperty(PropertyManager.RUNTIME_PROFILES);
+ PropertyManager.refresh();
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, "foo1, foo2, foo3");
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ assertTrue(ExoContainer.hasProfile("foo1"));
+ assertTrue(ExoContainer.hasProfile("foo2"));
+ assertTrue(ExoContainer.hasProfile("foo3"));
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, " \tfoo ");
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ assertTrue(ExoContainer.hasProfile("foo"));
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, ",foo ");
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ assertTrue(ExoContainer.hasProfile("foo"));
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, "foo, bar, \t baz \t");
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ assertTrue(ExoContainer.hasProfile("baz"));
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, "foo1, bar, \t baz1 \t");
+ assertFalse(ExoContainer.hasProfile("foo0"));
+ assertFalse(ExoContainer.hasProfile("baz"));
+ assertTrue(ExoContainer.hasProfile("bar"));
+ }
+ finally
+ {
+ if (oldValue == null)
+ {
+ System.clearProperty(PropertyManager.RUNTIME_PROFILES);
+ PropertyManager.refresh();
+ }
+ else
+ {
+ PropertyManager.setProperty(PropertyManager.RUNTIME_PROFILES, oldValue);
+ }
+ }
+ }
+
public void testRemoveComponent() throws Exception
{
RootContainer container = RootContainer.getInstance();
13 years
exo-jcr SVN: r4345 - in ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext: management and 1 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-05-05 08:14:47 -0400 (Thu, 05 May 2011)
New Revision: 4345
Added:
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ResourceKey.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResource.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethod.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethodParameter.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceProperty.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ValueWrapper.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/GetterInvoker.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/MethodInvoker.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/NoSuchMethodInvoker.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SetterInvoker.java
ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SimpleMethodInvoker.java
Log:
EXOJCR-769 : The annotation processor of RESTEndPoint was ported in WS ( ws.rest.ext ).
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ResourceKey.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ResourceKey.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ResourceKey.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 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.management;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public final class ResourceKey
+{
+
+ /** . */
+ private final String name;
+
+ public ResourceKey(String name)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException();
+ }
+ this.name = name;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj instanceof ResourceKey)
+ {
+ ResourceKey that = (ResourceKey)obj;
+ return name.equals(that.name);
+ }
+ return false;
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResource.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResource.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResource.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2009 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.management;
+
+import org.exoplatform.management.annotations.ImpactType;
+import org.exoplatform.management.spi.ManagedMethodMetaData;
+import org.exoplatform.management.spi.ManagedPropertyMetaData;
+import org.exoplatform.management.spi.ManagedResource;
+import org.exoplatform.management.spi.ManagedTypeMetaData;
+import org.exoplatform.services.rest.ext.management.invocation.MethodInvoker;
+import org.exoplatform.services.rest.impl.ApplicationContextImpl;
+import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
+
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.MessageBodyReader;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class RestResource
+{
+
+ /** . */
+ final Map<String, RestResourceProperty> properties;
+
+ /** . */
+ private final List<RestResourceMethod> methods;
+
+ /** . */
+ private final ManagedResource managedResource;
+
+ /** . */
+ private final String name;
+
+ /** . */
+ private final String description;
+
+ public RestResource(String name, ManagedResource managedResource)
+ {
+ ManagedTypeMetaData managedType = managedResource.getMetaData();
+
+ //
+ HashMap<String, RestResourceProperty> properties = new HashMap<String, RestResourceProperty>();
+ for (ManagedPropertyMetaData managedProperty : managedType.getProperties()) {
+ RestResourceProperty resourceProperty = new RestResourceProperty(managedProperty);
+ properties.put(resourceProperty.getName(), resourceProperty);
+ }
+
+ //
+ List<RestResourceMethod> methods = new ArrayList<RestResourceMethod>();
+ for (ManagedMethodMetaData managedMethod : managedType.getMethods()) {
+ RestResourceMethod resourceMethod = new RestResourceMethod(managedMethod);
+ methods.add(resourceMethod);
+ }
+
+ //
+ this.name = name;
+ this.description = managedType.getDescription();
+ this.managedResource = managedResource;
+ this.properties = Collections.unmodifiableMap(properties);
+ this.methods = methods;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public Collection<RestResourceProperty> getProperties()
+ {
+ return properties.values();
+ }
+
+ public Collection<RestResourceMethod> getMethods()
+ {
+ return methods;
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public RestResource get()
+ {
+ return this;
+ }
+
+ @GET
+ @Path("{name}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Object get(@Context UriInfo info, @PathParam("name") String name)
+ {
+ MultivaluedMap<String, String> parameters = info.getQueryParameters();
+
+ // Try first to get a property
+ RestResourceProperty property = properties.get(name);
+ if (property != null)
+ {
+ MethodInvoker getter = property.getGetterInvoker();
+ if (getter != null)
+ {
+ return safeInvoke(getter, parameters);
+ }
+ }
+
+ //
+ return tryInvoke(name, parameters, ImpactType.READ);
+ }
+
+ @PUT
+ @Path("{name}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Object put(@Context UriInfo info, @PathParam("name") String name)
+ {
+ MultivaluedMap<String, String> parameters = getParameters(info);
+ // Try first to get a property
+ RestResourceProperty property = properties.get(name);
+ if (property != null)
+ {
+ MethodInvoker setter = property.getSetterInvoker();
+ if (setter != null)
+ {
+ return safeInvoke(setter, parameters);
+ }
+ }
+
+ //
+ return tryInvoke(name, parameters, ImpactType.IDEMPOTENT_WRITE);
+ }
+
+ @POST
+ @Path("{name}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Object post(@Context UriInfo info, @PathParam("name") String name)
+ {
+ return tryInvoke(name, getParameters(info), ImpactType.WRITE);
+ }
+
+ /**
+ * Try to invoke a method with matching parameters from the query string
+ *
+ * @param methodName the method name to invoke
+ * @param info the uri info
+ * @param impact the expected impact
+ * @return a suitable response
+ */
+ private Object tryInvoke(String methodName, MultivaluedMap<String, String> parameters, ImpactType impact)
+ {
+ //
+ RestResourceMethod method = lookupMethod(methodName, parameters.keySet(), impact);
+
+ //
+ if (method != null)
+ {
+ MethodInvoker invoker = method.getMethodInvoker();
+ return safeInvoke(invoker, parameters);
+ }
+
+ //
+ return null;
+ }
+
+ private RestResourceMethod lookupMethod(String methodName, Set<String> argNames, ImpactType impact)
+ {
+ for (RestResourceMethod method : methods)
+ {
+ if (method.getName().equals(methodName) && method.metaData.getImpact() == impact && method.parameterNames.equals(argNames))
+ {
+ return method;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Invoke safely a method.
+ *
+ * @param invoker the method to invoke
+ * @param argMap the arguments
+ * @return the ok response or an object returned by the method wrapped by {@link ValueWrapper}
+ */
+ private Object safeInvoke(MethodInvoker invoker, Map<String, List<String>> argMap)
+ {
+ Object resource = managedResource.getResource();
+
+ //
+ managedResource.beforeInvoke(resource);
+
+ //
+ try
+ {
+ Object ret = invoker.invoke(resource, argMap);
+ return ret == null ? Response.ok() : ValueWrapper.wrap(ret);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ return Response.serverError();
+ }
+ finally
+ {
+ managedResource.afterInvoke(resource);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private MultivaluedMap<String, String> getParameters(UriInfo info)
+ {
+ MultivaluedMap<String, String> parameters = info.getQueryParameters();
+ ApplicationContextImpl context = (ApplicationContextImpl)info;
+
+ Type formType = (ParameterizedType)MultivaluedMapImpl.class.getGenericInterfaces()[0];
+ MediaType contentType = context.getHttpHeaders().getMediaType();
+ if (contentType == null) {
+ contentType = MediaType.APPLICATION_FORM_URLENCODED_TYPE;
+ }
+
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ try {
+ MessageBodyReader reader =
+ context.getProviders().getMessageBodyReader(MultivaluedMap.class, formType, null, contentType);
+ if (reader != null) {
+ form = (MultivaluedMap<String, String>)reader.readFrom(MultivaluedMap.class, formType, null, contentType, context
+ .getHttpHeaders().getRequestHeaders(), context.getContainerRequest().getEntityStream());
+ }
+ } catch (Exception e) {
+ }
+
+ parameters.putAll(form);
+ return parameters;
+ }
+
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethod.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethod.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethod.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 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.management;
+
+import org.exoplatform.management.spi.ManagedMethodMetaData;
+import org.exoplatform.management.spi.ManagedMethodParameterMetaData;
+import org.exoplatform.services.rest.ext.management.invocation.MethodInvoker;
+import org.exoplatform.services.rest.ext.management.invocation.SimpleMethodInvoker;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class RestResourceMethod
+{
+
+ /** . */
+ final ManagedMethodMetaData metaData;
+
+ /** . */
+ final List<RestResourceMethodParameter> parameters;
+
+ /** . */
+ final Set<String> parameterNames;
+
+ /** . */
+ final MethodInvoker methodInvoker;
+
+ public RestResourceMethod(ManagedMethodMetaData metaData)
+ {
+ List<RestResourceMethodParameter> parameters = new ArrayList<RestResourceMethodParameter>();
+ Set<String> parameterNames = new HashSet<String>();
+ for (ManagedMethodParameterMetaData parameterMD : metaData.getParameters())
+ {
+ parameters.add(new RestResourceMethodParameter(parameterMD));
+ parameterNames.add(parameterMD.getName());
+ }
+
+ //
+ this.metaData = metaData;
+ this.parameterNames = Collections.unmodifiableSet(parameterNames);
+ this.parameters = Collections.unmodifiableList(parameters);
+ this.methodInvoker = new SimpleMethodInvoker(metaData.getMethod())
+ {
+ @Override
+ protected String getArgumentName(int index)
+ {
+ RestResourceMethodParameter param = RestResourceMethod.this.parameters.get(index);
+ return param != null ? param.getName() : null;
+ }
+ };
+ }
+
+ public String getName()
+ {
+ return metaData.getName();
+ }
+
+ public String getMethod()
+ {
+ switch (metaData.getImpact())
+ {
+ case READ:
+ return "get";
+ case WRITE:
+ return "post";
+ case IDEMPOTENT_WRITE:
+ return "put";
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ public String getDescription()
+ {
+ return metaData.getDescription();
+ }
+
+ public List<RestResourceMethodParameter> getParameters()
+ {
+ return parameters;
+ }
+
+ // Internal *********************************************************************************************************
+
+ MethodInvoker getMethodInvoker()
+ {
+ return methodInvoker;
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethodParameter.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethodParameter.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceMethodParameter.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 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.management;
+
+import org.exoplatform.management.spi.ManagedMethodParameterMetaData;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class RestResourceMethodParameter
+{
+
+ /** . */
+ final ManagedMethodParameterMetaData metaData;
+
+ public RestResourceMethodParameter(ManagedMethodParameterMetaData metaData)
+ {
+ this.metaData = metaData;
+ }
+
+ public String getName()
+ {
+ return metaData.getName();
+ }
+
+ public String getDescription()
+ {
+ return metaData.getDescription();
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceProperty.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceProperty.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/RestResourceProperty.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 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.management;
+
+import org.exoplatform.management.spi.ManagedPropertyMetaData;
+import org.exoplatform.services.rest.ext.management.invocation.GetterInvoker;
+import org.exoplatform.services.rest.ext.management.invocation.MethodInvoker;
+import org.exoplatform.services.rest.ext.management.invocation.NoSuchMethodInvoker;
+import org.exoplatform.services.rest.ext.management.invocation.SetterInvoker;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class RestResourceProperty
+{
+
+ /** . */
+ final ManagedPropertyMetaData metaData;
+
+ /** . */
+ private final MethodInvoker setterInvoker;
+
+ /** . */
+ private final MethodInvoker getterInvoker;
+
+ public RestResourceProperty(ManagedPropertyMetaData metaData)
+ {
+ Method getter = metaData.getGetter();
+ MethodInvoker getterInvoker = getter != null ? new GetterInvoker(getter) : new NoSuchMethodInvoker();
+
+ //
+ Method setter = metaData.getSetter();
+ MethodInvoker setterInvoker = setter != null ? new SetterInvoker(setter) : new NoSuchMethodInvoker();
+
+ //
+ this.metaData = metaData;
+ this.setterInvoker = setterInvoker;
+ this.getterInvoker = getterInvoker;
+ }
+
+ public String getName()
+ {
+ return metaData.getName();
+ }
+
+ public String getDescription()
+ {
+ return metaData.getDescription();
+ }
+
+ // Internal *********************************************************************************************************
+
+ MethodInvoker getSetterInvoker()
+ {
+ return setterInvoker;
+ }
+
+ MethodInvoker getGetterInvoker()
+ {
+ return getterInvoker;
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ValueWrapper.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ValueWrapper.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/ValueWrapper.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 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.management;
+
+/**
+ * Temporary class until eXo JSON marshaller supports non java bean objects.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ValueWrapper<T>
+{
+
+ public static <T> ValueWrapper<T> wrap(T value)
+ {
+ return new ValueWrapper<T>(value);
+ }
+
+ /** . */
+ private final T value;
+
+ public ValueWrapper(T value)
+ {
+ this.value = value;
+ }
+
+ public T getValue()
+ {
+ return value;
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/GetterInvoker.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/GetterInvoker.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/GetterInvoker.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 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.management.invocation;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class GetterInvoker extends SimpleMethodInvoker
+{
+
+ public GetterInvoker(Method method)
+ {
+ super(method);
+ }
+
+ @Override
+ protected String getArgumentName(int index)
+ {
+ throw new IndexOutOfBoundsException();
+ }
+}
\ No newline at end of file
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/MethodInvoker.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/MethodInvoker.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/MethodInvoker.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 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.management.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface MethodInvoker
+{
+
+ Object invoke(Object o, Map<String, List<String>> argMap) throws IllegalAccessException, InvocationTargetException;
+
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/NoSuchMethodInvoker.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/NoSuchMethodInvoker.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/NoSuchMethodInvoker.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 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.management.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class NoSuchMethodInvoker implements MethodInvoker
+{
+ public Object invoke(Object o, Map<String, List<String>> argMap) throws IllegalAccessException, InvocationTargetException
+ {
+ throw new UnsupportedOperationException();
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SetterInvoker.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SetterInvoker.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SetterInvoker.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 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.management.invocation;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class SetterInvoker extends SimpleMethodInvoker
+{
+
+ public SetterInvoker(Method method)
+ {
+ super(method);
+ }
+
+ @Override
+ protected String getArgumentName(int index)
+ {
+ if (index == 0)
+ {
+ return "value";
+ }
+ else
+ {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+}
Added: ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SimpleMethodInvoker.java
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SimpleMethodInvoker.java (rev 0)
+++ ws/trunk/exo.ws.rest.ext/src/main/java/org/exoplatform/services/rest/ext/management/invocation/SimpleMethodInvoker.java 2011-05-05 12:14:47 UTC (rev 4345)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 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.management.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class SimpleMethodInvoker implements MethodInvoker
+{
+
+ /** The method we invoke. */
+ private final Method method;
+
+ public SimpleMethodInvoker(Method method)
+ {
+ if (method == null)
+ {
+ throw new NullPointerException();
+ }
+
+ //
+ this.method = method;
+ }
+
+ public Object invoke(Object o, Map<String, List<String>> argMap) throws IllegalAccessException, InvocationTargetException
+ {
+ Class[] paramTypes = method.getParameterTypes();
+ Object[] args = new Object[paramTypes.length];
+ for (int i = 0;i < paramTypes.length;i++)
+ {
+ String argName = getArgumentName(i);
+ List<String> argValues = argMap.get(argName);
+ Class paramType = paramTypes[i];
+ Object arg;
+ if (paramType.isPrimitive())
+ {
+ throw new UnsupportedOperationException("Todo " + paramType);
+ }
+ else if (paramType.isArray())
+ {
+ throw new UnsupportedOperationException("Todo " + paramType);
+ }
+ else if (paramType == String.class)
+ {
+ arg = (argValues != null && argValues.size() > 0) ? argValues.get(0) : null;
+ }
+ else
+ {
+ throw new UnsupportedOperationException("Todo " + paramType);
+ }
+ args[i] = arg;
+ }
+
+ //
+ return method.invoke(o, args);
+ }
+
+ protected abstract String getArgumentName(int index);
+}
\ No newline at end of file
13 years
exo-jcr SVN: r4344 - in jcr/trunk: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene and 2 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-05-05 05:32:16 -0400 (Thu, 05 May 2011)
New Revision: 4344
Modified:
jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java
jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/ClientTransportImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RedoLog.java
jcr/trunk/exo.jcr.framework.ftpclient/src/main/java/org/exoplatform/frameworks/ftpclient/Log.java
jcr/trunk/exo.jcr.framework.web/src/main/java/org/exoplatform/frameworks/jcr/web/DisplayJCRContentServlet.java
Log:
EXOJCR-1221 : The same violations was fixed in JCR.
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java 2011-05-05 08:38:08 UTC (rev 4343)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/BackupConsole.java 2011-05-05 09:32:16 UTC (rev 4344)
@@ -25,6 +25,7 @@
import java.net.URL;
import java.util.HashMap;
+
/**
* Created by The eXo Platform SAS. <br/>Date:
*
@@ -109,14 +110,14 @@
int curArg = 0;
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no any parameters.");
+ System.out.println(INCORRECT_PARAM + "There is no any parameters."); //NOSONAR
return;
}
// help
if (args[curArg].equalsIgnoreCase("help"))
{
- System.out.println(HELP_INFO);
+ System.out.println(HELP_INFO); //NOSONAR
return;
}
@@ -130,7 +131,7 @@
}
catch (MalformedURLException e)
{
- System.out.println(INCORRECT_PARAM + "There is no url parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no url parameter."); //NOSONAR
return;
}
@@ -149,7 +150,10 @@
if (url.getUserInfo() != null)
{
- System.out.println(INCORRECT_PARAM + "Parameters Login:Password should not be specified in url parameter to form authentication - " + sUrl);
+ System.out
+ .println(INCORRECT_PARAM
+ + "Parameters Login:Password should not be specified in url parameter to form authentication - "
+ + sUrl); //NOSONAR
return;
}
}
@@ -164,28 +168,30 @@
//check POST or GET
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "No specified POST or GET parameter to form parameter.");
+ System.out.println(INCORRECT_PARAM + "No specified POST or GET parameter to form parameter."); //NOSONAR
return;
}
String method = args[curArg++];
if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("POST"))
{
- System.out.println(INCORRECT_PARAM + "Method to form authentication shulde be GET or POST to form parameter - " + method);
+ System.out.println(INCORRECT_PARAM
+ + "Method to form authentication shulde be GET or POST to form parameter - " + method); //NOSONAR
return;
}
//url to form authentication
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "No specified url and form properties to form parameter.");
+ System.out.println(INCORRECT_PARAM + "No specified url and form properties to form parameter."); //NOSONAR
return;
}
String[] params = args[curArg++].split("[?]");
if (params.length != 2)
{
- System.out.println(INCORRECT_PARAM + "From parameters is not spacified to form parameter - " + args[curArg]);
+ System.out
+ .println(INCORRECT_PARAM + "From parameters is not spacified to form parameter - " + args[curArg]); //NOSONAR
return;
}
String formUrl = params[0];
@@ -195,9 +201,9 @@
if (formParams.length < 2)
{
- System.out.println(INCORRECT_PARAM
- + "From parameters shoulde be conatains at least two (for login and for pasword) parameters - "
- + params[1]);
+ System.out.println(INCORRECT_PARAM //NOSONAR
+ + "From parameters shoulde be conatains at least two (for login and for pasword) parameters - " //NOSONAR
+ + params[1]); //NOSONAR
return;
}
@@ -209,7 +215,8 @@
if (para.length != 2)
{
- System.out.println(INCORRECT_PARAM + "From parameters is incorect, shoulde be as \"name=value\" - " + fParam);
+ System.out.println(INCORRECT_PARAM + "From parameters is incorect, shoulde be as \"name=value\" - "
+ + fParam); //NOSONAR
return;
}
@@ -222,12 +229,12 @@
{
if (login == null)
{
- System.out.println(INCORRECT_PARAM + "There is no specific Login:Password in url parameter - " + sUrl);
+ System.out.println(INCORRECT_PARAM + "There is no specific Login:Password in url parameter - " + sUrl); //NOSONAR
return;
}
else if (!login.matches("[^:]+:[^:]+"))
{
- System.out.println(INCORRECT_PARAM + "There is incorrect Login:Password parameter - " + login);
+ System.out.println(INCORRECT_PARAM + "There is incorrect Login:Password parameter - " + login); //NOSONAR
return;
}
}
@@ -253,7 +260,7 @@
// commands
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no command parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no command parameter."); //NOSONAR
return;
}
String command = args[curArg++];
@@ -289,7 +296,7 @@
if (curArg == args.length)
{
- System.out.println(client.startBackUp(repositoryName, workspaceName, backupDir));
+ System.out.println(client.startBackUp(repositoryName, workspaceName, backupDir)); //NOSONAR
}
else
{
@@ -302,40 +309,40 @@
}
catch (NumberFormatException e)
{
- System.out.println(INCORRECT_PARAM + "Incemental job period is not didgit - " + e.getMessage());
+ System.out.println(INCORRECT_PARAM + "Incemental job period is not didgit - " + e.getMessage()); //NOSONAR
return;
}
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.startIncrementalBackUp(repositoryName, workspaceName, backupDir, inc));
+ System.out.println(client.startIncrementalBackUp(repositoryName, workspaceName, backupDir, inc)); //NOSONAR
}
}
else if (command.equalsIgnoreCase("stop"))
{
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no backup identifier parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no backup identifier parameter."); //NOSONAR
return;
}
String backupId = args[curArg++];
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.stop(backupId));
+ System.out.println(client.stop(backupId)); //NOSONAR
}
else if (command.equalsIgnoreCase("drop"))
{
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no path to workspace or force-session-close parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no path to workspace or force-session-close parameter."); //NOSONAR
return;
}
@@ -358,16 +365,16 @@
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.drop(isForce, repositoryName, workspaceName));
+ System.out.println(client.drop(isForce, repositoryName, workspaceName)); //NOSONAR
}
else if (command.equalsIgnoreCase("status"))
{
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no backup identifier parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no backup identifier parameter."); //NOSONAR
return;
}
@@ -375,19 +382,19 @@
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.status(backupId));
+ System.out.println(client.status(backupId)); //NOSONAR
}
else if (command.equalsIgnoreCase("info"))
{
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.info());
+ System.out.println(client.info()); //NOSONAR
}
else if (command.equalsIgnoreCase("restores"))
{
@@ -401,17 +408,17 @@
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.restores(repositoryName, workspaceName));
+ System.out.println(client.restores(repositoryName, workspaceName)); //NOSONAR
}
else if (command.equalsIgnoreCase("list"))
{
if (curArg == args.length)
{
- System.out.println(client.list());
+ System.out.println(client.list()); //NOSONAR
}
else
{
@@ -421,14 +428,14 @@
{
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
- System.out.println(client.listCompleted());
+ System.out.println(client.listCompleted()); //NOSONAR
}
else
{
- System.out.println(INCORRECT_PARAM + "There is no 'completed' parameter - " + complated);
+ System.out.println(INCORRECT_PARAM + "There is no 'completed' parameter - " + complated); //NOSONAR
return;
}
}
@@ -469,7 +476,7 @@
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "Should be more parameters.");
+ System.out.println(INCORRECT_PARAM + "Should be more parameters."); //NOSONAR
return;
}
}
@@ -487,14 +494,14 @@
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
//5. restore remove-exists <backup_id>
//11. restore <backup_id>
- System.out.println(client.restore(repositoryName, workspaceName, backupId, null,
- backupSetPath, removeExists));
+ System.out.println(client.restore(repositoryName, workspaceName, backupId, null, backupSetPath,
+ removeExists)); //NOSONAR
return;
}
//check /repo/ws or /repo
@@ -514,21 +521,21 @@
if (curArg < args.length)
{
- System.out.println(INCORRECT_PARAM + "Should be less parameters : " + parameter);
+ System.out.println(INCORRECT_PARAM + "Should be less parameters : " + parameter); //NOSONAR
return;
}
//6. restore remove-exists <backup_set_path>
//12. restore <backup_set_path>
System.out.println(client.restore(repositoryName, workspaceName, backupId, null, backupSetPath,
- removeExists));
+ removeExists)); //NOSONAR
return;
}
// check backup_id or backup_set_path
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no backup identifier or backup set path parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no backup identifier or backup set path parameter."); //NOSONAR
return;
}
parameter = args[curArg++];
@@ -544,7 +551,7 @@
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no path to config file parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no path to config file parameter."); //NOSONAR
return;
}
String pathToConf = args[curArg++];
@@ -552,13 +559,13 @@
File conf = new File(pathToConf);
if (!conf.exists())
{
- System.out.println(" File " + pathToConf + " do not exist. Check the path.");
+ System.out.println(" File " + pathToConf + " do not exist. Check the path."); //NOSONAR
return;
}
if (curArg < args.length)
{
- System.out.println(TOO_MANY_PARAMS);
+ System.out.println(TOO_MANY_PARAMS); //NOSONAR
return;
}
@@ -572,23 +579,23 @@
9. restore <repo/ws> <backup_set_path> <pathToConfigFile>
10. restore <repo> <backup_set_path> <pathToConfigFile>
*/
- System.out.println(client.restore(repositoryName, workspaceName, backupId, new FileInputStream(conf),
+ System.out.println(client.restore(repositoryName, workspaceName, backupId, new FileInputStream(conf), //NOSONAR
backupSetPath, removeExists));
}
else
{
- System.out.println("Unknown command <" + command + ">");
+ System.out.println("Unknown command <" + command + ">"); //NOSONAR
}
}
catch (IOException e)
{
- System.out.println("ERROR: " + e.getMessage());
+ System.out.println("ERROR: " + e.getMessage()); //NOSONAR
e.printStackTrace();
}
catch (BackupExecuteException e)
{
- System.out.println("ERROR: " + e.getMessage());
+ System.out.println("ERROR: " + e.getMessage()); //NOSONAR
e.printStackTrace();
}
@@ -669,7 +676,7 @@
{
if (curArg == args.length)
{
- System.out.println(INCORRECT_PARAM + "There is no path to workspace parameter.");
+ System.out.println(INCORRECT_PARAM + "There is no path to workspace parameter."); //NOSONAR
return null;
}
// make correct path
@@ -678,7 +685,7 @@
if ( !repWS.matches("[/][^/]+") && !repWS.matches("[/][^/]+[/][^/]+"))
{
- System.out.println(INCORRECT_PARAM + "There is incorrect path to workspace parameter: " + repWS);
+ System.out.println(INCORRECT_PARAM + "There is incorrect path to workspace parameter: " + repWS); //NOSONAR
return null;
}
else
Modified: jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/ClientTransportImpl.java
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/ClientTransportImpl.java 2011-05-05 08:38:08 UTC (rev 4343)
+++ jcr/trunk/applications/exo.jcr.applications.backupconsole/src/main/java/org/exoplatform/jcr/backupconsole/ClientTransportImpl.java 2011-05-05 09:32:16 UTC (rev 4344)
@@ -182,7 +182,7 @@
if (Response.Status.OK.getStatusCode() != respLogin.getStatusCode())
{
- System.out.println("Form authentication is fail, status code : " + respLogin.getStatusCode());
+ System.out.println("Form authentication is fail, status code : " + respLogin.getStatusCode()); //NOSONAR
System.exit(0);
}
}
@@ -268,7 +268,7 @@
if (Response.Status.OK.getStatusCode() != respLogin.getStatusCode())
{
- System.out.println("Form authentication is fail, status code : " + respLogin.getStatusCode());
+ System.out.println("Form authentication is fail, status code : " + respLogin.getStatusCode()); //NOSONAR
System.exit(0);
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RedoLog.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RedoLog.java 2011-05-05 08:38:08 UTC (rev 4343)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/RedoLog.java 2011-05-05 09:32:16 UTC (rev 4344)
@@ -199,7 +199,7 @@
}
catch (Exception e)
{
- e.printStackTrace();
+ log.error(e.getLocalizedMessage(), e);
throw e;
}
entryCount = 0;
Modified: jcr/trunk/exo.jcr.framework.ftpclient/src/main/java/org/exoplatform/frameworks/ftpclient/Log.java
===================================================================
--- jcr/trunk/exo.jcr.framework.ftpclient/src/main/java/org/exoplatform/frameworks/ftpclient/Log.java 2011-05-05 08:38:08 UTC (rev 4343)
+++ jcr/trunk/exo.jcr.framework.ftpclient/src/main/java/org/exoplatform/frameworks/ftpclient/Log.java 2011-05-05 09:32:16 UTC (rev 4344)
@@ -36,12 +36,12 @@
public void info(String message)
{
- System.out.println(moduleName + ":" + message);
+ System.out.println(moduleName + ":" + message); //NOSONAR
}
public void info(String message, Throwable thr)
{
- System.out.println(moduleName + ":" + message);
+ System.out.println(moduleName + ":" + message); //NOSONAR
thr.printStackTrace(System.out);
}
Modified: jcr/trunk/exo.jcr.framework.web/src/main/java/org/exoplatform/frameworks/jcr/web/DisplayJCRContentServlet.java
===================================================================
--- jcr/trunk/exo.jcr.framework.web/src/main/java/org/exoplatform/frameworks/jcr/web/DisplayJCRContentServlet.java 2011-05-05 08:38:08 UTC (rev 4343)
+++ jcr/trunk/exo.jcr.framework.web/src/main/java/org/exoplatform/frameworks/jcr/web/DisplayJCRContentServlet.java 2011-05-05 09:32:16 UTC (rev 4344)
@@ -127,7 +127,7 @@
}
catch (Exception e)
{
- e.printStackTrace();
+ e.printStackTrace(); //NOSONAR
throw new ServletException(e);
}
}
13 years