You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2017/03/29 10:09:32 UTC
svn commit: r1789321 -
/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/
Author: cziegeler
Date: Wed Mar 29 10:09:31 2017
New Revision: 1789321
URL: http://svn.apache.org/viewvc?rev=1789321&view=rev
Log:
SLING-6743 : Drop workspace support
Added:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java (with props)
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java Wed Mar 29 10:09:31 2017
@@ -28,7 +28,6 @@ import javax.servlet.http.HttpServletRes
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.SlingPostConstants;
@@ -37,7 +36,7 @@ import org.apache.sling.servlets.post.Ve
/**
* The <code>AbstractCopyMoveOperation</code> is the abstract base close for
* the {@link CopyOperation} and {@link MoveOperation} classes implementing
- * commong behaviour.
+ * common behaviour.
*/
abstract class AbstractCopyMoveOperation extends AbstractPostOperation {
@@ -68,7 +67,6 @@ abstract class AbstractCopyMoveOperation
dest = ResourceUtil.getParent(source) + "/" + dest;
}
dest = ResourceUtil.normalize(dest);
- dest = removeAndValidateWorkspace(dest, session);
// destination parent and name
String dstParent = trailingSlash ? dest : ResourceUtil.getParent(dest);
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java Wed Mar 29 10:09:31 2017
@@ -29,8 +29,8 @@ import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
+import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
@@ -40,7 +40,6 @@ import org.apache.sling.api.resource.Per
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.NodeNameGenerator;
import org.apache.sling.servlets.post.PostResponse;
@@ -161,7 +160,7 @@ abstract class AbstractCreateOperation e
if ( mvm != null ) {
final Node node = rsrc.adaptTo(Node.class);
- final Set<String> newMixins = new HashSet<String>();
+ final Set<String> newMixins = new HashSet<>();
newMixins.addAll(Arrays.asList(mixins));
// clear existing mixins first
@@ -206,7 +205,7 @@ abstract class AbstractCreateOperation e
final boolean requireItemPrefix = requireItemPathPrefix(request);
// walk the request parameters and collect the properties
- final LinkedHashMap<String, RequestProperty> reqProperties = new LinkedHashMap<String, RequestProperty>();
+ final LinkedHashMap<String, RequestProperty> reqProperties = new LinkedHashMap<>();
for (final Map.Entry<String, RequestParameter[]> e : request.getRequestParameterMap().entrySet()) {
final String paramName = e.getKey();
@@ -570,7 +569,7 @@ abstract class AbstractCreateOperation e
}
try {
- final Map<String, Object> props = new HashMap<String, Object>();
+ final Map<String, Object> props = new HashMap<>();
if (nodeType != null) {
props.put("jcr:primaryType", nodeType);
}
@@ -636,9 +635,7 @@ abstract class AbstractCreateOperation e
basePath = basePath += "/" + specialParam.getString();
// if the resulting path already exists then report an error
- Session session = request.getResourceResolver().adaptTo(Session.class);
- String jcrPath = removeAndValidateWorkspace(basePath, session);
- if (request.getResourceResolver().getResource(jcrPath) != null) {
+ if (request.getResourceResolver().getResource(basePath) != null) {
throw new RepositoryException(
"Collision in node names for path=" + basePath);
}
@@ -676,31 +673,26 @@ abstract class AbstractCreateOperation e
private String ensureUniquePath(SlingHttpServletRequest request, String basePath) throws RepositoryException {
// if resulting path exists, add a suffix until it's not the case
// anymore
- final Session session = request.getResourceResolver().adaptTo(Session.class);
final ResourceResolver resolver = request.getResourceResolver();
- // basePath might contain a workspace prefix, need to remove it
- // to test for existence
- String jcrPath = removeAndValidateWorkspace(basePath, session);
-
// if resulting path exists, add a random suffix until it's not the case
// anymore
final int MAX_TRIES = 1000;
- if (resolver.getResource(jcrPath) != null ) {
+ if (resolver.getResource(basePath) != null ) {
for(int i=0; i < MAX_TRIES; i++) {
final int uniqueIndex = Math.abs(randomCollisionIndex.nextInt());
- String newPath = jcrPath + "_" + uniqueIndex;
+ String newPath = basePath + "_" + uniqueIndex;
if (resolver.getResource(newPath) == null) {
basePath = basePath + "_" + uniqueIndex;
- jcrPath = newPath;
+ basePath = newPath;
break;
}
}
// Give up after MAX_TRIES
- if (resolver.getResource(jcrPath) != null ) {
+ if (resolver.getResource(basePath) != null ) {
throw new RepositoryException(
- "Collision in generated node names under " + basePath + ", generated path " + jcrPath + " already exists");
+ "Collision in generated node names under " + basePath + ", generated path " + basePath + " already exists");
}
}
Added: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java?rev=1789321&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java (added)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java Wed Mar 29 10:09:31 2017
@@ -0,0 +1,612 @@
+/*
+ * 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.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+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.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.wrappers.SlingRequestPaths;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.PostOperation;
+import org.apache.sling.servlets.post.PostResponse;
+import org.apache.sling.servlets.post.SlingPostConstants;
+import org.apache.sling.servlets.post.SlingPostProcessor;
+import org.apache.sling.servlets.post.VersioningConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 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.
+ */
+public abstract class AbstractPostOperation implements PostOperation {
+
+ /**
+ * default log
+ */
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * 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
+ * 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
+ * of errors, the unsaved changes in the session are rolled back.
+ *
+ * @param request the request to operate on
+ * @param response The <code>PostResponse</code> to record execution
+ * progress.
+ * @param processors The array of processors
+ */
+ @Override
+ 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);
+ response.setPath(path);
+
+ // location
+ response.setLocation(externalizePath(request, path));
+
+ // parent location
+ path = ResourceUtil.getParent(path);
+ if (path != null) {
+ response.setParentLocation(externalizePath(request, path));
+ }
+
+ final List<Modification> changes = new ArrayList<>();
+
+ doRun(request, response, changes);
+
+ // invoke processors
+ if (processors != null) {
+ for (SlingPostProcessor processor : processors) {
+ processor.process(request, changes);
+ }
+ }
+
+ // check modifications for remaining postfix and store the base path
+ final Map<String, String> modificationSourcesContainingPostfix = new HashMap<>();
+ final Set<String> allModificationSources = new HashSet<>(changes.size());
+ for (final Modification modification : changes) {
+ final String source = modification.getSource();
+ if (source != null) {
+ allModificationSources.add(source);
+ final int atIndex = source.indexOf('@');
+ if (atIndex > 0) {
+ modificationSourcesContainingPostfix.put(source.substring(0, atIndex), source);
+ }
+ }
+ }
+
+ // fail if any of the base paths (before the postfix) which had a postfix are contained in the modification set
+ if (modificationSourcesContainingPostfix.size() > 0) {
+ for (final Map.Entry<String, String> sourceToCheck : modificationSourcesContainingPostfix.entrySet()) {
+ if (allModificationSources.contains(sourceToCheck.getKey())) {
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Postfix-containing path " + sourceToCheck.getValue() +
+ " contained in the modification list. Check configuration.");
+ return;
+ }
+ }
+ }
+
+ final Set<String> nodesToCheckin = new LinkedHashSet<>();
+
+ // set changes on html response
+ for(Modification change : changes) {
+ switch ( change.getType() ) {
+ case MODIFY : response.onModified(change.getSource()); break;
+ case DELETE : response.onDeleted(change.getSource()); break;
+ case MOVE : response.onMoved(change.getSource(), change.getDestination()); break;
+ case COPY : response.onCopied(change.getSource(), change.getDestination()); break;
+ case CREATE :
+ response.onCreated(change.getSource());
+ if (versionableConfiguration.isCheckinOnNewVersionableNode()) {
+ nodesToCheckin.add(change.getSource());
+ }
+ break;
+ case ORDER : response.onChange("ordered", change.getSource(), change.getDestination()); break;
+ case CHECKOUT :
+ response.onChange("checkout", change.getSource());
+ nodesToCheckin.add(change.getSource());
+ break;
+ case CHECKIN :
+ response.onChange("checkin", change.getSource());
+ nodesToCheckin.remove(change.getSource());
+ break;
+ }
+ }
+
+ if (isSessionSaveRequired(session, request)) {
+ request.getResourceResolver().commit();
+ }
+
+ if (!isSkipCheckin(request)) {
+ // now do the checkins
+ for(String checkinPath : nodesToCheckin) {
+ if (checkin(request.getResourceResolver(), checkinPath)) {
+ response.onChange("checkin", checkinPath);
+ }
+ }
+ }
+
+ } catch (Exception e) {
+
+ log.error("Exception during response processing.", e);
+ response.setError(e);
+
+ } finally {
+ try {
+ if (isSessionSaveRequired(session, request)) {
+ request.getResourceResolver().revert();
+ }
+ } catch (RepositoryException e) {
+ log.warn("RepositoryException in finally block: {}",
+ e.getMessage(), e);
+ }
+ }
+
+ }
+
+ /**
+ * Actually performs the desired operation filling progress into the
+ * <code>changes</code> list and preparing and further information in the
+ * <code>response</code>.
+ * <p>
+ * The <code>response</code> comes prepared with the path, location and
+ * parent location set. Other properties are expected to be set by this
+ * implementation.
+ *
+ * @param request The <code>SlingHttpServletRequest</code> providing the
+ * input, mostly in terms of request parameters, to the
+ * operation.
+ * @param response The {@link PostResponse} to fill with response
+ * information
+ * @param changes A container to add {@link Modification} instances
+ * representing the operations done.
+ * @throws RepositoryException Maybe thrown if any error occurrs while
+ * accessing the repository.
+ */
+ protected abstract void doRun(SlingHttpServletRequest request,
+ PostResponse response,
+ List<Modification> changes) throws RepositoryException;
+
+ /**
+ * Get the versioning configuration.
+ * @param request The http request
+ * @return The versioning configuration
+ */
+ protected VersioningConfiguration getVersioningConfiguration(SlingHttpServletRequest request) {
+ VersioningConfiguration versionableConfiguration =
+ (VersioningConfiguration) request.getAttribute(VersioningConfiguration.class.getName());
+ return versionableConfiguration != null ? versionableConfiguration : new VersioningConfiguration();
+ }
+
+ /**
+ * Check if checkin should be skipped
+ * @param request The http request
+ * @return {@code true} if checkin should be skipped
+ */
+ protected boolean isSkipCheckin(SlingHttpServletRequest request) {
+ return !getVersioningConfiguration(request).isAutoCheckin();
+ }
+
+ /**
+ * Check whether changes should be written back
+ * @param request The http request
+ * @return {@code true} If session handling should be skipped
+ */
+ protected 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
+ */
+ protected boolean isSessionSaveRequired(Session session, SlingHttpServletRequest request)
+ throws RepositoryException {
+ 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
+ * is set with valid resources an empty iterator is returned. Any resources
+ * addressed in the {@link SlingPostConstants#RP_APPLY_TO} parameter is
+ * ignored.
+ *
+ * @param request The <code>SlingHttpServletRequest</code> object used to
+ * get the {@link SlingPostConstants#RP_APPLY_TO} parameter.
+ * @return The iterator of resources listed in the parameter or
+ * <code>null</code> if the parameter is not set in the request.
+ */
+ protected Iterator<Resource> getApplyToResources(
+ SlingHttpServletRequest request) {
+
+ final String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO);
+ if (applyTo == null) {
+ return null;
+ }
+
+ return new ApplyToIterator(request, applyTo);
+ }
+
+ /**
+ * Returns an external form of the given path prepending the context path
+ * and appending a display extension.
+ *
+ * @param request The http request
+ * @param path the path to externalize
+ * @return the url
+ */
+ protected final String externalizePath(SlingHttpServletRequest request,
+ String path) {
+ StringBuilder ret = new StringBuilder();
+ ret.append(SlingRequestPaths.getContextPath(request));
+ ret.append(request.getResourceResolver().map(path));
+
+ // append optional extension
+ String ext = request.getParameter(SlingPostConstants.RP_DISPLAY_EXTENSION);
+ if (ext != null && ext.length() > 0) {
+ if (ext.charAt(0) != '.') {
+ ret.append('.');
+ }
+ ret.append(ext);
+ }
+
+ return ret.toString();
+ }
+
+ /**
+ * Resolves the given path with respect to the current root path.
+ *
+ * @param absPath The absolute base path
+ * @param relPath the path to resolve
+ * @return the given path if it starts with a '/'; a resolved path
+ * otherwise.
+ */
+ protected final String resolvePath(String absPath, String relPath) {
+ if (relPath.startsWith("/")) {
+ return relPath;
+ }
+ return absPath + "/" + relPath;
+ }
+
+ /**
+ * 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
+ * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_CURRENT <code>./</code>},
+ * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_PARENT <code>../</code>}
+ * and {@link SlingPostConstants#ITEM_PREFIX_ABSOLUTE <code>/</code>} are
+ * considered as providing content to be stored. Otherwise all parameters
+ * not starting with the command prefix <code>:</code> are considered as
+ * parameters to be stored.
+ *
+ * @param request The http request
+ * @return If a prefix is required.
+ */
+ protected final boolean requireItemPathPrefix(
+ SlingHttpServletRequest request) {
+
+ boolean requirePrefix = false;
+
+ Enumeration<?> names = request.getParameterNames();
+ while (names.hasMoreElements() && !requirePrefix) {
+ String name = (String) names.nextElement();
+ requirePrefix = name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_CURRENT);
+ }
+
+ return requirePrefix;
+ }
+
+ /**
+ * Returns <code>true</code> if the <code>name</code> starts with either
+ * of the prefixes
+ * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_CURRENT <code>./</code>},
+ * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_PARENT <code>../</code>}
+ * and {@link SlingPostConstants#ITEM_PREFIX_ABSOLUTE <code>/</code>}.
+ *
+ * @param name The name
+ * @return {@code true} if the name has a prefix
+ */
+ protected boolean hasItemPathPrefix(String name) {
+ return name.startsWith(SlingPostConstants.ITEM_PREFIX_ABSOLUTE)
+ || name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_CURRENT)
+ || 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;
+ }
+ try {
+ node = node.getParent();
+ return findVersionableAncestor(node);
+ } catch (ItemNotFoundException e) {
+ // top-level
+ return null;
+ }
+ }
+
+ protected boolean isVersionable(Node node) throws RepositoryException {
+ return node.isNodeType("mix:versionable");
+ }
+
+ protected void checkoutIfNecessary(Node node, List<Modification> changes,
+ VersioningConfiguration versioningConfiguration) throws RepositoryException {
+ if (versioningConfiguration.isAutoCheckout()) {
+ Node versionableNode = findVersionableAncestor(node);
+ if (versionableNode != null) {
+ if (!versionableNode.isCheckedOut()) {
+ versionableNode.checkout();
+ changes.add(Modification.onCheckout(versionableNode.getPath()));
+ }
+ }
+ }
+ }
+
+ private boolean checkin(final ResourceResolver resolver, final String path) throws RepositoryException {
+ final Resource rsrc = resolver.getResource(path);
+ final Node node = (rsrc == null ? null : rsrc.adaptTo(Node.class));
+ if (node != null) {
+ if (node.isCheckedOut() && isVersionable(node)) {
+ node.checkin();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static class ApplyToIterator implements Iterator<Resource> {
+
+ private final ResourceResolver resolver;
+ private final Resource baseResource;
+ private final String[] paths;
+
+ private int pathIndex;
+
+ private Resource nextResource;
+
+ private Iterator<Resource> resourceIterator = null;
+
+ ApplyToIterator(SlingHttpServletRequest request, String[] paths) {
+ this.resolver = request.getResourceResolver();
+ this.baseResource = request.getResource();
+ this.paths = paths;
+ this.pathIndex = 0;
+
+ nextResource = seek();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return nextResource != null;
+ }
+
+ @Override
+ public Resource next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ Resource result = nextResource;
+ nextResource = seek();
+
+ return result;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ private Resource seek() {
+ if (resourceIterator != null) {
+ if (resourceIterator.hasNext()) {
+ //return the next resource in the iterator
+ Resource res = resourceIterator.next();
+ return res;
+ }
+ resourceIterator = null;
+ }
+ while (pathIndex < paths.length) {
+ String path = paths[pathIndex];
+ pathIndex++;
+
+ //SLING-2415 - support wildcard as the last segment of the applyTo path
+ if (path.endsWith("*")) {
+ if (path.length() == 1) {
+ resourceIterator = baseResource.listChildren();
+ } else if (path.endsWith("/*")) {
+ path = path.substring(0, path.length() - 2);
+ if (path.length() == 0) {
+ resourceIterator = baseResource.listChildren();
+ } else {
+ Resource res = resolver.getResource(baseResource, path);
+ if (res != null) {
+ resourceIterator = res.listChildren();
+ }
+ }
+ }
+ if (resourceIterator != null) {
+ //return the first resource in the iterator
+ if (resourceIterator.hasNext()) {
+ Resource res = resourceIterator.next();
+ return res;
+ }
+ resourceIterator = null;
+ }
+ } else {
+ Resource res = resolver.getResource(baseResource, path);
+ if (res != null) {
+ return res;
+ }
+ }
+ }
+
+ // no more elements in the array
+ return null;
+ }
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractPostOperation.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java Wed Mar 29 10:09:31 2017
@@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRes
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java Wed Mar 29 10:09:31 2017
@@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRes
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java Wed Mar 29 10:09:31 2017
@@ -27,7 +27,6 @@ import org.apache.sling.api.SlingHttpSer
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.SlingPostConstants;
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java Wed Mar 29 10:09:31 2017
@@ -120,7 +120,6 @@ public class ImportOperation extends Abs
final boolean autoCheckout = "true".equalsIgnoreCase(getRequestParamAsString(request, SlingPostConstants.RP_AUTO_CHECKOUT));
String basePath = getItemPath(request);
- basePath = removeAndValidateWorkspace(basePath, request.getResourceResolver().adaptTo(Session.class));
if (basePath.endsWith("/")) {
//remove the trailing slash
basePath = basePath.substring(0, basePath.length() - 1);
@@ -208,33 +207,41 @@ public class ImportOperation extends Abs
},
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));
}
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java Wed Mar 29 10:09:31 2017
@@ -28,7 +28,6 @@ import javax.servlet.http.HttpServletRes
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.SlingPostConstants;
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java?rev=1789321&r1=1789320&r2=1789321&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java Wed Mar 29 10:09:31 2017
@@ -17,6 +17,17 @@
package org.apache.sling.servlets.post.impl.operations;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+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;
+
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.SlingHttpServletRequest;
@@ -24,23 +35,12 @@ import org.apache.sling.api.resource.Per
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.servlets.post.AbstractPostOperation;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.impl.helper.StreamedChunk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.RepositoryException; // required due to AbstractPostOperation signature.
-import javax.servlet.ServletContext;
-import javax.servlet.http.Part;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
/**
* Performs a streamed modification of the content.
* Each File body encountered will result in a session save operation, to cause the underlying Resource implementation
@@ -79,7 +79,7 @@ public class StreamedUploadOperation ext
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<String, List<String>>();
+ Map<String, List<String>> formFields = new HashMap<>();
boolean streamingBodies = false;
while (partsIterator.hasNext()) {
Part part = partsIterator.next();
@@ -117,7 +117,7 @@ public class StreamedUploadOperation ext
private void addField(Map<String, List<String>> formFields, String name, Part part) {
List<String> values = formFields.get(name);
if ( values == null ) {
- values = new ArrayList<String>();
+ values = new ArrayList<>();
formFields.put(name, values);
}
try {
@@ -153,7 +153,7 @@ public class StreamedUploadOperation ext
}
String name = getUploadName(part);
Resource fileResource = parentResource.getChild(name);
- Map<String, Object> fileProps = new HashMap<String, Object>();
+ Map<String, Object> fileProps = new HashMap<>();
if (fileResource == null) {
fileProps.put("jcr:primaryType", NT_FILE);
fileResource = parentResource.getResourceResolver().create(parentResource, name, fileProps);