SLING-6723 : Make dependency to javax.jcr, jcr.contentloader and jcr.api optional
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1789343 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java b/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
index e837d20..2b65cbf 100644
--- a/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
+++ b/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
@@ -320,13 +320,13 @@
* not set or set to any other value.
*/
public static final String RP_STATUS = RP_PREFIX + "status";
-
+
/**
- * Optional request parameter: defines if to enable the error handling
- * also for POST request.
+ * Optional request parameter: defines if to enable the error handling
+ * also for POST request.
* The parameter value is checked to see if it matches the case-insensitive
- * value true.
- *
+ * value true.
+ *
* @since 2.2.0 (Bundle version 2.3.0)
*/
public static final String RP_SEND_ERROR = RP_PREFIX + "sendError";
@@ -508,15 +508,15 @@
/**
* Name of the request parameter indicating whether versionable nodes should
* be checked in during an {@link SlingPostConstants#OPERATION_IMPORT} operation.
- *
+ *
* @since 2.1.2
*/
public static final String RP_AUTO_CHECKOUT = RP_PREFIX + "autoCheckout";
/**
* Name of the request attribute (not parameter) indicating that a post operation
- * should not invoke session.save() upon completion.
- *
+ * should not invoke the commit method on the resource resolver upon completion.
+ *
* @since 2.1.2
*/
public static final String ATTR_SKIP_SESSION_HANDLING = "skip-session-handling";
@@ -582,7 +582,7 @@
* @since 2.3.4
*/
public static final String NT_SLING_CHUNK_OFFSET = "sling:offset";
-
+
/**
* Constant for prefix for sling:chunk node name.
* @since 2.3.4
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
index e39d4f1..4f80685 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
@@ -19,13 +19,13 @@
import java.util.Iterator;
import java.util.List;
-import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.servlets.post.Modification;
@@ -44,107 +44,106 @@
protected final void doRun(SlingHttpServletRequest request,
PostResponse response,
List<Modification> changes)
- throws RepositoryException {
- Session session = request.getResourceResolver().adaptTo(Session.class);
+ throws PersistenceException {
+ try {
+ Session session = request.getResourceResolver().adaptTo(Session.class);
- VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
+ VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
- Resource resource = request.getResource();
- String source = resource.getPath();
+ Resource resource = request.getResource();
+ String source = resource.getPath();
- // ensure dest is not empty/null and is absolute
- String dest = request.getParameter(SlingPostConstants.RP_DEST);
- if (dest == null || dest.length() == 0) {
- throw new IllegalArgumentException("Unable to process "
- + getOperationName() + ". Missing destination");
- }
-
- // register whether the path ends with a trailing slash
- boolean trailingSlash = dest.endsWith("/");
-
- // ensure destination is an absolute and normalized path
- if (!dest.startsWith("/")) {
- dest = ResourceUtil.getParent(source) + "/" + dest;
- }
- dest = ResourceUtil.normalize(dest);
-
- // destination parent and name
- String dstParent = trailingSlash ? dest : ResourceUtil.getParent(dest);
-
- // delete destination if already exists
- if (!trailingSlash && session.itemExists(dest)) {
-
- final String replaceString = request.getParameter(SlingPostConstants.RP_REPLACE);
- final boolean isReplace = "true".equalsIgnoreCase(replaceString);
- if (!isReplace) {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
- "Cannot " + getOperationName() + " " + resource + " to "
- + dest + ": destination exists");
- return;
- } else {
- checkoutIfNecessary(session.getItem(dest).getParent(), changes, versioningConfiguration);
+ // ensure dest is not empty/null and is absolute
+ String dest = request.getParameter(SlingPostConstants.RP_DEST);
+ if (dest == null || dest.length() == 0) {
+ throw new IllegalArgumentException("Unable to process "
+ + getOperationName() + ". Missing destination");
}
- } else {
+ // register whether the path ends with a trailing slash
+ boolean trailingSlash = dest.endsWith("/");
- // check if path to destination exists and create it, but only
- // if it's a descendant of the current node
- if (!dstParent.equals("")) {
- if (session.itemExists(dstParent)) {
- checkoutIfNecessary((Node) session.getItem(dstParent), changes, versioningConfiguration);
- } else {
+ // ensure destination is an absolute and normalized path
+ if (!dest.startsWith("/")) {
+ dest = ResourceUtil.getParent(source) + "/" + dest;
+ }
+ dest = ResourceUtil.normalize(dest);
+
+ // destination parent and name
+ String dstParent = trailingSlash ? dest : ResourceUtil.getParent(dest);
+
+ // delete destination if already exists
+ if (!trailingSlash && session.itemExists(dest)) {
+
+ final String replaceString = request.getParameter(SlingPostConstants.RP_REPLACE);
+ final boolean isReplace = "true".equalsIgnoreCase(replaceString);
+ if (!isReplace) {
response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
"Cannot " + getOperationName() + " " + resource + " to "
- + dest + ": parent of destination does not exist");
+ + dest + ": destination exists");
return;
+ } else {
+ checkoutIfNecessary(session.getItem(dest).getParent(), changes, versioningConfiguration);
}
+
+ } else {
+
+ // check if path to destination exists and create it, but only
+ // if it's a descendant of the current node
+ if (!dstParent.equals("")) {
+ if (session.itemExists(dstParent)) {
+ checkoutIfNecessary((Node) session.getItem(dstParent), changes, versioningConfiguration);
+ } else {
+ response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
+ "Cannot " + getOperationName() + " " + resource + " to "
+ + dest + ": parent of destination does not exist");
+ return;
+ }
+ }
+
+ // the destination is newly created, hence a create request
+ response.setCreateRequest(true);
}
- // the destination is newly created, hence a create request
- response.setCreateRequest(true);
- }
+ Iterator<Resource> resources = getApplyToResources(request);
+ Resource destResource = null;
+ if (resources == null) {
- Iterator<Resource> resources = getApplyToResources(request);
- Item destItem = null;
- if (resources == null) {
- // ensure we have an item underlying the request's resource
- Item item = resource.adaptTo(Item.class);
- if (item == null) {
+ String dstName = trailingSlash ? null : ResourceUtil.getName(dest);
+ destResource = execute(changes, resource, dstParent, dstName, versioningConfiguration);
+
+ } else {
+
+ // multiple applyTo requires trailing slash on destination
+ if (!trailingSlash) {
+ throw new IllegalArgumentException(
+ "Applying "
+ + getOperationName()
+ + " to multiple resources requires a trailing slash on the destination");
+ }
+
+ // multiple copy will never return 201/CREATED
+ response.setCreateRequest(false);
+
+ while (resources.hasNext()) {
+ Resource applyTo = resources.next();
+ execute(changes, applyTo, dstParent, null, versioningConfiguration);
+ }
+ destResource = request.getResourceResolver().getResource(dest);
+
+ }
+
+ if ( destResource == null ) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND,
- "Missing source " + resource + " for " + getOperationName());
+ "Missing source " + resource + " for " + getOperationName());
return;
}
-
- String dstName = trailingSlash ? null : ResourceUtil.getName(dest);
- destItem = execute(changes, item, dstParent, dstName, versioningConfiguration);
-
- } else {
-
- // multiple applyTo requires trailing slash on destination
- if (!trailingSlash) {
- throw new IllegalArgumentException(
- "Applying "
- + getOperationName()
- + " to multiple resources requires a trailing slash on the destination");
- }
-
- // multiple copy will never return 201/CREATED
- response.setCreateRequest(false);
-
- while (resources.hasNext()) {
- Resource applyTo = resources.next();
- Item item = applyTo.adaptTo(Item.class);
- if (item != null) {
- execute(changes, item, dstParent, null, versioningConfiguration);
- }
- }
- destItem = session.getItem(dest);
-
+ // finally apply the ordering parameter
+ this.jcrSsupport.orderNode(request, destResource, changes);
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException(re.getMessage(), re);
}
-
- // finally apply the ordering parameter
- orderNode(request, destItem, changes);
}
/**
@@ -162,11 +161,12 @@
* @param destName The name of the target item inside the
* <code>destParent</code>. If <code>null</code> the name of
* the <code>source</code> is used as the target item name.
- * @throws RepositoryException May be thrown if an error occurrs executing
+ * @throws RepositoryException May be thrown if an error occurs executing
* the operation.
*/
- protected abstract Item execute(List<Modification> changes, Item source,
- String destParent, String destName,
+ protected abstract Resource execute(List<Modification> changes, Resource source,
+ String destParent,
+ String destName,
VersioningConfiguration versioningConfiguration) throws RepositoryException;
}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java
index 6325b9a..9226778 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java
@@ -27,15 +27,13 @@
import java.util.NoSuchElementException;
import java.util.Set;
-import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
-import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
-import javax.jcr.Session;
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
@@ -53,19 +51,21 @@
* The <code>AbstractPostOperation</code> class is a base implementation of the
* {@link PostOperation} service interface providing actual implementations with
* useful tooling and common functionality like preparing the change logs or
- * saving or refreshing the JCR Session.
+ * saving or refreshing.
*/
public abstract class AbstractPostOperation implements PostOperation {
/**
- * default log
+ * Default logger
*/
protected final Logger log = LoggerFactory.getLogger(getClass());
+ protected final JCRSupport jcrSsupport = JCRSupport.INSTANCE;
+
/**
* Prepares and finalizes the actual operation. Preparation encompasses
* getting the absolute path of the item to operate on by calling the
- * {@link #getItemPath(SlingHttpServletRequest)} method and setting the
+ * {@link #getResourcePath(SlingHttpServletRequest)} method and setting the
* location and parent location on the response. After the operation has
* been done in the {@link #doRun(SlingHttpServletRequest, PostResponse, List)}
* method the session is saved if there are unsaved modifications. In case
@@ -80,13 +80,11 @@
public void run(final SlingHttpServletRequest request,
final PostResponse response,
final SlingPostProcessor[] processors) {
- final Session session = request.getResourceResolver().adaptTo(Session.class);
-
final VersioningConfiguration versionableConfiguration = getVersioningConfiguration(request);
try {
// calculate the paths
- String path = getItemPath(request);
+ String path = this.getResourcePath(request);
response.setPath(path);
// location
@@ -159,10 +157,12 @@
response.onChange("checkin", change.getSource());
nodesToCheckin.remove(change.getSource());
break;
+ case RESTORE : response.onChange("restore", change.getSource());
+ break;
}
}
- if (isSessionSaveRequired(session, request)) {
+ if (isResourceResolverCommitRequired(request)) {
request.getResourceResolver().commit();
}
@@ -181,16 +181,10 @@
response.setError(e);
} finally {
- try {
- if (isSessionSaveRequired(session, request)) {
- request.getResourceResolver().revert();
- }
- } catch (RepositoryException e) {
- log.warn("RepositoryException in finally block: {}",
- e.getMessage(), e);
+ if (isResourceResolverCommitRequired(request)) {
+ request.getResourceResolver().revert();
}
}
-
}
/**
@@ -209,19 +203,19 @@
* information
* @param changes A container to add {@link Modification} instances
* representing the operations done.
- * @throws RepositoryException Maybe thrown if any error occurrs while
+ * @throws PersistenceException Maybe thrown if any error occurs while
* accessing the repository.
*/
protected abstract void doRun(SlingHttpServletRequest request,
PostResponse response,
- List<Modification> changes) throws RepositoryException;
+ List<Modification> changes) throws PersistenceException;
/**
* Get the versioning configuration.
* @param request The http request
* @return The versioning configuration
*/
- protected VersioningConfiguration getVersioningConfiguration(SlingHttpServletRequest request) {
+ protected VersioningConfiguration getVersioningConfiguration(final SlingHttpServletRequest request) {
VersioningConfiguration versionableConfiguration =
(VersioningConfiguration) request.getAttribute(VersioningConfiguration.class.getName());
return versionableConfiguration != null ? versionableConfiguration : new VersioningConfiguration();
@@ -239,37 +233,22 @@
/**
* Check whether changes should be written back
* @param request The http request
- * @return {@code true} If session handling should be skipped
+ * @return {@code true} If committing be skipped
*/
- protected boolean isSkipSessionHandling(SlingHttpServletRequest request) {
+ private boolean isSkipSessionHandling(SlingHttpServletRequest request) {
return Boolean.parseBoolean((String) request.getAttribute(SlingPostConstants.ATTR_SKIP_SESSION_HANDLING)) == true;
}
/**
* Check whether commit to the resource resolver should be called.
- * @param session The JCR session
* @param request The http request
- * @return {@code true} if a save is required.
- * @throws RepositoryException
+ * @return {@code true} if a commit is required.
*/
- protected boolean isSessionSaveRequired(Session session, SlingHttpServletRequest request)
- throws RepositoryException {
+ private boolean isResourceResolverCommitRequired(SlingHttpServletRequest request) {
return !isSkipSessionHandling(request) && request.getResourceResolver().hasChanges();
}
/**
- * Returns the path of the resource of the request as the item path.
- * <p>
- * This method may be overwritten by extension if the operation has
- * different requirements on path processing.
- * @param request The http request
- * @return The item path
- */
- protected String getItemPath(SlingHttpServletRequest request) {
- return request.getResource().getPath();
- }
-
- /**
* Returns an iterator on <code>Resource</code> instances addressed in the
* {@link SlingPostConstants#RP_APPLY_TO} request parameter. If the request
* parameter is not set, <code>null</code> is returned. If the parameter
@@ -335,6 +314,18 @@
}
/**
+ * Returns the path of the resource of the request as the item path.
+ * <p>
+ * This method may be overwritten by extension if the operation has
+ * different requirements on path processing.
+ * @param request The http request
+ * @return The resource path
+ */
+ protected String getResourcePath(SlingHttpServletRequest request) {
+ return request.getResource().getPath();
+ }
+
+ /**
* Returns true if any of the request parameters starts with
* {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_CURRENT <code>./</code>}.
* In this case only parameters starting with either of the prefixes
@@ -378,104 +369,6 @@
|| name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_PARENT);
}
- /**
- * Orders the given node according to the specified command. The following
- * syntax is supported: <xmp> | first | before all child nodes | before A |
- * before child node A | after A | after child node A | last | after all
- * nodes | N | at a specific position, N being an integer </xmp>
- *
- * @param request The http request
- * @param item node to order
- * @param changes The list of modifications
- * @throws RepositoryException if an error occurs
- */
- protected void orderNode(SlingHttpServletRequest request, Item item,
- List<Modification> changes) throws RepositoryException {
-
- String command = request.getParameter(SlingPostConstants.RP_ORDER);
- if (command == null || command.length() == 0) {
- // nothing to do
- return;
- }
-
- if (!item.isNode()) {
- return;
- }
-
- Node parent = item.getParent();
-
- String next = null;
- if (command.equals(SlingPostConstants.ORDER_FIRST)) {
-
- next = parent.getNodes().nextNode().getName();
-
- } else if (command.equals(SlingPostConstants.ORDER_LAST)) {
-
- next = "";
-
- } else if (command.startsWith(SlingPostConstants.ORDER_BEFORE)) {
-
- next = command.substring(SlingPostConstants.ORDER_BEFORE.length());
-
- } else if (command.startsWith(SlingPostConstants.ORDER_AFTER)) {
-
- String name = command.substring(SlingPostConstants.ORDER_AFTER.length());
- NodeIterator iter = parent.getNodes();
- while (iter.hasNext()) {
- Node n = iter.nextNode();
- if (n.getName().equals(name)) {
- if (iter.hasNext()) {
- next = iter.nextNode().getName();
- } else {
- next = "";
- }
- }
- }
-
- } else {
- // check for integer
- try {
- // 01234
- // abcde move a -> 2 (above 3)
- // bcade move a -> 1 (above 1)
- // bacde
- int newPos = Integer.parseInt(command);
- next = "";
- NodeIterator iter = parent.getNodes();
- while (iter.hasNext() && newPos >= 0) {
- Node n = iter.nextNode();
- if (n.getName().equals(item.getName())) {
- // if old node is found before index, need to
- // inc index
- newPos++;
- }
- if (newPos == 0) {
- next = n.getName();
- break;
- }
- newPos--;
- }
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(
- "provided node ordering command is invalid: " + command);
- }
- }
-
- if (next != null) {
- if (next.equals("")) {
- next = null;
- }
- parent.orderBefore(item.getName(), next);
- changes.add(Modification.onOrder(item.getPath(), next));
- if (log.isDebugEnabled()) {
- log.debug("Node {} moved '{}'", item.getPath(), command);
- }
- } else {
- throw new IllegalArgumentException(
- "provided node ordering command is invalid: " + command);
- }
- }
-
protected Node findVersionableAncestor(Node node) throws RepositoryException {
if (isVersionable(node)) {
return node;
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
index f5faf7a..21ac0e5 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
@@ -24,6 +24,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
@@ -37,34 +38,37 @@
@Override
protected void doRun(SlingHttpServletRequest request, PostResponse response, List<Modification> changes)
- throws RepositoryException {
- Iterator<Resource> res = getApplyToResources(request);
- if (res == null) {
+ throws PersistenceException {
+ try {
+ Iterator<Resource> res = getApplyToResources(request);
+ if (res == null) {
- Resource resource = request.getResource();
- Node node = resource.adaptTo(Node.class);
- if (node == null) {
- response.setStatus(HttpServletResponse.SC_NOT_FOUND,
- "Missing source " + resource + " for checkout");
- return;
- }
-
- node.checkin();
- changes.add(Modification.onCheckin(resource.getPath()));
-
- } else {
-
- while (res.hasNext()) {
- Resource resource = res.next();
+ Resource resource = request.getResource();
Node node = resource.adaptTo(Node.class);
- if (node != null) {
- node.checkin();
- changes.add(Modification.onCheckin(resource.getPath()));
+ if (node == null) {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND,
+ "Missing source " + resource + " for checkout");
+ return;
}
+
+ node.checkin();
+ changes.add(Modification.onCheckin(resource.getPath()));
+
+ } else {
+
+ while (res.hasNext()) {
+ Resource resource = res.next();
+ Node node = resource.adaptTo(Node.class);
+ if (node != null) {
+ node.checkin();
+ changes.add(Modification.onCheckin(resource.getPath()));
+ }
+ }
+
}
-
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException(re.getMessage(), re);
}
-
}
/**
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
index 610eaa7..a835d6a 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
@@ -24,6 +24,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
@@ -36,34 +37,37 @@
public class CheckoutOperation extends AbstractPostOperation {
@Override
protected void doRun(SlingHttpServletRequest request, PostResponse response, List<Modification> changes)
- throws RepositoryException {
- Iterator<Resource> res = getApplyToResources(request);
- if (res == null) {
+ throws PersistenceException {
+ try {
+ Iterator<Resource> res = getApplyToResources(request);
+ if (res == null) {
- Resource resource = request.getResource();
- Node node = resource.adaptTo(Node.class);
- if (node == null) {
- response.setStatus(HttpServletResponse.SC_NOT_FOUND,
- "Missing source " + resource + " for checkout");
- return;
- }
-
- node.checkout();
- changes.add(Modification.onCheckout(resource.getPath()));
-
- } else {
-
- while (res.hasNext()) {
- Resource resource = res.next();
+ Resource resource = request.getResource();
Node node = resource.adaptTo(Node.class);
- if (node != null) {
- node.checkout();
- changes.add(Modification.onCheckout(resource.getPath()));
+ if (node == null) {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND,
+ "Missing source " + resource + " for checkout");
+ return;
}
+
+ node.checkout();
+ changes.add(Modification.onCheckout(resource.getPath()));
+
+ } else {
+
+ while (res.hasNext()) {
+ Resource resource = res.next();
+ Node node = resource.adaptTo(Node.class);
+ if (node != null) {
+ node.checkout();
+ changes.add(Modification.onCheckout(resource.getPath()));
+ }
+ }
+
}
-
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException(re.getMessage(), re);
}
-
}
/**
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
index 0530965..37fef28 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
@@ -26,6 +26,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
+import org.apache.sling.api.resource.Resource;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.VersioningConfiguration;
@@ -42,16 +43,22 @@
}
@Override
- protected Item execute(List<Modification> changes, Item source,
+ protected Resource execute(List<Modification> changes,
+ Resource source,
String destParent, String destName,
VersioningConfiguration versioningConfiguration) throws RepositoryException {
+ // ensure we have an item underlying the request's resource
+ Item item = source.adaptTo(Item.class);
+ if (item == null) {
+ return null;
+ }
- Item destItem = copy(source, (Node) source.getSession().getItem(destParent), destName);
+ Item destItem = copy(item, (Node) item.getSession().getItem(destParent), destName);
String dest = destParent + "/" + destName;
changes.add(Modification.onCopied(source.getPath(), dest));
log.debug("copy {} to {}", source, dest);
- return destItem;
+ return source.getResourceResolver().getResource(destItem.getPath());
}
/**
@@ -101,7 +108,7 @@
throw new RepositoryException(
"Cannot copy ancestor " + src.getPath() + " to descendant " + dstParent.getPath());
}
-
+
// ensure destination name
if (name == null) {
name = src.getName();
@@ -132,7 +139,7 @@
}
return dst;
}
-
+
/** @return true if src is an ancestor node of dest, or if
* both are the same node */
static boolean isAncestorOrSameNode(Node src, Node dest) throws RepositoryException {
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
index bde5017..ec5c19d 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
@@ -52,7 +52,7 @@
@Override
protected void doRun(final SlingHttpServletRequest request,
final PostResponse response, final List<Modification> changes)
- throws RepositoryException {
+ throws PersistenceException {
// SLING-3203: selectors, extension and suffix make no sense here and
// might lead to deleting other resources than the one the user means.
@@ -69,17 +69,21 @@
final VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
final boolean deleteChunks = isDeleteChunkRequest(request);
final Iterator<Resource> res = getApplyToResources(request);
- if (res == null) {
- final Resource resource = request.getResource();
- deleteResource(resource, changes, versioningConfiguration,
- deleteChunks);
- } else {
- while (res.hasNext()) {
- final Resource resource = res.next();
+ try {
+ if (res == null) {
+ final Resource resource = request.getResource();
deleteResource(resource, changes, versioningConfiguration,
deleteChunks);
- }
+ } else {
+ while (res.hasNext()) {
+ final Resource resource = res.next();
+ deleteResource(resource, changes, versioningConfiguration,
+ deleteChunks);
+ }
+ }
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException(re.getMessage(), re);
}
}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
index cce7df1..0d6910b 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
@@ -65,205 +65,204 @@
@Override
protected void doRun(SlingHttpServletRequest request, PostResponse response, final List<Modification> changes)
- throws RepositoryException {
- ContentImporter importer = contentImporter;
- if (importer == null) {
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
- "Missing content importer for import");
- return;
- }
- Map<String, RequestProperty> reqProperties = collectContent(request,
- response);
-
- VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
-
- // do not change order unless you have a very good reason.
- Session session = request.getResourceResolver().adaptTo(Session.class);
-
+ throws PersistenceException {
try {
- processCreate(request.getResourceResolver(), reqProperties, response, changes, versioningConfiguration);
- } catch ( final PersistenceException pe) {
- if ( pe.getCause() instanceof RepositoryException ) {
- throw (RepositoryException)pe.getCause();
- }
- throw new RepositoryException(pe);
- }
- String path = response.getPath();
- Node node = null;
- try {
- node = (Node) session.getItem(path);
- } catch ( RepositoryException e ) {
- log.warn(e.getMessage(),e);
- // was not able to resolve the node
- } catch ( ClassCastException e) {
- log.warn(e.getMessage(),e);
- // it was not a node
- }
- if (node == null) {
-
- response.setStatus(HttpServletResponse.SC_NOT_FOUND,
- "Missing target node " + path + " for import");
- return;
- }
-
- String contentType = getRequestParamAsString(request, SlingPostConstants.RP_CONTENT_TYPE);
- if (contentType == null) {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
- "Required :contentType parameter is missing");
- return;
- }
-
- //import options passed as request parameters.
- final boolean replace = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_REPLACE));
- final boolean replaceProperties = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_REPLACE_PROPERTIES));
- final boolean checkin = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_CHECKIN));
- final boolean autoCheckout = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_AUTO_CHECKOUT));
-
- String basePath = getItemPath(request);
- if (basePath.endsWith("/")) {
- //remove the trailing slash
- basePath = basePath.substring(0, basePath.length() - 1);
- }
-
- // default to creating content
- response.setCreateRequest(true);
-
- final String targetName;
- //check if a name was posted to use as the name of the imported root node
- if (getRequestParamAsString(request, SlingPostConstants.RP_NODE_NAME) != null) {
- // exact name
- targetName = getRequestParamAsString(request, SlingPostConstants.RP_NODE_NAME);
- if (targetName.length() > 0 && node.hasNode(targetName)) {
- if (replace) {
- response.setCreateRequest(false);
- } else {
- response.setStatus(
- HttpServletResponse.SC_PRECONDITION_FAILED,
- "Cannot import " + path + "/" + targetName
- + ": node exists");
- return;
- }
- }
- } else if (getRequestParamAsString(request, SlingPostConstants.RP_NODE_NAME_HINT) != null) {
- // node name hint only
- String nodePath = generateName(request, basePath);
- String name = nodePath.substring(nodePath.lastIndexOf('/') + 1);
- targetName = name;
- } else {
- // no name posted, so the import won't create a root node
- targetName = "";
- }
- final String contentRootName = targetName + "." + contentType;
-
- try {
- InputStream contentStream = null;
- RequestParameter contentParameter = request.getRequestParameter(SlingPostConstants.RP_CONTENT);
- if (contentParameter != null) {
- contentStream = contentParameter.getInputStream();
- } else {
- RequestParameter contentFile = request.getRequestParameter(SlingPostConstants.RP_CONTENT_FILE);
- if (contentFile != null) {
- contentStream = contentFile.getInputStream();
- }
- }
-
- if (contentStream == null) {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
- "Missing content for import");
+ ContentImporter importer = contentImporter;
+ if (importer == null) {
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Missing content importer for import");
return;
- } else {
- importer.importContent(node, contentRootName, contentStream,
- new ImportOptions() {
+ }
+ Map<String, RequestProperty> reqProperties = collectContent(request,
+ response);
- @Override
- public boolean isCheckin() {
- return checkin;
- }
+ VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
- @Override
- public boolean isAutoCheckout() {
- return autoCheckout;
- }
+ // do not change order unless you have a very good reason.
+ Session session = request.getResourceResolver().adaptTo(Session.class);
- @Override
- public boolean isIgnoredImportProvider(
- String extension) {
- // this probably isn't important in this context.
- return false;
- }
+ processCreate(request.getResourceResolver(), reqProperties, response, changes, versioningConfiguration);
- @Override
- public boolean isOverwrite() {
- return replace;
- }
+ String path = response.getPath();
+ Node node = null;
+ try {
+ node = (Node) session.getItem(path);
+ } catch ( RepositoryException e ) {
+ log.warn(e.getMessage(),e);
+ // was not able to resolve the node
+ } catch ( ClassCastException e) {
+ log.warn(e.getMessage(),e);
+ // it was not a node
+ }
+ if (node == null) {
- /* (non-Javadoc)
- * @see org.apache.sling.jcr.contentloader.ImportOptions#isPropertyOverwrite()
- */
- @Override
- public boolean isPropertyOverwrite() {
- return replaceProperties;
- }
- },
- new ContentImportListener() {
-
- @Override
- public void onReorder(String orderedPath, String beforeSibbling) {
- changes.add(Modification.onOrder(orderedPath, beforeSibbling));
- }
-
- @Override
- public void onMove(String srcPath, String destPath) {
- changes.add(Modification.onMoved(srcPath, destPath));
- }
-
- @Override
- public void onModify(String srcPath) {
- changes.add(Modification.onModified(srcPath));
- }
-
- @Override
- public void onDelete(String srcPath) {
- changes.add(Modification.onDeleted(srcPath));
- }
-
- @Override
- public void onCreate(String srcPath) {
- changes.add(Modification.onCreated(srcPath));
- }
-
- @Override
- public void onCopy(String srcPath, String destPath) {
- changes.add(Modification.onCopied(srcPath, destPath));
- }
-
- @Override
- public void onCheckin(String srcPath) {
- changes.add(Modification.onCheckin(srcPath));
- }
- @Override
- public void onCheckout(String srcPath) {
- changes.add(Modification.onCheckout(srcPath));
- }
- });
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND,
+ "Missing target node " + path + " for import");
+ return;
}
- if (!changes.isEmpty()) {
- //fill in the data for the response report
- Modification modification = changes.get(0);
- if (modification.getType() == ModificationType.CREATE) {
- String importedPath = modification.getSource();
- response.setLocation(externalizePath(request, importedPath));
- response.setPath(importedPath);
- int lastSlashIndex = importedPath.lastIndexOf('/');
- if (lastSlashIndex != -1) {
- String parentPath = importedPath.substring(0, lastSlashIndex);
- response.setParentLocation(externalizePath(request, parentPath));
+ String contentType = getRequestParamAsString(request, SlingPostConstants.RP_CONTENT_TYPE);
+ if (contentType == null) {
+ response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
+ "Required :contentType parameter is missing");
+ return;
+ }
+
+ //import options passed as request parameters.
+ final boolean replace = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_REPLACE));
+ final boolean replaceProperties = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_REPLACE_PROPERTIES));
+ final boolean checkin = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_CHECKIN));
+ final boolean autoCheckout = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_AUTO_CHECKOUT));
+
+ String basePath = getResourcePath(request);
+ if (basePath.endsWith("/")) {
+ //remove the trailing slash
+ basePath = basePath.substring(0, basePath.length() - 1);
+ }
+
+ // default to creating content
+ response.setCreateRequest(true);
+
+ final String targetName;
+ //check if a name was posted to use as the name of the imported root node
+ if (getRequestParamAsString(request, SlingPostConstants.RP_NODE_NAME) != null) {
+ // exact name
+ targetName = getRequestParamAsString(request, SlingPostConstants.RP_NODE_NAME);
+ if (targetName.length() > 0 && node.hasNode(targetName)) {
+ if (replace) {
+ response.setCreateRequest(false);
+ } else {
+ response.setStatus(
+ HttpServletResponse.SC_PRECONDITION_FAILED,
+ "Cannot import " + path + "/" + targetName
+ + ": node exists");
+ return;
}
}
+ } else if (getRequestParamAsString(request, SlingPostConstants.RP_NODE_NAME_HINT) != null) {
+ // node name hint only
+ String nodePath = generateName(request, basePath);
+ String name = nodePath.substring(nodePath.lastIndexOf('/') + 1);
+ targetName = name;
+ } else {
+ // no name posted, so the import won't create a root node
+ targetName = "";
}
- } catch (IOException e) {
- throw new RepositoryException(e);
+ final String contentRootName = targetName + "." + contentType;
+ try {
+ InputStream contentStream = null;
+ RequestParameter contentParameter = request.getRequestParameter(SlingPostConstants.RP_CONTENT);
+ if (contentParameter != null) {
+ contentStream = contentParameter.getInputStream();
+ } else {
+ RequestParameter contentFile = request.getRequestParameter(SlingPostConstants.RP_CONTENT_FILE);
+ if (contentFile != null) {
+ contentStream = contentFile.getInputStream();
+ }
+ }
+
+ if (contentStream == null) {
+ response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
+ "Missing content for import");
+ return;
+ } else {
+ importer.importContent(node, contentRootName, contentStream,
+ new ImportOptions() {
+
+ @Override
+ public boolean isCheckin() {
+ return checkin;
+ }
+
+ @Override
+ public boolean isAutoCheckout() {
+ return autoCheckout;
+ }
+
+ @Override
+ public boolean isIgnoredImportProvider(
+ String extension) {
+ // this probably isn't important in this context.
+ return false;
+ }
+
+ @Override
+ public boolean isOverwrite() {
+ return replace;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.sling.jcr.contentloader.ImportOptions#isPropertyOverwrite()
+ */
+ @Override
+ public boolean isPropertyOverwrite() {
+ return replaceProperties;
+ }
+ },
+ new ContentImportListener() {
+
+ @Override
+ public void onReorder(String orderedPath, String beforeSibbling) {
+ changes.add(Modification.onOrder(orderedPath, beforeSibbling));
+ }
+
+ @Override
+ public void onMove(String srcPath, String destPath) {
+ changes.add(Modification.onMoved(srcPath, destPath));
+ }
+
+ @Override
+ public void onModify(String srcPath) {
+ changes.add(Modification.onModified(srcPath));
+ }
+
+ @Override
+ public void onDelete(String srcPath) {
+ changes.add(Modification.onDeleted(srcPath));
+ }
+
+ @Override
+ public void onCreate(String srcPath) {
+ changes.add(Modification.onCreated(srcPath));
+ }
+
+ @Override
+ public void onCopy(String srcPath, String destPath) {
+ changes.add(Modification.onCopied(srcPath, destPath));
+ }
+
+ @Override
+ public void onCheckin(String srcPath) {
+ changes.add(Modification.onCheckin(srcPath));
+ }
+ @Override
+ public void onCheckout(String srcPath) {
+ changes.add(Modification.onCheckout(srcPath));
+ }
+ });
+ }
+
+ if (!changes.isEmpty()) {
+ //fill in the data for the response report
+ Modification modification = changes.get(0);
+ if (modification.getType() == ModificationType.CREATE) {
+ String importedPath = modification.getSource();
+ response.setLocation(externalizePath(request, importedPath));
+ response.setPath(importedPath);
+ int lastSlashIndex = importedPath.lastIndexOf('/');
+ if (lastSlashIndex != -1) {
+ String parentPath = importedPath.substring(0, lastSlashIndex);
+ response.setParentLocation(externalizePath(request, parentPath));
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new PersistenceException(e.getMessage(), e);
+ }
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException(re.getMessage(), re);
}
+
+
}
}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/JCRSupport.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/JCRSupport.java
new file mode 100644
index 0000000..0c27116
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/JCRSupport.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.servlets.post.impl.operations;
+
+import java.util.List;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.servlets.post.Modification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JCRSupport {
+
+ public static final JCRSupport INSTANCE = new JCRSupport();
+
+ /** Logger. */
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final Object supportImpl;
+
+ public JCRSupport() {
+ Object impl = null;
+ try {
+ impl = new JCRSupportImpl();
+ } catch ( final Throwable t) {
+ logger.warn("Support for JCR operations like checkin, checkout, ordering etc. is currently disabled " +
+ "in the servlets post module. Check whether the JCR API is available.");
+ }
+ this.supportImpl = impl;
+ }
+
+ public void orderNode(final SlingHttpServletRequest request,
+ final Resource resource,
+ final List<Modification> changes) throws PersistenceException {
+ if ( supportImpl != null ) {
+ ((JCRSupportImpl)supportImpl).orderNode(request, resource, changes);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/JCRSupportImpl.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/JCRSupportImpl.java
new file mode 100644
index 0000000..f9382c0
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/JCRSupportImpl.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.servlets.post.impl.operations;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.SlingPostConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JCRSupportImpl {
+
+ /** Logger. */
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ /**
+ * Orders the given node according to the specified command. The following
+ * syntax is supported: <xmp> | first | before all child nodes | before A |
+ * before child node A | after A | after child node A | last | after all
+ * nodes | N | at a specific position, N being an integer </xmp>
+ *
+ * @param request The http request
+ * @param item node to order
+ * @param changes The list of modifications
+ * @throws RepositoryException if an error occurs
+ */
+ public void orderNode(final SlingHttpServletRequest request,
+ final Resource resource,
+ final List<Modification> changes) throws PersistenceException {
+
+ final String command = request.getParameter(SlingPostConstants.RP_ORDER);
+ if (command == null || command.length() == 0) {
+ // nothing to do
+ return;
+ }
+
+ final Node node = resource.adaptTo(Node.class);
+ if (node == null) {
+ return;
+ }
+
+ try {
+ final Node parent = node.getParent();
+
+ String next = null;
+ if (command.equals(SlingPostConstants.ORDER_FIRST)) {
+
+ next = parent.getNodes().nextNode().getName();
+
+ } else if (command.equals(SlingPostConstants.ORDER_LAST)) {
+
+ next = "";
+
+ } else if (command.startsWith(SlingPostConstants.ORDER_BEFORE)) {
+
+ next = command.substring(SlingPostConstants.ORDER_BEFORE.length());
+
+ } else if (command.startsWith(SlingPostConstants.ORDER_AFTER)) {
+
+ String name = command.substring(SlingPostConstants.ORDER_AFTER.length());
+ NodeIterator iter = parent.getNodes();
+ while (iter.hasNext()) {
+ Node n = iter.nextNode();
+ if (n.getName().equals(name)) {
+ if (iter.hasNext()) {
+ next = iter.nextNode().getName();
+ } else {
+ next = "";
+ }
+ }
+ }
+
+ } else {
+ // check for integer
+ try {
+ // 01234
+ // abcde move a -> 2 (above 3)
+ // bcade move a -> 1 (above 1)
+ // bacde
+ int newPos = Integer.parseInt(command);
+ next = "";
+ NodeIterator iter = parent.getNodes();
+ while (iter.hasNext() && newPos >= 0) {
+ Node n = iter.nextNode();
+ if (n.getName().equals(node.getName())) {
+ // if old node is found before index, need to
+ // inc index
+ newPos++;
+ }
+ if (newPos == 0) {
+ next = n.getName();
+ break;
+ }
+ newPos--;
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ "provided node ordering command is invalid: " + command);
+ }
+ }
+
+ if (next != null) {
+ if (next.equals("")) {
+ next = null;
+ }
+ parent.orderBefore(node.getName(), next);
+ changes.add(Modification.onOrder(node.getPath(), next));
+ if (logger.isDebugEnabled()) {
+ logger.debug("Node {} moved '{}'", node.getPath(), command);
+ }
+ } else {
+ throw new IllegalArgumentException(
+ "provided node ordering command is invalid: " + command);
+ }
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException("Unable to order resource", re, resource.getPath(), null);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
index 19fbdab..72b14ce 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
@@ -78,7 +78,7 @@
protected void doRun(final SlingHttpServletRequest request,
final PostResponse response,
final List<Modification> changes)
- throws RepositoryException {
+ throws PersistenceException {
try {
final Map<String, RequestProperty> reqProperties = collectContent(request, response);
@@ -102,20 +102,14 @@
// order content
final Resource newResource = request.getResourceResolver().getResource(response.getPath());
- final Node newNode = newResource.adaptTo(Node.class);
- if ( newNode != null ) {
- orderNode(request, newNode, changes);
- }
- } catch ( final PersistenceException pe) {
- if ( pe.getCause() instanceof RepositoryException ) {
- throw (RepositoryException)pe.getCause();
- }
- throw new RepositoryException(pe);
+ this.jcrSsupport.orderNode(request, newResource, changes);
+ } catch ( final RepositoryException pe) {
+ throw new PersistenceException(pe.getMessage(), pe);
}
}
@Override
- protected String getItemPath(SlingHttpServletRequest request) {
+ protected String getResourcePath(SlingHttpServletRequest request) {
// calculate the paths
StringBuilder rootPathBuf = new StringBuilder();
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
index 1a680ef..baacf55 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
@@ -22,6 +22,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import org.apache.sling.api.resource.Resource;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.VersioningConfiguration;
@@ -38,9 +39,15 @@
}
@Override
- protected Item execute(List<Modification> changes, Item source,
+ protected Resource execute(List<Modification> changes, Resource source,
String destParent, String destName,
- VersioningConfiguration versioningConfiguration) throws RepositoryException {
+ VersioningConfiguration versioningConfiguration)
+ throws RepositoryException {
+ // ensure we have an item underlying the request's resource
+ Item item = source.adaptTo(Item.class);
+ if (item == null) {
+ return null;
+ }
if (destName == null) {
destName = source.getName();
@@ -51,17 +58,17 @@
destParent = "";
}
String destPath = destParent + "/" + destName;
- Session session = source.getSession();
-
- checkoutIfNecessary(source.getParent(), changes, versioningConfiguration);
+ Session session = item.getSession();
+
+ checkoutIfNecessary(item.getParent(), changes, versioningConfiguration);
if (session.itemExists(destPath)) {
session.getItem(destPath).remove();
}
-
+
session.move(sourcePath, destPath);
changes.add(Modification.onMoved(sourcePath, destPath));
- return session.getItem(destPath);
+ return source.getResourceResolver().getResource(destPath);
}
}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
index 5838525..e5f5d0d 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
@@ -27,6 +27,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
@@ -41,34 +42,38 @@
@Override
protected void doRun(SlingHttpServletRequest request, PostResponse response, List<Modification> changes)
- throws RepositoryException {
- final String version = request.getParameter(SlingPostConstants.RP_VERSION);
- if (version == null || version.length() == 0) {
- throw new IllegalArgumentException("Unable to process restore. Missing version");
- }
- final String removeString = request.getParameter(SlingPostConstants.RP_REMOVE_EXISTING);
- final boolean removeExisting = Boolean.parseBoolean(removeString);
-
- Iterator<Resource> res = getApplyToResources(request);
- if (res == null) {
- Resource resource = request.getResource();
- Node node = resource.adaptTo(Node.class);
- if (node == null) {
- response.setStatus(HttpServletResponse.SC_NOT_FOUND,
- "Missing source " + resource + " for restore");
- return;
+ throws PersistenceException {
+ try {
+ final String version = request.getParameter(SlingPostConstants.RP_VERSION);
+ if (version == null || version.length() == 0) {
+ throw new IllegalArgumentException("Unable to process restore. Missing version");
}
- restore(node, version, removeExisting);
- changes.add(Modification.onRestore(resource.getPath(), version));
- } else {
- while (res.hasNext()) {
- Resource resource = res.next();
+ final String removeString = request.getParameter(SlingPostConstants.RP_REMOVE_EXISTING);
+ final boolean removeExisting = Boolean.parseBoolean(removeString);
+
+ Iterator<Resource> res = getApplyToResources(request);
+ if (res == null) {
+ Resource resource = request.getResource();
Node node = resource.adaptTo(Node.class);
- if (node != null) {
- restore(node, version, removeExisting);
- changes.add(Modification.onRestore(resource.getPath(), version));
+ if (node == null) {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND,
+ "Missing source " + resource + " for restore");
+ return;
+ }
+ restore(node, version, removeExisting);
+ changes.add(Modification.onRestore(resource.getPath(), version));
+ } else {
+ while (res.hasNext()) {
+ Resource resource = res.next();
+ Node node = resource.adaptTo(Node.class);
+ if (node != null) {
+ restore(node, version, removeExisting);
+ changes.add(Modification.onRestore(resource.getPath(), version));
+ }
}
}
+ } catch ( final RepositoryException re) {
+ throw new PersistenceException(re.getMessage(), re);
}
}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
index 956cfd0..d875329 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
@@ -24,7 +24,6 @@
import java.util.List;
import java.util.Map;
-import javax.jcr.RepositoryException; // required due to AbstractPostOperation signature.
import javax.servlet.ServletContext;
import javax.servlet.http.Part;
@@ -76,36 +75,30 @@
}
@Override
- protected void doRun(SlingHttpServletRequest request, PostResponse response, List<Modification> changes) throws RepositoryException {
- try {
- Iterator<Part> partsIterator = (Iterator<Part>) request.getAttribute("request-parts-iterator");
- Map<String, List<String>> formFields = new HashMap<>();
- boolean streamingBodies = false;
- while (partsIterator.hasNext()) {
- Part part = partsIterator.next();
- String name = part.getName();
+ protected void doRun(SlingHttpServletRequest request, PostResponse response, List<Modification> changes)
+ throws PersistenceException {
+ @SuppressWarnings("unchecked")
+ Iterator<Part> partsIterator = (Iterator<Part>) request.getAttribute("request-parts-iterator");
+ Map<String, List<String>> formFields = new HashMap<>();
+ boolean streamingBodies = false;
+ while (partsIterator.hasNext()) {
+ Part part = partsIterator.next();
+ String name = part.getName();
- if (isFormField(part)) {
- addField(formFields, name, part);
- if (streamingBodies) {
- LOG.warn("Form field {} was sent after the bodies started to be streamed. " +
- "Will not have been available to all streamed bodies. " +
- "It is recommended to send all form fields before streamed bodies in the POST ", name);
- }
- } else {
- streamingBodies = true;
- // process the file body and commit.
- writeContent(request.getResourceResolver(), part, formFields, response, changes);
-
+ if (isFormField(part)) {
+ addField(formFields, name, part);
+ if (streamingBodies) {
+ LOG.warn("Form field {} was sent after the bodies started to be streamed. " +
+ "Will not have been available to all streamed bodies. " +
+ "It is recommended to send all form fields before streamed bodies in the POST ", name);
}
- }
- } catch ( final PersistenceException pe) {
- if ( pe.getCause() instanceof RepositoryException ) {
- throw (RepositoryException)pe.getCause();
- }
- throw new RepositoryException(pe);
- }
+ } else {
+ streamingBodies = true;
+ // process the file body and commit.
+ writeContent(request.getResourceResolver(), part, formFields, response, changes);
+ }
+ }
}
/**
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java b/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java
index 8dd2a62..064bdf2 100644
--- a/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java
+++ b/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java
@@ -19,6 +19,22 @@
package org.apache.sling.servlets.post.impl.operations;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.Part;
+
import org.apache.commons.io.IOUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ModifiableValueMap;
@@ -39,21 +55,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.RepositoryException;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.Part;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
public class StreamingUploadOperationTest {
@@ -72,8 +73,8 @@
}
@Test
- public void test() throws RepositoryException, UnsupportedEncodingException {
- List<Modification> changes = new ArrayList<Modification>();
+ public void test() throws PersistenceException, RepositoryException, UnsupportedEncodingException {
+ List<Modification> changes = new ArrayList<>();
PostResponse response = new AbstractPostResponse() {
@Override
protected void doSend(HttpServletResponse response) throws IOException {
@@ -91,14 +92,14 @@
}
};
- List<Part> partsList = new ArrayList<Part>();
+ List<Part> partsList = new ArrayList<>();
partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("test1.txt", "text/plain", "test1bad.txt", 4, new ByteArrayInputStream("test".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
final Iterator<Part> partsIterator = partsList.iterator();
- final Map<String, Resource> repository = new HashMap<String, Resource>();
+ final Map<String, Resource> repository = new HashMap<>();
final ResourceResolver resourceResolver = new MockResourceResolver() {
@Override
public Resource getResource(String path) {
@@ -244,8 +245,8 @@
}
@Test
- public void testParts() throws RepositoryException, UnsupportedEncodingException {
- List<Modification> changes = new ArrayList<Modification>();
+ public void testParts() throws PersistenceException, RepositoryException, UnsupportedEncodingException {
+ List<Modification> changes = new ArrayList<>();
PostResponse response = new AbstractPostResponse() {
@Override
protected void doSend(HttpServletResponse response) throws IOException {
@@ -263,7 +264,7 @@
}
};
- List<Part> partsList = new ArrayList<Part>();
+ List<Part> partsList = new ArrayList<>();
partsList.add(new MockPart("test1.txt@Length", null, null, 0, new ByteArrayInputStream("8".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("test1.txt@Offset", null, null, 0, new ByteArrayInputStream("0".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart(
@@ -284,7 +285,7 @@
partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
final Iterator<Part> partsIterator = partsList.iterator();
- final Map<String, Resource> repository = new HashMap<String, Resource>();
+ final Map<String, Resource> repository = new HashMap<>();
final ResourceResolver resourceResolver = new MockResourceResolver() {
@Override
public Resource getResource(String path) {
@@ -309,7 +310,7 @@
@Override
public Iterable<Resource> getChildren(Resource resource) {
- List<Resource> children = new ArrayList<Resource>();
+ List<Resource> children = new ArrayList<>();
for(Map.Entry<String, Resource> e : repository.entrySet()) {
if (isChild(resource.getPath(), e.getKey())) {
children.add(e.getValue());
@@ -457,8 +458,8 @@
}
@Test
- public void testPartsContentRange() throws RepositoryException, UnsupportedEncodingException {
- List<Modification> changes = new ArrayList<Modification>();
+ public void testPartsContentRange() throws PersistenceException, RepositoryException, UnsupportedEncodingException {
+ List<Modification> changes = new ArrayList<>();
PostResponse response = new AbstractPostResponse() {
@Override
protected void doSend(HttpServletResponse response) throws IOException {
@@ -476,7 +477,7 @@
}
};
- List<Part> partsList = new ArrayList<Part>();
+ List<Part> partsList = new ArrayList<>();
partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart(
@@ -496,7 +497,7 @@
partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
final Iterator<Part> partsIterator = partsList.iterator();
- final Map<String, Resource> repository = new HashMap<String, Resource>();
+ final Map<String, Resource> repository = new HashMap<>();
final ResourceResolver resourceResolver = new MockResourceResolver() {
@Override
public Resource getResource(String path) {
@@ -521,7 +522,7 @@
@Override
public Iterable<Resource> getChildren(Resource resource) {
- List<Resource> children = new ArrayList<Resource>();
+ List<Resource> children = new ArrayList<>();
for(Map.Entry<String, Resource> e : repository.entrySet()) {
if (isChild(resource.getPath(), e.getKey())) {
children.add(e.getValue());
@@ -671,7 +672,7 @@
private Map<String,Object> mapOf(String ... s) {
- Map<String, Object> m = new HashMap<String, Object>();
+ Map<String, Object> m = new HashMap<>();
for (int i = 0; i < s.length; i+=2) {
m.put(s[i],s[i+1]);
}