[maven-release-plugin] copy for tag org.apache.sling.servlets.post-2.3.8
git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.servlets.post-2.3.8@1684838 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/post/README.txt b/post/README.txt
deleted file mode 100644
index ca88f5b..0000000
--- a/post/README.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Apache Sling Default Post Servlets
-
-Provides default POST servlets.
-
-Getting Started
-===============
-
-This component uses a Maven 2 (http://maven.apache.org/) build
-environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/)
-2.0.7 or later. We recommend to use the latest Maven version.
-
-If you have Maven 2 installed, you can compile and
-package the jar using the following command:
-
- mvn package
-
-See the Maven 2 documentation for other build features.
-
-The latest source code for this component is available in the
-Subversion (http://subversion.tigris.org/) source repository of
-the Apache Software Foundation. If you have Subversion installed,
-you can checkout the latest source using the following command:
-
- svn checkout http://svn.apache.org/repos/asf/sling/trunk/servlets/post
-
-See the Subversion documentation for other source control features.
-
diff --git a/post/pom.xml b/post/pom.xml
deleted file mode 100644
index 3768a28..0000000
--- a/post/pom.xml
+++ /dev/null
@@ -1,194 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>22</version>
- <relativePath />
- </parent>
-
- <artifactId>org.apache.sling.servlets.post</artifactId>
- <packaging>bundle</packaging>
- <version>2.3.8</version>
-
- <name>Apache Sling Default POST Servlets</name>
- <description>
- Provides default POST servlets.
- </description>
-
- <scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.servlets.post-2.3.8</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.servlets.post-2.3.8</developerConnection>
- <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.servlets.post-2.3.8</url>
- </scm>
-
- <properties>
- <site.jira.version.id>12314180</site.jira.version.id>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-scr-plugin</artifactId>
- </plugin>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.sling.servlets.post;version=2.3.0
- </Export-Package>
- <Private-Package>
- org.apache.sling.servlets.post.impl.*
- </Private-Package>
- <Sling-Bundle-Resources>
- /system/sling.js
- </Sling-Bundle-Resources>
- <Embed-Dependency>
- jackrabbit-jcr-commons;inline=org/apache/jackrabbit/util/ISO8601.class|org/apache/jackrabbit/util/Text.class
- </Embed-Dependency>
- <Sling-Namespaces>
- sling=http://sling.apache.org/jcr/sling/1.0
- </Sling-Namespaces>
- <Sling-Nodetypes>
- SLING-INF/nodetypes/chunk.cnd,
- </Sling-Nodetypes>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>src/main/resources/org/apache/sling/servlets/post/HtmlResponse.html</exclude>
- <exclude>src/main/resources/org/apache/sling/servlets/post/HtmlNoGoBackResponse.html</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <configuration>
- <!-- No javadocs -->
- <excludePackageNames>
- org.apache.sling.servlets.post.impl
- </excludePackageNames>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- <version>2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.api</artifactId>
- <version>2.3.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.jcr.api</artifactId>
- <version>2.0.6</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.0.2-incubator</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.4</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.json</artifactId>
- <version>2.0.2-incubator</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.jcr.contentloader</artifactId>
- <version>2.1.10</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-jcr-commons</artifactId>
- <version>1.6.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.testing</artifactId>
- <version>2.0.10</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit-addons</groupId>
- <artifactId>junit-addons</artifactId>
- <version>1.4</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
-
diff --git a/post/src/main/java/org/apache/sling/servlets/post/AbstractPostOperation.java b/post/src/main/java/org/apache/sling/servlets/post/AbstractPostOperation.java
deleted file mode 100644
index 9299b5b..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/AbstractPostOperation.java
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * 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;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-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 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.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 errorrs, 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.
- */
- 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);
- path = removeAndValidateWorkspace(path, session);
- 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<Modification>();
-
- doRun(request, response, changes);
-
- // invoke processors
- if (processors != null) {
- for (SlingPostProcessor processor : processors) {
- processor.process(request, changes);
- }
- }
-
- final Set<String> nodesToCheckin = new LinkedHashSet<String>();
-
- // 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.
- */
- 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
- */
- protected boolean isSkipCheckin(SlingHttpServletRequest request) {
- return !getVersioningConfiguration(request).isAutoCheckin();
- }
-
- /**
- * Check whether changes should be written back
- */
- 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.
- */
- protected boolean isSessionSaveRequired(Session session, SlingHttpServletRequest request)
- throws RepositoryException {
- return !isSkipSessionHandling(request) && request.getResourceResolver().hasChanges();
- }
-
- /**
- * Remove the workspace name, if any, from the start of the path and validate that the
- * session's workspace name matches the path workspace name.
- */
- protected String removeAndValidateWorkspace(String path, Session session) throws RepositoryException {
- final int wsSepPos = path.indexOf(":/");
- if (wsSepPos != -1) {
- final String workspaceName = path.substring(0, wsSepPos);
- if (!workspaceName.equals(session.getWorkspace().getName())) {
- throw new RepositoryException("Incorrect workspace. Expecting " + workspaceName + ". Received "
- + session.getWorkspace().getName());
- }
- return path.substring(wsSepPos + 1);
- }
- return path;
- }
-
-
- /**
- * 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.
- */
- 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 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 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.
- */
- 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>}.
- */
- 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 item node to order
- * @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();
- }
-
- public boolean hasNext() {
- return nextResource != null;
- }
-
- public Resource next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
-
- Resource result = nextResource;
- nextResource = seek();
-
- return result;
- }
-
- 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
diff --git a/post/src/main/java/org/apache/sling/servlets/post/AbstractPostResponse.java b/post/src/main/java/org/apache/sling/servlets/post/AbstractPostResponse.java
deleted file mode 100644
index ed462ea..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/AbstractPostResponse.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.SlingException;
-
-/**
- * The <code>AbstractPostResponse</code> class provides a basic implementation
- * of the {@link PostResponse} interface maintaining properties to be
- * prepared for sending the response in an internal map.
- */
-public abstract class AbstractPostResponse implements PostResponse {
-
- /**
- * Name of the title property set by {@link #setTitle(String)}
- */
- public static final String PN_TITLE = "title";
-
- /**
- * Name of the status code property set by {@link #setStatus(int, String)}
- */
- public static final String PN_STATUS_CODE = "status.code";
-
- /**
- * Name of the status message property set by {@link #setStatus(int, String)}
- */
- public static final String PN_STATUS_MESSAGE = "status.message";
-
- /**
- * Name of the location property set by {@link #setLocation(String)}
- */
- public static final String PN_LOCATION = "location";
-
- /**
- * Name of the parent location property set by {@link #setParentLocation(String)}
- */
- public static final String PN_PARENT_LOCATION = "parentLocation";
-
- /**
- * Name of the path property set by {@link #setPath(String)}
- */
- public static final String PN_PATH = "path";
-
- /**
- * Name of the referer property set by {@link #setReferer(String)}
- */
- public static final String PN_REFERER = "referer";
-
- /**
- * Name of the create status property set by {@link #setCreateRequest(boolean)}
- */
- public static final String PN_IS_CREATED = "isCreate";
-
- /**
- * Name of the error property set by {@link #setError(Throwable)}
- */
- public static final String PN_ERROR = "error";
-
- /**
- * Properties of the response
- */
- private final Map<String, Object> properties = new HashMap<String, Object>();
-
- // ---------- Settings for the response ------------------------------------
-
- /**
- * Returns the referer as from the 'referer' request header.
- */
- public String getReferer() {
- return getProperty(PN_REFERER, String.class);
- }
-
- /**
- * Sets the referer property
- */
- public void setReferer(String referer) {
- setProperty(PN_REFERER, referer);
- }
-
- /**
- * Returns the absolute path of the item upon which the request operated.
- * <p>
- * If the {@link #setPath(String)} method has not been called yet, this
- * method returns <code>null</code>.
- */
- public String getPath() {
- return getProperty(PN_PATH, String.class);
- }
-
- /**
- * Sets the absolute path of the item upon which the request operated.
- */
- public void setPath(String path) {
- setProperty(PN_PATH, path);
- }
-
- /**
- * Returns <code>true</code> if this was a create request.
- * <p>
- * Before calling the {@link #setCreateRequest(boolean)} method, this method
- * always returns <code>false</code>.
- */
- public boolean isCreateRequest() {
- final Boolean isCreateRequest = getProperty(PN_IS_CREATED,
- Boolean.class);
- return (isCreateRequest != null)
- ? isCreateRequest.booleanValue()
- : false;
- }
-
- /**
- * Sets whether the request was a create request or not.
- */
- public void setCreateRequest(boolean isCreateRequest) {
- setProperty(PN_IS_CREATED, isCreateRequest);
- }
-
- /**
- * Returns the location of the modification. this is the externalized form
- * of the current path.
- *
- * @return the location of the modification.
- */
- public String getLocation() {
- return getProperty(PN_LOCATION, String.class);
- }
-
- public void setLocation(String location) {
- setProperty(PN_LOCATION, location);
- }
-
- /**
- * Returns the parent location of the modification. this is the externalized
- * form of the parent node of the current path.
- *
- * @return the location of the modification.
- */
- public String getParentLocation() {
- return getProperty(PN_PARENT_LOCATION, String.class);
- }
-
- public void setParentLocation(String parentLocation) {
- setProperty(PN_PARENT_LOCATION, parentLocation);
- }
-
- /**
- * Sets the title of the response message
- *
- * @param title the title
- */
- public void setTitle(String title) {
- setProperty(PN_TITLE, title);
- }
-
- /**
- * sets the response status code properties
- *
- * @param code the code
- * @param message the message
- */
- public void setStatus(int code, String message) {
- setProperty(PN_STATUS_CODE, code);
- setProperty(PN_STATUS_MESSAGE, message);
- }
-
- /**
- * Returns the status code of this instance. If the status code has never
- * been set by calling the {@link #setStatus(int, String)} method, the
- * status code is determined by checking if there was an error. If there was
- * an error, the response is assumed to be unsuccessful and 500 is returned.
- * If there is no error, the response is assumed to be successful and 200 is
- * returned.
- */
- public int getStatusCode() {
- Integer status = getProperty(PN_STATUS_CODE, Integer.class);
- if (status == null) {
- if (getError() != null) {
- // if there was an error
- status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
- } else {
- status = HttpServletResponse.SC_OK;
- }
- }
- return status;
- }
-
- public String getStatusMessage() {
- return getProperty(PN_STATUS_MESSAGE, String.class);
- }
-
- /**
- * Returns any recorded error or <code>null</code>
- *
- * @return an error or <code>null</code>
- */
- public Throwable getError() {
- return getProperty(PN_ERROR, Throwable.class);
- }
-
- public void setError(Throwable error) {
- setProperty(PN_ERROR, new SlingException("Exception during response processing.", null));
- }
-
- /**
- * Returns <code>true</code> if no {@link #getError() error} is set and if
- * the {@link #getStatusCode() status code} is one of the 2xx codes.
- */
- public boolean isSuccessful() {
- return getError() == null && (getStatusCode() / 100) == 2;
- }
-
- // ---------- ChangeLog ----------------------------------------------------
-
- /**
- * Records a 'modified' change
- *
- * @param path path of the item that was modified
- */
- public void onModified(String path) {
- onChange("modified", path);
- }
-
- /**
- * Records a 'created' change
- *
- * @param path path of the item that was created
- */
- public void onCreated(String path) {
- onChange("created", path);
- }
-
- /**
- * Records a 'deleted' change
- *
- * @param path path of the item that was deleted
- */
- public void onDeleted(String path) {
- if (path != null) {
- onChange("deleted", path);
- }
- }
-
- /**
- * Records a 'moved' change.
- * <p/>
- * Note: the moved change only records the basic move command. the implied
- * changes on the moved properties and sub nodes are not recorded.
- *
- * @param srcPath source path of the node that was moved
- * @param dstPath destination path of the node that was moved.
- */
- public void onMoved(String srcPath, String dstPath) {
- onChange("moved", srcPath, dstPath);
- }
-
- /**
- * Records a 'copied' change.
- * <p/>
- * Note: the copy change only records the basic copy command. the implied
- * changes on the copied properties and sub nodes are not recorded.
- *
- * @param srcPath source path of the node that was copied
- * @param dstPath destination path of the node that was copied.
- */
- public void onCopied(String srcPath, String dstPath) {
- onChange("copied", srcPath, dstPath);
- }
-
-
- /**
- * prepares the response properties
- */
- private void prepare(final HttpServletResponse response, final boolean setStatus) {
- String path = getPath();
- if (getProperty(PN_STATUS_CODE) == null) {
- if (getError() != null) {
- setStatus(500, getError().toString());
- setTitle("Error while processing " + path);
- } else {
- if (isCreateRequest()) {
- setStatus(201, "Created");
- setTitle("Content created " + path);
- } else {
- setStatus(200, "OK");
- setTitle("Content modified " + path);
- }
- }
- }
-
- String referer = getReferer();
- if (referer == null) {
- referer = "";
- }
- setReferer(referer);
-
- if (setStatus) {
- Object status = getProperty(PN_STATUS_CODE);
- if (status instanceof Number) {
- int statusCode = ((Number) status).intValue();
- response.setStatus(statusCode);
-
- // special treatment of 201/CREATED and 3xx: Requires Location
- if (statusCode == HttpServletResponse.SC_CREATED || statusCode / 100 == 3) {
- response.setHeader("Location", getLocation());
- }
- }
- }
-
- }
-
- /**
- * Sets a generic response property with the given
- *
- * @param name name of the property
- * @param value value of the property
- */
- protected void setProperty(String name, Object value) {
- properties.put(name, value);
- }
-
- /**
- * Returns the generic response property with the given name and type or
- * <code>null</code> if no such property exists or the property is not of
- * the requested type.
- */
- @SuppressWarnings("unchecked")
- protected <Type> Type getProperty(String name, Class<Type> type) {
- Object value = getProperty(name);
- if (type.isInstance(value)) {
- return (Type) value;
- }
-
- return null;
- }
-
- /**
- * Returns the generic response property with the given name and type or
- * <code>null</code> if no such property exists.
- */
- protected Object getProperty(String name) {
- return properties.get(name);
- }
-
- protected boolean isSafeReferer(){
- String referer = getReferer();
- if (referer.startsWith("http://") || referer.startsWith("https://")) {
- return true;
- } else {
- return false;
- }
- }
-
- protected abstract void doSend(HttpServletResponse response) throws IOException;
-
- /**
- * Writes the response to the given writer and replaces all ${var} patterns
- * by the value of the respective property. if the property is not defined
- * the pattern is not modified.
- *
- * @param response to send to
- * @param setStatus whether to set the status code on the response
- * @throws IOException if an i/o exception occurs
- */
- public final void send(HttpServletResponse response, boolean setStatus)
- throws IOException {
- prepare(response, setStatus);
- doSend(response);
- }
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java b/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java
deleted file mode 100644
index 242710d..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-
-import javax.jcr.RepositoryException;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.servlets.HtmlResponse;
-import org.apache.sling.servlets.post.impl.helper.HtmlPostResponseProxy;
-import org.apache.sling.servlets.post.impl.helper.HtmlResponseProxy;
-
-/**
- * The <code>AbstractSlingPostOperation</code> is the abstract base class
- * implementation of the {@link SlingPostOperation} interface extending the new
- * {@link AbstractPostOperation}.
- * <p>
- * This class exists for backwards compatibility. Existing implementations are
- * advised to migrate to the new {@link AbstractPostOperation}.
- *
- * @deprecated as of 2.0.8 (Bundle version 2.2.0) and replaced by
- * {@link AbstractPostOperation}.
- */
-public abstract class AbstractSlingPostOperation extends AbstractPostOperation
- implements SlingPostOperation {
-
- /**
- *
- * @param request
- * @param response
- * @param changes
- * @throws RepositoryException
- */
- protected abstract void doRun(SlingHttpServletRequest request,
- HtmlResponse response, List<Modification> changes)
- throws RepositoryException;
-
- /**
- * Implementation of the
- * {@link AbstractPostOperation#doRun(SlingHttpServletRequest, PostResponse, List)}
- * method calling our own
- * {@link #run(SlingHttpServletRequest, HtmlResponse, SlingPostProcessor[])}
- * meethod with a proxy for the Sling API <code>HtmlResponse</code>.
- */
- protected void doRun(SlingHttpServletRequest request,
- PostResponse response, List<Modification> changes)
- throws RepositoryException {
- final HtmlResponse htmlResponseProxy = (response instanceof HtmlPostResponseProxy)
- ? ((HtmlPostResponseProxy) response).getHtmlResponse()
- : new HtmlResponseProxy(response);
- doRun(request, htmlResponseProxy, changes);
- }
-
- /**
- * Implementation of the
- * {@link SlingPostOperation#run(SlingHttpServletRequest, HtmlResponse, SlingPostProcessor[])}
- * API method calling the
- * {@link PostOperation#run(SlingHttpServletRequest, PostResponse, SlingPostProcessor[])}
- * with a proxy around the Sling API <code>HtmlResponse</code> provided.
- */
- public void run(SlingHttpServletRequest request, HtmlResponse response,
- SlingPostProcessor[] processors) {
- final PostResponse postResponseProxy = new HtmlPostResponseProxy(
- response);
- run(request, postResponseProxy, processors);
- }
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/HtmlResponse.java b/post/src/main/java/org/apache/sling/servlets/post/HtmlResponse.java
deleted file mode 100644
index 5c93c35..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/HtmlResponse.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.Writer;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.request.ResponseUtil;
-
-/**
- * The <code>HtmlResponse</code> is an {@link AbstractPostResponse} preparing
- * the response in HTML (actually XHTML) such that it can be interpreted
- * as a plain response in a browser or as XML response in an Ajax request.
- */
-public class HtmlResponse extends AbstractPostResponse {
-
- /**
- * Name of the property into which the change log is gathered to be
- * sent back by the {@link #doSend(HttpServletResponse)} method. This
- * property is only sent before replacing all variables in the HTML
- * response remplate.
- */
- private static final String PN_CHANGE_LOG = "changeLog";
-
- /**
- * name of the html template
- */
- private static final String TEMPLATE_NAME = "HtmlResponse.html";
-
- /**
- * name of the html safe referer template
- */
- private static final String NO_GO_BACK_TEMPLATE_NAME = "HtmlNoGoBackResponse.html";
-
- /**
- * list of changes
- */
- private final StringBuilder changes = new StringBuilder();
-
- /**
- * Records a generic change of the given <code>type</code>.
- * <p>
- * The change is added to the internal list of changes with the syntax of a
- * method call, where the <code>type</code> is the method name and the
- * <code>arguments</code> are the string arguments to the method enclosed in
- * double quotes. For example, the the call
- *
- * <pre>
- * onChange("sameple", "arg1", "arg2");
- * </pre>
- *
- * is aded as
- *
- * <pre>
- * sample("arg1", "arg2")
- * </pre>
- *
- * to the internal list of changes.
- *
- * @param type The type of the modification
- * @param arguments The arguments to the modifications
- */
- public void onChange(String type, String... arguments) {
- changes.append(type);
- String delim = "(";
- for (String a : arguments) {
- changes.append(delim);
- changes.append('\"');
- changes.append(a);
- changes.append('\"');
- delim = ", ";
- }
- changes.append(");<br/>");
- }
-
- // ---------- Response Generation ------------------------------------------
-
- /**
- * Writes the response to the given writer and replaces all ${var} patterns
- * by the value of the respective property. if the property is not defined
- * the pattern is not modified.
- *
- * @param response to send to
- * @param setStatus whether to set the status code on the response
- * @throws IOException if an i/o exception occurs
- */
- @Override
- protected void doSend(HttpServletResponse response)
- throws IOException {
-
- response.setContentType("text/html");
- response.setCharacterEncoding("UTF-8");
-
- // get changelog
- changes.insert(0, "<pre>");
- changes.append("</pre>");
- setProperty(PN_CHANGE_LOG, changes.toString());
-
- Writer out = response.getWriter();
-
- String templateName;
- if(isSafeReferer()) {
- templateName = TEMPLATE_NAME;
- } else {
- templateName = NO_GO_BACK_TEMPLATE_NAME;
- }
-
- InputStream template = getClass().getResourceAsStream(templateName);
- Reader in = new BufferedReader(new InputStreamReader(template));
- StringBuilder varBuffer = new StringBuilder();
- int state = 0;
- int read;
- while ((read = in.read()) >= 0) {
- char c = (char) read;
- switch (state) {
- // initial
- case 0:
- if (c == '$') {
- state = 1;
- } else {
- out.write(c);
- }
- break;
- // $ read
- case 1:
- if (c == '{') {
- state = 2;
- } else {
- state = 0;
- out.write('$');
- out.write(c);
- }
- break;
- // { read
- case 2:
- if (c == '}') {
- state = 0;
- Object prop = getProperty(varBuffer.toString());
- if (prop != null) {
- out.write(ResponseUtil.escapeXml(prop.toString()));
- }
- varBuffer.setLength(0);
- } else {
- varBuffer.append(c);
- }
- }
- }
- in.close();
- out.flush();
- }
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/JSONResponse.java b/post/src/main/java/org/apache/sling/servlets/post/JSONResponse.java
deleted file mode 100644
index 8863abb..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/JSONResponse.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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;
-
-import org.apache.sling.commons.json.JSONArray;
-import org.apache.sling.commons.json.JSONException;
-import org.apache.sling.commons.json.JSONObject;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * The <code>JSONResponse</code> is an {@link AbstractPostResponse} preparing
- * the response in JSON.
- */
-public class JSONResponse extends AbstractPostResponse {
-
- public static final String RESPONSE_CONTENT_TYPE = "application/json";
-
- // package private because it is used by the unit test
- static final String PROP_TYPE = "type";
-
- // package private because it is used by the unit test
- static final String PROP_ARGUMENT = "argument";
-
- // package private because it is used by the unit test
- static final String RESPONSE_CHARSET = "UTF-8";
-
- private static final String PROP_CHANGES = "changes";
-
- private JSONObject json = new JSONObject();
-
- private JSONArray changes = new JSONArray();
-
- private Throwable error;
-
- public JSONResponse() throws JSONResponseException {
- try {
- json = new JSONObject();
- changes = new JSONArray();
- json.put(PROP_CHANGES, changes);
- } catch (Throwable e) {
- throw new JSONResponseException(e);
- }
- }
-
- public void onChange(String type, String... arguments)
- throws JSONResponseException {
- try {
- JSONObject change = new JSONObject();
- change.put(PROP_TYPE, type);
- for (String argument : arguments) {
- change.accumulate(PROP_ARGUMENT, argument);
- }
- changes.put(change);
- } catch (JSONException e) {
- throw new JSONResponseException(e);
- }
- }
-
- @Override
- public void setError(Throwable error) {
- try {
- this.error = error;
- JSONObject jsonError = new JSONObject();
- jsonError.put("class", error.getClass().getName());
- jsonError.put("message", error.getMessage());
- json.put("error", jsonError);
- } catch (JSONException e) {
- throw new JSONResponseException(e);
- }
- }
-
- @Override
- public Throwable getError() {
- return this.error;
- }
-
- @Override
- public void setProperty(String name, Object value) {
- try {
- this.json.put(name, value);
- } catch (Throwable e) {
- throw new JSONResponseException("Error setting JSON property '"
- + name + "' to '" + value + "'", e);
- }
- }
-
- @Override
- public Object getProperty(String name) throws JSONResponseException {
- try {
- if (json.has(name)) {
- return json.get(name);
- } else {
- return null;
- }
- } catch (JSONException e) {
- throw new JSONResponseException("Error getting JSON property '"
- + name + "'", e);
- }
- }
-
- @SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
- @Override
- protected void doSend(HttpServletResponse response) throws IOException {
-
- response.setContentType(RESPONSE_CONTENT_TYPE);
- response.setCharacterEncoding(RESPONSE_CHARSET);
-
- try {
- json.write(response.getWriter());
- } catch (JSONException e) {
- IOException ioe = new IOException("Error creating JSON response");
- ioe.initCause(e);
- throw ioe;
- }
- }
-
- JSONObject getJson() {
- return json;
- }
-
- public class JSONResponseException extends RuntimeException {
-
- public JSONResponseException(String message, Throwable exception) {
- super(message, exception);
- }
-
- public JSONResponseException(Throwable e) {
- super("Error building JSON response", e);
- }
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/Modification.java b/post/src/main/java/org/apache/sling/servlets/post/Modification.java
deleted file mode 100644
index f5b7741..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/Modification.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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;
-
-public class Modification {
-
- private final ModificationType type;
-
- private final String source;
-
- private final String destination;
-
- public Modification(final ModificationType type, final String source,
- final String destination) {
- this.type = type;
- this.source = source;
- this.destination = destination;
- }
-
- public ModificationType getType() {
- return type;
- }
-
- public String getSource() {
- return source;
- }
-
- public String getDestination() {
- return destination;
- }
-
- /**
- * Records a 'modified' change
- *
- * @param path path of the item that was modified
- */
- public static Modification onModified(String path) {
- return onChange(ModificationType.MODIFY, path);
- }
-
- /**
- * Records a 'created' change
- *
- * @param path path of the item that was created
- */
- public static Modification onCreated(String path) {
- return onChange(ModificationType.CREATE, path);
- }
-
- /**
- * Records a 'deleted' change
- *
- * @param path path of the item that was deleted
- */
- public static Modification onDeleted(String path) {
- return onChange(ModificationType.DELETE, path);
- }
-
- /**
- * Records a 'moved' change.
- * <p/>
- * Note: the moved change only records the basic move command. the implied
- * changes on the moved properties and sub nodes are not recorded.
- *
- * @param srcPath source path of the node that was moved
- * @param dstPath destination path of the node that was moved.
- */
- public static Modification onMoved(String srcPath, String dstPath) {
- return onChange(ModificationType.MOVE, srcPath, dstPath);
- }
-
- /**
- * Records a 'copied' change.
- * <p/>
- * Note: the copy change only records the basic copy command. the implied
- * changes on the copied properties and sub nodes are not recorded.
- *
- * @param srcPath source path of the node that was copied
- * @param dstPath destination path of the node that was copied.
- */
- public static Modification onCopied(String srcPath, String dstPath) {
- return onChange(ModificationType.COPY, srcPath, dstPath);
- }
-
- /**
- * Records a 'order' change.
- *
- * @param orderedPath Path of the node that was reordered
- * @param beforeSibbling Name of the sibbling node before which the source node has
- * been inserted.
- */
- public static Modification onOrder(String orderedPath, String beforeSibbling) {
- return onChange(ModificationType.ORDER, orderedPath, beforeSibbling);
- }
-
- protected static Modification onChange(ModificationType type, String source) {
- return onChange(type, source, null);
- }
-
- protected static Modification onChange(ModificationType type,
- final String source, final String dest) {
- return new Modification(type, source, dest);
- }
-
- public static Modification onCheckin(String path) {
- return onChange(ModificationType.CHECKIN, path, null);
- }
-
- public static Modification onCheckout(String path) {
- return onChange(ModificationType.CHECKOUT, path, null);
- }
-
- public static Modification onRestore(String path, String version) {
- return onChange(ModificationType.RESTORE, path, version);
- }
-
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Modification[type=").append(type).append(", source=").append(source);
- if (destination != null) {
- builder.append(", dest=").append(destination);
- }
- builder.append("]");
- return builder.toString();
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java b/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java
deleted file mode 100644
index 1781a8f..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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;
-
-public enum ModificationType {
-
- /**
- * Content has been created or updated. The source path provides the path of
- * the modified Item.
- */
- MODIFY,
-
- /**
- * An Item has been deleted. The source path provides the path of the
- * deleted Item.
- */
- DELETE,
-
- /**
- * An Item has been moved to a new location. The source provides the
- * original path of the Item, the destination provides the new path of the
- * Item.
- */
- MOVE,
-
- /**
- * An Item has been copied to a new location. The source path provides the
- * path of the copied Item, the destination path provides the path of the
- * new Item.
- */
- COPY,
-
- /**
- * A Node has been created. The source path provides the path of the newly
- * created Node.
- */
- CREATE,
-
- /**
- * A child Node has been reordered. The source path provides the path of the
- * node, which has been reordered. The destination path provides the name of
- * the sibbling node before which the source Node has been ordered. which
- * the
- */
- ORDER,
-
- /**
- * A Node has been checked out. The source path provides the path of the node.
- */
- CHECKOUT,
-
- /**
- * A Node has been checked in. The source path provides the path of the node.
- */
- CHECKIN,
-
- /**
- * A Node has been restored to a given version. The soruce path provides the
- * path of the node and the destination describes the target version.
- */
- RESTORE
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java b/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java
deleted file mode 100644
index 1234c3e..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/NodeNameGenerator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-
-/**
- * Service interface which allows for custom node name generation for * resources.
- *
- */
-public interface NodeNameGenerator {
-
- /**
- * Get the to-be-created node name from the request.
- *
- * @param req request
- * @param parentPath the path to the new node's parent
- * @param requirePrefix if true, ignore parameters which do not being with ./
- * @param defaultNodeNameGenerator the default node name generator
- *
- * @return the node name to be created or null if other NodeNameGenerators should be consulted
- */
- public String getNodeName(SlingHttpServletRequest request, String parentPath, boolean requirePrefix,
- NodeNameGenerator defaultNodeNameGenerator);
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/PostOperation.java b/post/src/main/java/org/apache/sling/servlets/post/PostOperation.java
deleted file mode 100644
index 366a298..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/PostOperation.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-
-/**
- * The <code>PostOperation</code> interface defines the service API to be
- * implemented by service providers extending the Sling POST servlet. Service
- * providers may register OSGi services of this type to be used by the Sling
- * default POST servlet to handle specific operations.
- * <p>
- * The <code>PostOperation</code> service must be registered with a
- * {@link #PROP_OPERATION_NAME} registration property giving the name(s) of the
- * operations supported by the service. The names will be used to find the
- * actual operation from the {@link SlingPostConstants#RP_OPERATION
- * <code>:operation</code>} request parameter.
- * <p>
- * The Sling POST servlet itself provides various operations (see the
- * <code>OPERATION_</code> constants in the {@link SlingPostConstants}
- * interface.These names should not be used by <code>SlingPostOperation</code>
- * service providers.
- * <p>
- * This interface replaces the old {@link SlingPostOperation} service interface
- * adding support for extensible responses by means of the {@link PostResponse}
- * interface as well as operation postprocessing.
- * <p>
- * Implementors of this interface are advised to extend the
- * {@link AbstractPostOperation} class to benefit from various precossings
- * implemented by that abstract class.
- */
-public interface PostOperation {
-
- /**
- * The name of the Sling POST operation service.
- */
- public static final String SERVICE_NAME = "org.apache.sling.servlets.post.PostOperation";
-
- /**
- * The name of the service registration property indicating the name(s) of
- * the operation provided by the operation implementation. The value of this
- * service property must be a single String or an array or
- * <code>java.util.Collection</code> of Strings. If multiple strings are
- * defined, the service is registered for all operation names.
- */
- public static final String PROP_OPERATION_NAME = "sling.post.operation";
-
- /**
- * Executes the operation provided by this service implementation. This
- * method is called by the Sling POST servlet.
- *
- * @param request The <code>SlingHttpServletRequest</code> object providing
- * the request input for the operation.
- * @param response The <code>HtmlResponse</code> into which the operation
- * steps should be recorded.
- * @param processors The {@link SlingPostProcessor} services to be called
- * after applying the operation. This may be <code>null</code> if
- * there are none.
- * @throws org.apache.sling.api.resource.ResourceNotFoundException May be
- * thrown if the operation requires an existing request
- * resource. If this exception is thrown the Sling POST servlet
- * sends back a <code>404/NOT FOUND</code> response to the
- * client.
- * @throws org.apache.sling.api.SlingException May be thrown if an error
- * occurrs running the operation.
- */
- void run(SlingHttpServletRequest request, PostResponse response,
- SlingPostProcessor[] processors);
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/PostResponse.java b/post/src/main/java/org/apache/sling/servlets/post/PostResponse.java
deleted file mode 100644
index e9dbfc8..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/PostResponse.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * The <code>PostResponse</code> interface defines the API of a response
- * container which can (and should) be used by {@link PostOperation} services to
- * prepare responses to be sent back to the client.
- * <p>
- * This bundle provides a preconfigured {@link HtmlResponse} and a
- * {@link JSONResponse} implementation of this interface. Clients may extend the
- * {@link AbstractPostResponse} class to provide their own response
- * implementations.
- */
-public interface PostResponse {
-
- /**
- * Sets the referer property
- */
- public void setReferer(String referer);
-
- /**
- * Returns the referer previously set by {@link #setReferer(String)}
- */
- public String getReferer();
-
- /**
- * Sets the absolute path of the item upon which the request operated.
- */
- public void setPath(String path);
-
- /**
- * Returns the absolute path of the item upon which the request operated.
- * <p>
- * If the {@link #setPath(String)} method has not been called yet, this
- * method returns <code>null</code>.
- */
- public String getPath();
-
- /**
- * Sets whether the request was a create request or not.
- */
- public void setCreateRequest(boolean isCreateRequest);
-
- /**
- * Returns <code>true</code> if this was a create request.
- * <p>
- * Before calling the {@link #setCreateRequest(boolean)} method, this method
- * always returns <code>false</code>.
- */
- public boolean isCreateRequest();
-
- /**
- * Sets the location of this modification. This is the externalized form of
- * the {@link #getPath() current path}.
- *
- * @param location
- */
- public void setLocation(String location);
-
- /**
- * Returns the location of the modification.
- * <p>
- * If the {@link #setLocation(String)} method has not been called yet, this
- * method returns <code>null</code>.
- */
- public String getLocation();
-
- /**
- * Sets the parent location of the modification. This is the externalized
- * form of the parent node of the {@link #getPath() current path}.
- */
- public void setParentLocation(String parentLocation);
-
- /**
- * Returns the parent location of the modification.
- * <p>
- * If the {@link #setParentLocation(String)} method has not been called yet,
- * this method returns <code>null</code>.
- */
- public String getParentLocation();
-
- /**
- * Sets the title of the response message
- *
- * @param title the title
- */
- public void setTitle(String title);
-
- /**
- * Sets the response status code properties
- *
- * @param code the code
- * @param message the message
- */
- public void setStatus(int code, String message);
-
- /**
- * Returns the status code of this instance. If the status code has never
- * been set by calling the {@link #setStatus(int, String)} method, the
- * status code is determined by checking if there was an error. If there was
- * an error, the response is assumed to be unsuccessful and 500 is returned.
- * If there is no error, the response is assumed to be successful and 200 is
- * returned.
- */
- public int getStatusCode();
-
- /**
- * Returns the status message or <code>null</code> if no has been set with
- * the {@link #setStatus(int, String)} method.
- */
- public String getStatusMessage();
-
- /**
- * Sets the recorded error causing the operation to fail.
- */
- public void setError(Throwable error);
-
- /**
- * Returns any recorded error or <code>null</code>
- *
- * @return an error or <code>null</code>
- */
- public Throwable getError();
-
- /**
- * Returns <code>true</code> if no {@link #getError() error} is set and if
- * the {@link #getStatusCode() status code} is one of the 2xx codes.
- */
- public boolean isSuccessful();
-
- // ---------- ChangeLog ----------------------------------------------------
-
- /**
- * Records a 'created' change
- *
- * @param path path of the item that was created
- */
- public void onCreated(String path);
-
- /**
- * Records a 'modified' change
- *
- * @param path path of the item that was modified
- */
- public void onModified(String path);
-
- /**
- * Records a 'deleted' change
- *
- * @param path path of the item that was deleted
- */
- public void onDeleted(String path);
-
- /**
- * Records a 'moved' change.
- * <p/>
- * Note: the moved change only records the basic move command. the implied
- * changes on the moved properties and sub nodes are not recorded.
- *
- * @param srcPath source path of the node that was moved
- * @param dstPath destination path of the node that was moved.
- */
- public void onMoved(String srcPath, String dstPath);
-
- /**
- * Records a 'copied' change.
- * <p/>
- * Note: the copy change only records the basic copy command. the implied
- * changes on the copied properties and sub nodes are not recorded.
- *
- * @param srcPath source path of the node that was copied
- * @param dstPath destination path of the node that was copied.
- */
- public void onCopied(String srcPath, String dstPath);
-
- /**
- * Records a generic change of the given <code>type</code> with arguments.
- *
- * @param type The type of the modification
- * @param arguments The arguments to the modifications
- */
- void onChange(String type, String... arguments);
-
- /**
- * Writes the response back over the provided HTTP channel. The actual
- * format of the response is implementation dependent.
- *
- * @param response to send to
- * @param setStatus whether to set the status code on the response
- * @throws IOException if an i/o exception occurs
- */
- void send(HttpServletResponse response, boolean setStatus)
- throws IOException;
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/PostResponseCreator.java b/post/src/main/java/org/apache/sling/servlets/post/PostResponseCreator.java
deleted file mode 100644
index 84ccc96..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/PostResponseCreator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-
-/**
- * Service interface which allows for alternate implementations of the
- * PostResponse interface to be created as needed.
- *
- */
-public interface PostResponseCreator {
- PostResponse createPostResponse(SlingHttpServletRequest req);
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/PostResponseWithErrorHandling.java b/post/src/main/java/org/apache/sling/servlets/post/PostResponseWithErrorHandling.java
deleted file mode 100644
index 92bf6b5..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/PostResponseWithErrorHandling.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingHttpServletRequest;
-
-@Component
-@Service
-public class PostResponseWithErrorHandling implements PostResponseCreator{
-
- public PostResponse createPostResponse(SlingHttpServletRequest request) {
- if (isSendError(request)) {
- return new HtmlResponse() {
-
- @Override
- protected void doSend(HttpServletResponse response) throws IOException {
- if (!this.isSuccessful()) {
- response.sendError(this.getStatusCode(), this.getError().toString());
- return;
- }else{
- super.doSend(response);
- }
- }
- };
- }else{
- return null;
- }
- }
-
- protected boolean isSendError(SlingHttpServletRequest request){
- boolean sendError=false;
- String sendErrorParam=request.getParameter(SlingPostConstants.RP_SEND_ERROR);
- if (sendErrorParam!=null && "true".equalsIgnoreCase(sendErrorParam)){
- sendError=true;
- }
- return sendError;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java b/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
deleted file mode 100644
index e837d20..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * 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;
-
-/**
- * The <code>SlingPostConstants</code> interface provides constants for well
- * known parameters of the core SlingPostServlet. Extensions of the servlet
- * through implementations of the {@link SlingPostOperation} interface may
- * extend this constants.
- */
-public interface SlingPostConstants {
-
- /**
- * Prefix for parameter names which control this POST (RP_ stands for
- * "request param") (value is ":"). This prefix must be used on all request
- * parameters which have significance to POST request processing. Such
- * parameters will not be used to denote properties to be written to the
- * repository.
- */
- public static final String RP_PREFIX = ":";
-
- /**
- * The name of the parameter containing the operation to execute (value is
- * ":operation"). If this parameter is missing or empty, the request is
- * assumed to be a request to create new content or to modify existing
- * content.
- */
- public static final String RP_OPERATION = RP_PREFIX + "operation";
-
- /**
- * The suffix to the resource path used to indicate to automatically
- * generate the name of the new item to create during a content creation
- * request (value is "/").
- */
- public static final String DEFAULT_CREATE_SUFFIX = "/";
-
- /**
- * An alternative suffix to the resource path used to indicate to
- * automatically generate the name of the new item to create during a
- * content creation request (value is "/*").
- */
- public static final String STAR_CREATE_SUFFIX = "/*";
-
- /**
- * Name of the predefined modify operation (value is "modify").
- * <p>
- * The modify operation uses the remaining request parameters to indicate
- * nodes and properties to create.
- * <p>
- * The modify operation is actually chosen by the Sling POST Servlet if the
- * request has no {@link #RP_OPERATION} request parameter.
- *
- * @since 2.0.6 (Bundle version 2.0.6)
- */
- public static final String OPERATION_MODIFY = "modify";
-
- /**
- * Name of the predefined delete operation (value is "delete").
- * <p>
- * The delete operation requires no further request parameters and just
- * deletes the content addressed by the request.
- * <p>
- * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
- * parameter are deleted instead of the request resource.
- */
- public static final String OPERATION_DELETE = "delete";
-
- /**
- * Name of the predefined copy operation (value is "copy").
- * <p>
- * The copy operation requires the {@link #RP_DEST} request parameter
- * denoting the path to copy the content to. In addition the
- * {@link #RP_ORDER} parameter may be defined to specificy to relative node
- * order of the destination node. Finally the {@link #RP_REPLACE} parameter
- * may be set to indicate whether an existing item at the destination should
- * be replaced or not.
- * <p>
- * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
- * parameter are copied instead of the request resource.
- */
- public static final String OPERATION_COPY = "copy";
-
- /**
- * Name of the predefined move operation (value is "move")
- * <p>
- * The move operation requires the {@link #RP_DEST} request parameter
- * denoting the path to move the content to. In addition the
- * {@link #RP_ORDER} parameter may be defined to specificy to relative node
- * order of the destination node. Finally the {@link #RP_REPLACE} parameter
- * may be set to indicate whether an existing item at the destination should
- * be replaced or not.
- * <p>
- * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
- * parameter are moved instead of the request resource.
- */
- public static final String OPERATION_MOVE = "move";
-
- /**
- * Name of the predefined null operation (value is "nop").
- * <p>
- * The null operation is a pseudo operation, which has no effects
- * whatsoever except setting the response status. The null operation may
- * be accompanied with the {@link #RP_NOP_STATUS} parameter to indicate
- * the actual response status to set and the {@link #RP_STATUS} parameter
- * to indicate how to send the actual response status.
- */
- public static final String OPERATION_NOP = "nop";
-
- /**
- * Name of the predefined checkin operation (value is "checkin").
- * <p>
- * The checkin operation requires no further request parameters and just
- * checks in the content addressed by the request.
- * <p>
- * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
- * parameter are checked in instead of the request resource.
- */
- public static final String OPERATION_CHECKIN = "checkin";
-
- /**
- * Name of the predefined checkout operation (value is "checkout").
- * <p>
- * The checkout operation requires no further request parameters and just
- * checks out the content addressed by the request.
- * <p>
- * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
- * parameter are checked out instead of the request resource.
- */
- public static final String OPERATION_CHECKOUT = "checkout";
-
- /**
- * Name of the predefined restore operation (value is "restore").
- * <p>
- * The restore operation requires the {@link #RP_VERSION} request parameter
- * denoting the name or the label of the version to be restored.
- * <p>
- * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
- * parameter are restored instead of the request resource. The
- * {@link #RP_REMOVE_EXISTING} parameter may be set to true to force
- * the operation even if there is a collision.
- */
- public static final String OPERATION_RESTORE = "restore";
-
- /**
- * Name of the predefined import operation (value is "import").
- *
- * <p>
- * The import operation requires either the {@link #RP_CONTENT} and {@link #RP_CONTENT_TYPE}
- * request parameters or the {@link #RP_CONTENT_FILE} request parameter.
- * Finally the {@link #RP_REPLACE} parameter may be set to indicate whether
- * an existing item at the destination should be overwritten or not.
- */
- public static final String OPERATION_IMPORT = "import";
-
- /**
- * Name of the request parameter used to indicate the resource to apply the
- * operation to (value is ":applyTo").
- * <p>
- * This property is used by certain opertaions - namely
- * {@link #OPERATION_COPY}, {@link #OPERATION_DELETE} and
- * {@link #OPERATION_MOVE} - to apply the operation to multiple resources
- * instead of the request resource.
- */
- public static final String RP_APPLY_TO = RP_PREFIX + "applyTo";
-
- /**
- * Name of the request parameter used to indicate the destination for the
- * copy and move operations (value is ":dest"). This request parameter is
- * required by the copy and move operations.
- */
- public static final String RP_DEST = RP_PREFIX + "dest";
-
- /**
- * Name of the request parameter indicating whether the destination for a
- * copy or move operation is to be replaced if existing (value is
- * ":replace"). Copy or move is only possible if the destination exists if
- * the replace parameter is set to the case-insignificant value true.
- *
- * This request parameter is also used to indicate whether the destination node
- * for an import operation is to be replaced if existing. The parameter value is
- * checked to see if it matches the case-insignificant value true.
- */
- public static final String RP_REPLACE = RP_PREFIX + "replace";
-
- /**
- * Name of the request parameter indicating whether the destination for a
- * property change during an import operation is to be replaced if existing.
- * The parameter value is checked to see if it matches the case-insignificant
- * value true.
- */
- public static final String RP_REPLACE_PROPERTIES = RP_PREFIX + "replaceProperties";
-
- /**
- * Optional request parameter indicating the order of newly created nodes in
- * creation, copy and move operation requests (value is ":order").
- * <p>
- * The value of this parameter may be {@link #ORDER_FIRST},
- * {@link #ORDER_BEFORE}, {@link #ORDER_AFTER}, {@link #ORDER_LAST} or a
- * numberic value indicating the absolute position in the child list of the
- * parent node.
- */
- public static final String RP_ORDER = RP_PREFIX + "order";
-
- /**
- * Name of the request parameter indicating whether the nodes existing
- * outside the versioning graph should be removed. See
- * {@link javax.jcr.version.VersionManager#restore(javax.jcr.version.Version, boolean)
- * VersionManager#restore()} for more info.
- * <p>
- * This request parameter is optional and can be used by the {@link #OPERATION_RESTORE}.
- */
- public static final String RP_REMOVE_EXISTING = RP_PREFIX + "removeExisting";
-
- /**
- * Name of the request parameter indicating the name or the label of the
- * resource version. This request parameter is required by the
- * {@link #OPERATION_RESTORE}.
- */
- public static final String RP_VERSION = RP_PREFIX + "version";
-
- /**
- * Possible value of the {@link #RP_ORDER} parameter indicating that the
- * node by moved to the first position amongst its sibblings (value is
- * "first").
- */
- public static final String ORDER_FIRST = "first";
-
- /**
- * Possible value of the {@link #RP_ORDER} parameter indicating that the
- * node by moved immediately before the sibbling whose name is contained in
- * the {@link #RP_ORDER} parameter (value is "before ").
- */
- public static final String ORDER_BEFORE = "before ";
-
- /**
- * Possible value of the {@link #RP_ORDER} parameter indicating that the
- * node by moved immediately after the sibbling whose name is contained in
- * the {@link #RP_ORDER} parameter (value is "after ").
- */
- public static final String ORDER_AFTER = "after ";
-
- /**
- * Possible value of the {@link #RP_ORDER} parameter indicating that the
- * node by moved to the last position amongst its sibblings (value is
- * "last").
- */
- public static final String ORDER_LAST = "last";
-
- /**
- * Optional request paramter specifying a node name for a newly created node
- * (value is ":name").
- */
- public static final String RP_NODE_NAME = RP_PREFIX + "name";
-
- /**
- * Optional request paramter specifying a node name hint for a newly created
- * node (value is ":nameHint").
- */
- public static final String RP_NODE_NAME_HINT = RP_PREFIX + "nameHint";
-
- /**
- * Prefix for properties addressing repository items with an absolute path
- * (value is "/").
- *
- * @see #ITEM_PREFIX_RELATIVE_CURRENT
- */
- public static final String ITEM_PREFIX_ABSOLUTE = "/";
-
- /**
- * Prefix for properties addressing repository items with a path relative to
- * the current request item (value is "./").
- * <p>
- * When collecting parameters addressing repository items for modification,
- * the parameters are first scanned to see whether there is a parameter with
- * this relative path prefix. If such a parameter exists, the modification
- * operations only assumes parameters whose name is prefixes with this
- * prefix or the {@link #ITEM_PREFIX_ABSOLUTE} or the
- * {@link #ITEM_PREFIX_RELATIVE_PARENT} to be parameters addressing
- * properties to modify. Otherwise, that is if no parameter starts with this
- * prefix, all parameters not starting with the
- * {@link #RP_PREFIX command prefix} are considered addressing properties to
- * modify.
- */
- public static final String ITEM_PREFIX_RELATIVE_CURRENT = "./";
-
- /**
- * Prefix for properties addressing repository items with a path relative to
- * the parent of the request item (value is "../").
- *
- * @see #ITEM_PREFIX_RELATIVE_CURRENT
- */
- public static final String ITEM_PREFIX_RELATIVE_PARENT = "../";
-
- /**
- * Optional request parameter: redirect to the specified URL after POST
- */
- public static final String RP_REDIRECT_TO = RP_PREFIX + "redirect";
-
- /**
- * Optional request parameter: define how the response is sent back to the
- * client. Supported values for this property are
- * {@link #STATUS_VALUE_BROWSER} and {@link #STATUS_VALUE_STANDARD}. The
- * default is to assume {@link #STATUS_VALUE_STANDARD} if the parameter is
- * 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.
- * The parameter value is checked to see if it matches the case-insensitive
- * value true.
- *
- * @since 2.2.0 (Bundle version 2.3.0)
- */
- public static final String RP_SEND_ERROR = RP_PREFIX + "sendError";
-
- /**
- * The supported value for the {@link #RP_STATUS} request parameter
- * requesting to report success or failure of request processing using
- * standard HTTP status codes. This value is assumed as the default value
- * for the {@link #RP_STATUS} parameter if the parameter is missing or not
- * any of the two supported values.
- *
- * @see #RP_STATUS
- * @see #STATUS_VALUE_BROWSER
- */
- public static final String STATUS_VALUE_STANDARD = "standard";
-
- /**
- * The supported value for the {@link #RP_STATUS} request parameter
- * requesting to not report success or failure of request processing using
- * standard HTTP status codes but instead alwas set the status to 200/OK and
- * only report the real success or failure status in the XHTML response.
- *
- * @see #RP_STATUS
- * @see #STATUS_VALUE_STANDARD
- */
- public static final String STATUS_VALUE_BROWSER = "browser";
-
- /**
- * Optional request parameter to indicate the actual response status to
- * send back as a result of calling the #OPERATION_NOP (value is ":nopstatus").
- * <p>
- * This parameter is expected to be single-valued and by an integer being a
- * valid HTTP status code. If this parameter is missing or the parameter
- * value cannot be converted to a HTTP status code (integer in the range
- * [100..999]), the default status code 200/OK is returned.
- *
- * @see #OPERATION_NOP
- * @see #RP_STATUS
- */
- public static final String RP_NOP_STATUS = RP_PREFIX + "nopstatus";
-
- /**
- * The default response status sent back by a {@link #OPERATION_NOP} if the
- * {@link #RP_NOP_STATUS} parameter is not provided or the parameter value
- * cannot be converted into a valid response status code (value is 200).
- *
- * @see #RP_NOP_STATUS
- */
- public static final int NOPSTATUS_VALUE_DEFAULT = 200;
-
- /**
- * Optional request parameter: if provided, added at the end of the computed
- * (or supplied) redirect URL
- */
- public static final String RP_DISPLAY_EXTENSION = RP_PREFIX
- + "displayExtension";
-
- /**
- * SLING-130, suffix that maps form field names to different JCR property
- * names
- */
- public static final String VALUE_FROM_SUFFIX = "@ValueFrom";
-
- /**
- * Suffix indicating a type hint for the property (value is "@TypeHint").
- */
- public static final String TYPE_HINT_SUFFIX = "@TypeHint";
-
- /**
- * Suffix indicating a default value for a property (value is
- * "@DefaultValue").
- */
- public static final String DEFAULT_VALUE_SUFFIX = "@DefaultValue";
-
- /**
- * Suffix indicating that the named property is to be removed before
- * applying any new content (value is "@Delete").
- */
- public static final String SUFFIX_DELETE = "@Delete";
-
- /**
- * Suffix indicating that the named item is to be set from an item whose
- * absolute or relative path is given in the parameter's value (value is
- * "@MoveFrom").
- * <p>
- * This suffix is similar to the {@link #VALUE_FROM_SUFFIX} in that the
- * value for the item is not taken from the request parameter itself but
- * from somewhere else. In this case the value is set by moving another
- * repository item (in the same workspace) to the location addressed by the
- * parameter.
- */
- public static final String SUFFIX_MOVE_FROM = "@MoveFrom";
-
- /**
- * Suffix indicating that the named item is to be set from an item whose
- * absolute or relative path is given in the parameter's value (value is
- * "@CopyFrom").
- * <p>
- * This suffix is similar to the {@link #VALUE_FROM_SUFFIX} in that the
- * value for the item is not taken from the request parameter itself but
- * from somewhere else. In this case the value is set by copying another
- * repository item (in the same workspace) to the location addressed by the
- * parameter.
- */
- public static final String SUFFIX_COPY_FROM = "@CopyFrom";
-
- /**
- * Suffix indicating that blank value or values for this property will be
- * ignored.
- */
- public static final String SUFFIX_IGNORE_BLANKS = "@IgnoreBlanks";
-
- /**
- * Suffix indicating that the default value should be used when the property
- * is not defined. By default the default value is only used when the property
- * is defined, but blank (i.e. an empty form field). With this suffix, the
- * default value will also be used if the property isn't provided at all. This is
- * useful for HTML checkboxes.
- */
- public static final String SUFFIX_USE_DEFAULT_WHEN_MISSING = "@UseDefaultWhenMissing";
-
- /**
- * Suffix indicating that a multi-value property is to be handled as an
- * ordered set and the sent values start with either "+" or "-" to indicate
- * wether a value should be added to or removed from the set.
- * <p>
- * If a property is marked to be patched with this suffix only properties
- * whose value start with {@link #PATCH_ADD +} or {@link #PATCH_REMOVE -}
- * are considered. Other values are ignored.
- *
- * @see #PATCH_ADD
- * @see #PATCH_REMOVE
- */
- public static final String SUFFIX_PATCH = "@Patch";
-
- /**
- * Indicates a value to be added to the named multi-value property if the
- * property is being #{@link #SUFFIX_PATCH patched}.
- * <p>
- * If the given value
- * already exists amongst the values of the multi-value properties it is
- * not added.
- */
- public static final char PATCH_ADD = '+';
-
- /**
- * Indicates a value to be removed from the named multi-value property if
- * the property is being #{@link #SUFFIX_PATCH patched}.
- * <p>
- * If the given value exists multiple times amongst the values of the
- * multi-value properties all occurrences are removed.
- */
- public static final char PATCH_REMOVE = '-';
-
- /**
- * Name of the request parameter containing the content to be imported
- * by the 'import' operation.
- */
- public static final String RP_CONTENT = RP_PREFIX + "content";
-
- /**
- * Name of the request parameter containing the content type of the content
- * to be imported by the 'import' operation.
- */
- public static final String RP_CONTENT_TYPE = RP_PREFIX + "contentType";
-
- /**
- * Name of the request parameter containing the file to be imported
- * by the 'import' operation.
- */
- public static final String RP_CONTENT_FILE = RP_PREFIX + "contentFile";
-
- /**
- * Name of the request parameter indicating whether versionable nodes should
- * be checked in during an {@link SlingPostConstants#OPERATION_IMPORT} operation.
- */
- public static final String RP_CHECKIN = RP_PREFIX + "checkin";
-
- /**
- * 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.
- *
- * @since 2.1.2
- */
- public static final String ATTR_SKIP_SESSION_HANDLING = "skip-session-handling";
-
- /**
- * Name of the request parameter indicating offset of the chunk in request.
- * @since 2.3.4
- */
- public static final String SUFFIX_OFFSET = "@Offset";
-
- /**
- * Name of the request parameter indicating length of complete file.
- * @since 2.3.4
- */
- public static final String SUFFIX_LENGTH = "@Length";
-
- /**
- * Name of the request parameter indicating request contains last chunk
- * and as a result upload should be finished. It is useful in scenarios
- * like file streaming where file size is not known in advance.
- * @since 2.3.4
- */
- public static final String SUFFIX_COMPLETED = "@Completed";
-
- /**
- * Name of the request parameter indicating request operation is applicable
- * to chunks.
- * @since 2.3.4
- */
- public static final String RP_APPLY_TO_CHUNKS = RP_PREFIX + "applyToChunks";
-
- /**
- * Constant for the sling:chunks mixin. Used to identify that node
- * contains chunks.
- * @since 2.3.4
- */
- public static final String NT_SLING_CHUNK_MIXIN = "sling:chunks";
-
- /**
- * Constant for the sling:fileLength property. The property stores file
- * length.
- * @since 2.3.4
- */
- public static final String NT_SLING_FILE_LENGTH = "sling:fileLength";
-
- /**
- * Constant for the sling:length property. The property stores
- * cumulative length of all uploaded chunks.
- * @since 2.3.4
- */
- public static final String NT_SLING_CHUNKS_LENGTH = "sling:length";
-
- /**
- * Constant for the sling:chunk node type. The node type is used
- * to store chunk.
- * @since 2.3.4
- */
- public static final String NT_SLING_CHUNK_NODETYPE = "sling:chunk";
-
- /**
- * Constant for the sling:offset property. The property stores start
- * offset of chunk.
- * @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
- */
- public static final String CHUNK_NODE_NAME = "chunk";
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/SlingPostOperation.java b/post/src/main/java/org/apache/sling/servlets/post/SlingPostOperation.java
deleted file mode 100644
index 4d430cb..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/SlingPostOperation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.servlets.HtmlResponse;
-
-/**
- * The <code>SlingPostOperation</code> interface defines the service API to be
- * implemented by service providers extending the Sling default POST servlet.
- * Service providers may register OSGi services of this type to be used by the
- * Sling default POST servlet to handle specific operations.
- * <p>
- * The <code>SlingPostOperation</code> service must be registered with a
- * {@link #PROP_OPERATION_NAME} registration property giving the name(s) of the
- * operations supported by the service. The names will be used to find the
- * actual operation from the {@link SlingPostConstants#RP_OPERATION
- * <code>:operation</code>} request parameter.
- * <p>
- * The Sling default POST servlet defines the <code>copy</code>,
- * <code>move</code> and <code>delete</code> operation names. These names should
- * not be used by <code>SlingPostOperation</code> service providers.
- *
- * @deprecated as of 2.0.8 (Bundle version 2.2.0) and replaced by
- * {@link PostOperation}.
- */
-@Deprecated
-public interface SlingPostOperation {
-
- /**
- * The name of the Sling POST operation service.
- */
- public static final String SERVICE_NAME = "org.apache.sling.servlets.post.SlingPostOperation";
-
- /**
- * The name of the service registration property indicating the name(s) of
- * the operation provided by the operation implementation (value is
- * "sling.post.operation"). The value of this service property must be a
- * single String or an array or <code>java.util.Collection</code> of
- * Strings. If multiple strings are defined, the service is registered for
- * all operation names.
- */
- public static final String PROP_OPERATION_NAME = "sling.post.operation";
-
- /**
- * Executes the operation provided by this service implementation. This
- * method is called by the Sling default POST servlet.
- *
- * @param request The <code>SlingHttpServletRequest</code> object providing
- * the request input for the operation.
- * @param response The <code>HtmlResponse</code> into which the operation
- * steps should be recorded.
- * @param processors The {@link SlingPostProcessor} services to be called
- * after applying the operation. This may be <code>null</code> if
- * there are none.
- * @throws org.apache.sling.api.resource.ResourceNotFoundException May be
- * thrown if the operation requires an existing request
- * resource. If this exception is thrown the Sling default POST
- * servlet sends back a <code>404/NOT FOUND</code> response to
- * the client.
- * @throws org.apache.sling.api.SlingException May be thrown if an error
- * occurrs running the operation.
- */
- void run(SlingHttpServletRequest request, HtmlResponse response,
- SlingPostProcessor[] processors);
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/SlingPostProcessor.java b/post/src/main/java/org/apache/sling/servlets/post/SlingPostProcessor.java
deleted file mode 100644
index eedb68f..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/SlingPostProcessor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-
-/**
- * The <code>SlingPostProcessor</code> interface defines a service API to be
- * implemented by service providers extending the Sling default POST servlet.
- * Service providers may register OSGi services of this type to be used by the
- * Sling default POST servlet to handle specific operations.
- * <p>
- * During a request the <code>SlingPostOperation</code> service is called
- * with a list of registered post processors. After the operation has performed
- * its changes but before the changes are persistet, all post processors
- * are called.
- */
-public interface SlingPostProcessor {
-
- /**
- * Process the current request.
- * The post processor can inspect the list of changes and perform additional
- * changes. If the processor performs a change it should make the change
- * and add a {@link Modification} object to the changes list.
- * @param request The current request.
- * @param changes The list of changes for this request.
- */
- void process(SlingHttpServletRequest request, List<Modification> changes)
- throws Exception;
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java b/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java
deleted file mode 100644
index fd64e3b..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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;
-
-
-/**
- * Data structure to hold the various options associated with how versionable
- * nodes are handled in the post servlet.
- */
-public class VersioningConfiguration implements Cloneable {
-
- private boolean autoCheckout = false;
-
- private boolean checkinOnNewVersionableNode = false;
-
- private boolean autoCheckin = true;
-
- @Override
- public VersioningConfiguration clone() {
- VersioningConfiguration cfg = new VersioningConfiguration();
- cfg.checkinOnNewVersionableNode = checkinOnNewVersionableNode;
- cfg.autoCheckout = autoCheckout;
- cfg.autoCheckin = autoCheckin;
- return cfg;
- }
-
- public boolean isAutoCheckout() {
- return autoCheckout;
- }
-
- public boolean isCheckinOnNewVersionableNode() {
- return checkinOnNewVersionableNode;
- }
-
- public boolean isAutoCheckin() {
- return autoCheckin;
- }
-
- public void setAutoCheckin(boolean autoCheckin) {
- this.autoCheckin = autoCheckin;
- }
-
- public void setAutoCheckout(boolean autoCheckout) {
- this.autoCheckout = autoCheckout;
- }
-
- public void setCheckinOnNewVersionableNode(boolean checkinOnNewVersionableNode) {
- this.checkinOnNewVersionableNode = checkinOnNewVersionableNode;
- }
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/PostOperationProxyProvider.java b/post/src/main/java/org/apache/sling/servlets/post/impl/PostOperationProxyProvider.java
deleted file mode 100644
index cfe7728..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/PostOperationProxyProvider.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.servlets.HtmlResponse;
-import org.apache.sling.servlets.post.PostOperation;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.SlingPostOperation;
-import org.apache.sling.servlets.post.SlingPostProcessor;
-import org.apache.sling.servlets.post.impl.helper.HtmlResponseProxy;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>PostOperationProxyProvider</code> listens for legacy
- * {@link SlingPostOperation} services being registered and wraps them with a
- * proxy for the new {@link PostOperation} API and registers the procies.
- */
-@Component(specVersion = "1.1", metatype = false)
-public class PostOperationProxyProvider implements ServiceListener {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- /**
- * The service listener filter to listen for SlingPostOperation services
- */
- private static final String REFERENCE_FILTER = "(" + Constants.OBJECTCLASS
- + "=" + SlingPostOperation.SERVICE_NAME + ")";
-
- // maps references to the SlingPostOperation services to the registrations
- // of the PostOperation proxies for unregistration purposes
- private final Map<ServiceReference, ServiceRegistration> proxies = new IdentityHashMap<ServiceReference, ServiceRegistration>();
-
- // The DS component context to access the services to proxy
- private BundleContext bundleContext;
-
- // DS activation/deactivation
-
- /**
- * Activates the proxy provider component:
- * <ol>
- * <li>Keep BundleContext reference</li>
- * <li>Start listening for SlingPostOperation services</li>
- * <li>Register proxies for all existing SlingPostOperation services</li>
- * </ol>
- */
- @SuppressWarnings("unused")
- @Activate
- private void activate(final BundleContext bundleContext) {
- this.bundleContext = bundleContext;
-
- try {
- bundleContext.addServiceListener(this, REFERENCE_FILTER);
- final ServiceReference[] serviceReferences = bundleContext.getServiceReferences(
- SlingPostOperation.SERVICE_NAME, null);
- if (serviceReferences != null) {
- for (ServiceReference serviceReference : serviceReferences) {
- register(serviceReference);
- }
- }
- } catch (InvalidSyntaxException ise) {
- // not expected for tested static filter
- // TODO:log !!
- }
- }
-
- /**
- * Deactivates the proxy provide component:
- * <ol>
- * <li>Unregister as a service listener</li>
- * <li>Unregister all proxies</li>
- * <li>Drop BundleContext reference</li>
- * </ol>
- */
- @SuppressWarnings("unused")
- @Deactivate
- private void deactivate() {
-
- this.bundleContext.removeServiceListener(this);
-
- final ServiceReference[] serviceReferences;
- synchronized (this.proxies) {
- serviceReferences = this.proxies.keySet().toArray(
- new ServiceReference[this.proxies.size()]);
- }
-
- for (ServiceReference serviceReference : serviceReferences) {
- unregister(serviceReference);
- }
-
- this.bundleContext = null;
- }
-
- // ServiceEvent handling
-
- public void serviceChanged(ServiceEvent event) {
-
- /*
- * There is a slight chance for a race condition on deactivation where
- * the component may be deactivating and the bundle context reference
- * has been removed but the framework is still sending service events.
- * In this situation we don't want to handle the event any way and so we
- * can safely ignore it
- */
- if (this.bundleContext == null) {
- return;
- }
-
- switch (event.getType()) {
- case ServiceEvent.REGISTERED:
- register(event.getServiceReference());
- break;
- case ServiceEvent.MODIFIED:
- update(event.getServiceReference());
- break;
- case ServiceEvent.UNREGISTERING:
- unregister(event.getServiceReference());
- break;
- }
- }
-
- /**
- * Access SlingPostOperation service and register proxy.
- * <p>
- * Called by serviceChanged
- */
- private void register(final ServiceReference serviceReference) {
- final SlingPostOperation service = (SlingPostOperation) this.bundleContext.getService(serviceReference);
- final PostOperationProxy proxy = new PostOperationProxy(service);
-
- final BundleContext bundleContext = serviceReference.getBundle().getBundleContext();
- final Dictionary<String, Object> props = copyServiceProperties(serviceReference);
- final ServiceRegistration reg = bundleContext.registerService(
- PostOperation.SERVICE_NAME, proxy, props);
-
- log.debug("Registering {}", proxy);
- synchronized (this.proxies) {
- this.proxies.put(serviceReference, reg);
- }
- }
-
- /**
- * Update proxy service registration properties
- * <p>
- * Called by serviceChanged
- */
- private void update(final ServiceReference serviceReference) {
- final ServiceRegistration proxyRegistration;
- synchronized (this.proxies) {
- proxyRegistration = this.proxies.get(serviceReference);
- }
-
- if (proxyRegistration != null) {
- log.debug("Updating {}", proxyRegistration);
- proxyRegistration.setProperties(copyServiceProperties(serviceReference));
- }
- }
-
- /**
- * Unregister proxy and unget SlingPostOperation service
- * <p>
- * Called by serviceChanged
- */
- private void unregister(final ServiceReference serviceReference) {
- final ServiceRegistration proxyRegistration;
- synchronized (this.proxies) {
- proxyRegistration = this.proxies.remove(serviceReference);
- }
-
- if (proxyRegistration != null) {
- log.debug("Unregistering {}", proxyRegistration);
- this.bundleContext.ungetService(serviceReference);
- proxyRegistration.unregister();
- }
- }
-
- // Helpers
-
- /**
- * Creates a Dictionary for use as the service registration properties of
- * the PostOperation proxy.
- */
- private Dictionary<String, Object> copyServiceProperties(
- final ServiceReference serviceReference) {
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- for (String key : serviceReference.getPropertyKeys()) {
- props.put(key, serviceReference.getProperty(key));
- }
- props.put(PostOperation.PROP_OPERATION_NAME,
- serviceReference.getProperty(SlingPostOperation.PROP_OPERATION_NAME));
- props.put(Constants.SERVICE_DESCRIPTION, "Proxy for "
- + serviceReference);
- return props;
- }
-
- /**
- * The <code>PostOperationProxy</code> is the proxy implementing the
- * {@link PostOperation} service interface by calling the
- * {@link SlingPostOperation} service.
- */
- private class PostOperationProxy implements PostOperation {
-
- private final SlingPostOperation delegatee;
-
- PostOperationProxy(final SlingPostOperation delegatee) {
- this.delegatee = delegatee;
- }
-
- public String toString() {
- return getClass().getSimpleName() + " for " + delegatee.getClass().getName();
- }
-
- public void run(SlingHttpServletRequest request, PostResponse response,
- SlingPostProcessor[] processors) {
- HtmlResponse apiResponse = new HtmlResponseProxy(response);
- delegatee.run(request, apiResponse, processors);
- }
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java b/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
deleted file mode 100644
index 5ff76c0..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.References;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.resource.ResourceNotFoundException;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.servlets.SlingAllMethodsServlet;
-import org.apache.sling.commons.osgi.OsgiUtil;
-import org.apache.sling.jcr.contentloader.ContentImporter;
-import org.apache.sling.servlets.post.HtmlResponse;
-import org.apache.sling.servlets.post.JSONResponse;
-import org.apache.sling.servlets.post.NodeNameGenerator;
-import org.apache.sling.servlets.post.PostOperation;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.PostResponseCreator;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.SlingPostOperation;
-import org.apache.sling.servlets.post.SlingPostProcessor;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-import org.apache.sling.servlets.post.impl.helper.DateParser;
-import org.apache.sling.servlets.post.impl.helper.DefaultNodeNameGenerator;
-import org.apache.sling.servlets.post.impl.helper.MediaRangeList;
-import org.apache.sling.servlets.post.impl.operations.CheckinOperation;
-import org.apache.sling.servlets.post.impl.operations.CheckoutOperation;
-import org.apache.sling.servlets.post.impl.operations.CopyOperation;
-import org.apache.sling.servlets.post.impl.operations.DeleteOperation;
-import org.apache.sling.servlets.post.impl.operations.ImportOperation;
-import org.apache.sling.servlets.post.impl.operations.ModifyOperation;
-import org.apache.sling.servlets.post.impl.operations.MoveOperation;
-import org.apache.sling.servlets.post.impl.operations.NopOperation;
-import org.apache.sling.servlets.post.impl.operations.RestoreOperation;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * POST servlet that implements the sling client library "protocol"
- */
-@Component(immediate = true, specVersion = "1.1", metatype = true, label = "%servlet.post.name", description = "%servlet.post.description")
-@Service(value = Servlet.class)
-@org.apache.felix.scr.annotations.Properties({
- @Property(name = "service.description", value = "Sling Post Servlet"),
- @Property(name = "service.vendor", value = "The Apache Software Foundation"),
- @Property(name = "sling.servlet.prefix", intValue = -1, propertyPrivate = true),
- @Property(name = "sling.servlet.paths", value = "sling/servlet/default/POST", propertyPrivate = true) })
-@References({
- @Reference(name = "postProcessor", referenceInterface = SlingPostProcessor.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = "postOperation", referenceInterface = PostOperation.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = "nodeNameGenerator", referenceInterface = NodeNameGenerator.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = "postResponseCreator", referenceInterface = PostResponseCreator.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = "contentImporter", referenceInterface = ContentImporter.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC) })
-public class SlingPostServlet extends SlingAllMethodsServlet {
-
- private static final long serialVersionUID = 1837674988291697074L;
-
- /**
- * default log
- */
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Property({ "EEE MMM dd yyyy HH:mm:ss 'GMT'Z", "ISO8601",
- "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd",
- "dd.MM.yyyy HH:mm:ss", "dd.MM.yyyy" })
- private static final String PROP_DATE_FORMAT = "servlet.post.dateFormats";
-
- @Property({ "title", "jcr:title", "name", "description",
- "jcr:description", "abstract", "text", "jcr:text" })
- private static final String PROP_NODE_NAME_HINT_PROPERTIES = "servlet.post.nodeNameHints";
-
- @Property(intValue = 20)
- private static final String PROP_NODE_NAME_MAX_LENGTH = "servlet.post.nodeNameMaxLength";
-
- private static final boolean DEFAULT_CHECKIN_ON_CREATE = false;
-
- @Property(boolValue = DEFAULT_CHECKIN_ON_CREATE)
- private static final String PROP_CHECKIN_ON_CREATE = "servlet.post.checkinNewVersionableNodes";
-
- private static final boolean DEFAULT_AUTO_CHECKOUT = false;
-
- @Property(boolValue = DEFAULT_AUTO_CHECKOUT)
- private static final String PROP_AUTO_CHECKOUT = "servlet.post.autoCheckout";
-
- private static final boolean DEFAULT_AUTO_CHECKIN = true;
-
- @Property(boolValue = DEFAULT_AUTO_CHECKIN)
- private static final String PROP_AUTO_CHECKIN = "servlet.post.autoCheckin";
-
-
- private static final String PARAM_CHECKIN_ON_CREATE = ":checkinNewVersionableNodes";
-
- private static final String PARAM_AUTO_CHECKOUT = ":autoCheckout";
-
- private static final String PARAM_AUTO_CHECKIN = ":autoCheckin";
-
- private static final String DEFAULT_IGNORED_PARAMETER_NAME_PATTERN = "j_.*";
-
- @Property(value = DEFAULT_IGNORED_PARAMETER_NAME_PATTERN)
- private static final String PROP_IGNORED_PARAMETER_NAME_PATTERN = "servlet.post.ignorePattern";
-
- private final ModifyOperation modifyOperation = new ModifyOperation();
-
- private ServiceRegistration[] internalOperations;
-
- /** Map of post operations. */
- private final Map<String, PostOperation> postOperations = new HashMap<String, PostOperation>();
-
- /** Sorted list of post processor holders. */
- private final List<PostProcessorHolder> postProcessors = new ArrayList<PostProcessorHolder>();
-
- /** Cached list of post processors, used during request processing. */
- private SlingPostProcessor[] cachedPostProcessors = new SlingPostProcessor[0];
-
- /** Sorted list of node name generator holders. */
- private final List<NodeNameGeneratorHolder> nodeNameGenerators = new ArrayList<NodeNameGeneratorHolder>();
-
- /** Cached list of node name generators used during request processing. */
- private NodeNameGenerator[] cachedNodeNameGenerators = new NodeNameGenerator[0];
-
- /** Sorted list of post response creator holders. */
- private final List<PostResponseCreatorHolder> postResponseCreators = new ArrayList<PostResponseCreatorHolder>();
-
- /** Cached array of post response creators used during request processing. */
- private PostResponseCreator[] cachedPostResponseCreators = new PostResponseCreator[0];
-
- private final ImportOperation importOperation = new ImportOperation();
-
- /**
- * The content importer reference.
- */
- private ContentImporter contentImporter;
-
- private VersioningConfiguration baseVersioningConfiguration;
-
- @Override
- protected void doPost(final SlingHttpServletRequest request,
- final SlingHttpServletResponse response) throws IOException {
- final VersioningConfiguration localVersioningConfig = createRequestVersioningConfiguration(request);
-
- request.setAttribute(VersioningConfiguration.class.getName(), localVersioningConfig);
-
- // prepare the response
- final PostResponse htmlResponse = createPostResponse(request);
- htmlResponse.setReferer(request.getHeader("referer"));
-
- final PostOperation operation = getSlingPostOperation(request);
- if (operation == null) {
-
- htmlResponse.setStatus(
- HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
- "Invalid operation specified for POST request");
-
- } else {
- request.getRequestProgressTracker().log(
- "Calling PostOperation: {0}", operation.getClass().getName());
- final SlingPostProcessor[] processors = this.cachedPostProcessors;
- try {
- operation.run(request, htmlResponse, processors);
- } catch (ResourceNotFoundException rnfe) {
- htmlResponse.setStatus(HttpServletResponse.SC_NOT_FOUND,
- rnfe.getMessage());
- } catch (final Exception exception) {
- log.warn("Exception while handling POST "
- + request.getResource().getPath() + " with "
- + operation.getClass().getName(), exception);
- htmlResponse.setError(exception);
- }
-
- }
-
- // check for redirect URL if processing succeeded
- if (htmlResponse.isSuccessful()) {
- if (redirectIfNeeded(request, htmlResponse, response)) {
- return;
- }
- }
-
- // create a html response and send if unsuccessful or no redirect
- htmlResponse.send(response, isSetStatus(request));
- }
-
- /**
- * Redirects the HttpServletResponse, if redirectURL is not empty
- * @param htmlResponse
- * @param request
- * @param redirectURL The computed redirect URL
- * @param response The HttpServletResponse to use for redirection
- * @return Whether a redirect was requested
- * @throws IOException
- */
- boolean redirectIfNeeded(final SlingHttpServletRequest request, final PostResponse htmlResponse, final SlingHttpServletResponse response)
- throws IOException {
- final String redirectURL = getRedirectUrl(request, htmlResponse);
- if (redirectURL != null) {
- final Matcher m = REDIRECT_WITH_SCHEME_PATTERN.matcher(redirectURL);
- final boolean hasScheme = m.matches();
- final String encodedURL;
- if (hasScheme && m.group(2).length() > 0) {
- encodedURL = m.group(1) + response.encodeRedirectURL(m.group(2));
- } else if (hasScheme) {
- encodedURL = redirectURL;
- } else {
- log.debug("Request path is [{}]", request.getPathInfo());
- encodedURL = response.encodeRedirectURL(redirectURL);
- }
- log.debug("redirecting to URL [{}] - encoded as [{}]", redirectURL, encodedURL);
- response.sendRedirect(encodedURL);
- return true;
- }
- return false;
- }
- private static final Pattern REDIRECT_WITH_SCHEME_PATTERN = Pattern.compile("^(https?://[^/]+)(.*)$");
-
- /**
- * Creates an instance of a PostResponse.
- * @param req The request being serviced
- * @return a {@link org.apache.sling.servlets.post.impl.helper.JSONResponse} if any of these conditions are true:
- * <ul>
- * <li> the request has an <code>Accept</code> header of <code>application/json</code></li>
- * <li>the request is a JSON POST request (see SLING-1172)</li>
- * <li>the request has a request parameter <code>:accept=application/json</code></li>
- * </ul>
- * or a {@link org.apache.sling.api.servlets.PostResponse} otherwise
- */
- PostResponse createPostResponse(final SlingHttpServletRequest req) {
- for (final PostResponseCreator creator : cachedPostResponseCreators) {
- final PostResponse response = creator.createPostResponse(req);
- if (response != null) {
- return response;
- }
- }
-
- // Fall through to default behavior
- @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
- final MediaRangeList mediaRangeList = new MediaRangeList(req);
- if (JSONResponse.RESPONSE_CONTENT_TYPE.equals(mediaRangeList.prefer("text/html", JSONResponse.RESPONSE_CONTENT_TYPE))) {
- return new JSONResponse();
- } else {
- return new HtmlResponse();
- }
- }
-
- private PostOperation getSlingPostOperation(
- final SlingHttpServletRequest request) {
- final String operation = request.getParameter(SlingPostConstants.RP_OPERATION);
- if (operation == null || operation.length() == 0) {
- // standard create/modify operation;
- return modifyOperation;
- }
-
- // named operation, retrieve from map
- synchronized ( this.postOperations ) {
- return postOperations.get(operation);
- }
- }
-
- /**
- * compute redirect URL (SLING-126)
- *
- * @param ctx the post processor
- * @return the redirect location or <code>null</code>
- */
- protected String getRedirectUrl(final SlingHttpServletRequest request, final PostResponse ctx) {
- // redirect param has priority (but see below, magic star)
- String result = request.getParameter(SlingPostConstants.RP_REDIRECT_TO);
- if (result != null) {
- try {
- URI redirectUri = new URI(result);
- if (redirectUri.getAuthority() != null) {
- // if it has a host information
- log.warn("redirect target ({}) does include host information ({}). This is not allowed for security reasons!", result, redirectUri.getAuthority());
- return null;
- }
- } catch (URISyntaxException e) {
- log.warn("given redirect target ({}) is not a valid uri: {}", result, e);
- return null;
- }
-
- log.debug("redirect requested as [{}] for path [{}]", result, ctx.getPath());
-
- // redirect to created/modified Resource
- final int star = result.indexOf('*');
- if (star >= 0 && ctx.getPath() != null) {
- final StringBuilder buf = new StringBuilder();
-
- // anything before the star
- if (star > 0) {
- buf.append(result.substring(0, star));
- }
-
- // append the name of the manipulated node
- buf.append(ResourceUtil.getName(ctx.getPath()));
-
- // anything after the star
- if (star < result.length() - 1) {
- buf.append(result.substring(star + 1));
- }
-
- // Prepend request path if it ends with create suffix and result isn't absolute
- final String requestPath = request.getPathInfo();
- if (requestPath.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX) && buf.charAt(0) != '/' &&
- !REDIRECT_WITH_SCHEME_PATTERN.matcher(buf).matches()) {
- buf.insert(0, requestPath);
- }
-
- // use the created path as the redirect result
- result = buf.toString();
-
- } else if (result.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX)) {
- // if the redirect has a trailing slash, append modified node
- // name
- result = result.concat(ResourceUtil.getName(ctx.getPath()));
- }
-
- log.debug("Will redirect to {}", result);
- }
- return result;
- }
-
- protected boolean isSetStatus(final SlingHttpServletRequest request) {
- final String statusParam = request.getParameter(SlingPostConstants.RP_STATUS);
- if (statusParam == null) {
- log.debug(
- "getStatusMode: Parameter {} not set, assuming standard status code",
- SlingPostConstants.RP_STATUS);
- return true;
- }
-
- if (SlingPostConstants.STATUS_VALUE_BROWSER.equals(statusParam)) {
- log.debug(
- "getStatusMode: Parameter {} asks for user-friendly status code",
- SlingPostConstants.RP_STATUS);
- return false;
- }
-
- if (SlingPostConstants.STATUS_VALUE_STANDARD.equals(statusParam)) {
- log.debug(
- "getStatusMode: Parameter {} asks for standard status code",
- SlingPostConstants.RP_STATUS);
- return true;
- }
-
- log.debug(
- "getStatusMode: Parameter {} set to unknown value {}, assuming standard status code",
- SlingPostConstants.RP_STATUS);
- return true;
- }
-
- // ---------- SCR Integration ----------------------------------------------
-
- @Activate
- protected void activate(final ComponentContext context,
- final Map<String, Object> configuration) {
- // configure now
- this.configure(configuration);
-
- // other predefined operations
- final ArrayList<ServiceRegistration> providedServices = new ArrayList<ServiceRegistration>();
- final BundleContext bundleContext = context.getBundleContext();
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_MODIFY, modifyOperation));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_COPY, new CopyOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_MOVE, new MoveOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_DELETE, new DeleteOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_NOP, new NopOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_CHECKIN, new CheckinOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_CHECKOUT, new CheckoutOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_RESTORE, new RestoreOperation()));
- providedServices.add(registerOperation(bundleContext,
- SlingPostConstants.OPERATION_IMPORT, importOperation));
-
- internalOperations = providedServices.toArray(new ServiceRegistration[providedServices.size()]);
- }
-
- private ServiceRegistration registerOperation(final BundleContext context,
- final String opCode, final PostOperation operation) {
- final Properties properties = new Properties();
- properties.put(PostOperation.PROP_OPERATION_NAME, opCode);
- properties.put(Constants.SERVICE_DESCRIPTION,
- "Apache Sling POST Servlet Operation " + opCode);
- properties.put(Constants.SERVICE_VENDOR,
- context.getBundle().getHeaders().get(Constants.BUNDLE_VENDOR));
- return context.registerService(PostOperation.SERVICE_NAME, operation,
- properties);
- }
-
- @Override
- public void init() throws ServletException {
- modifyOperation.setServletContext(getServletContext());
- }
-
- @Modified
- private void configure(final Map<String, Object> configuration) {
- this.baseVersioningConfiguration = createBaseVersioningConfiguration(configuration);
-
- final DateParser dateParser = new DateParser();
- final String[] dateFormats = OsgiUtil.toStringArray(configuration.get(PROP_DATE_FORMAT));
- for (String dateFormat : dateFormats) {
- try {
- dateParser.register(dateFormat);
- } catch (Throwable t) {
- log.warn(
- "configure: Ignoring DateParser format {} because it is invalid: {}",
- dateFormat, t);
- }
- }
-
- final String[] nameHints = OsgiUtil.toStringArray(configuration.get(PROP_NODE_NAME_HINT_PROPERTIES));
- final int nameMax = (int) OsgiUtil.toLong(
- configuration.get(PROP_NODE_NAME_MAX_LENGTH), -1);
- final NodeNameGenerator nodeNameGenerator = new DefaultNodeNameGenerator(
- nameHints, nameMax);
-
- final String paramMatch = OsgiUtil.toString(
- configuration.get(PROP_IGNORED_PARAMETER_NAME_PATTERN),
- DEFAULT_IGNORED_PARAMETER_NAME_PATTERN);
- final Pattern paramMatchPattern = Pattern.compile(paramMatch);
-
- this.modifyOperation.setDateParser(dateParser);
- this.modifyOperation.setDefaultNodeNameGenerator(nodeNameGenerator);
- this.importOperation.setDefaultNodeNameGenerator(nodeNameGenerator);
- this.modifyOperation.setIgnoredParameterNamePattern(paramMatchPattern);
- this.importOperation.setIgnoredParameterNamePattern(paramMatchPattern);
- }
-
- @Override
- public void destroy() {
- modifyOperation.setServletContext(null);
- }
-
- @Deactivate
- protected void deactivate() {
- if (internalOperations != null) {
- for (final ServiceRegistration registration : internalOperations) {
- registration.unregister();
- }
- internalOperations = null;
- }
- modifyOperation.setExtraNodeNameGenerators(null);
- importOperation.setExtraNodeNameGenerators(null);
- importOperation.setContentImporter(null);
- }
-
- /**
- * Bind a new post operation
- */
- protected void bindPostOperation(final PostOperation operation, final Map<String, Object> properties) {
- final String operationName = (String) properties.get(SlingPostOperation.PROP_OPERATION_NAME);
- if ( operationName != null && operation != null ) {
- synchronized (this.postOperations) {
- this.postOperations.put(operationName, operation);
- }
- }
- }
-
- /**
- * Unbind a post operation
- */
- protected void unbindPostOperation(final PostOperation operation, final Map<String, Object> properties) {
- final String operationName = (String) properties.get(SlingPostOperation.PROP_OPERATION_NAME);
- if ( operationName != null ) {
- synchronized (this.postOperations) {
- this.postOperations.remove(operationName);
- }
- }
- }
-
- /**
- * Bind a new post processor
- */
- protected void bindPostProcessor(final SlingPostProcessor processor, final Map<String, Object> properties) {
- final PostProcessorHolder pph = new PostProcessorHolder();
- pph.processor = processor;
- pph.ranking = OsgiUtil.toInteger(properties.get(Constants.SERVICE_RANKING), 0);
-
- synchronized ( this.postProcessors ) {
- int index = 0;
- while ( index < this.postProcessors.size() &&
- pph.ranking < this.postProcessors.get(index).ranking ) {
- index++;
- }
- if ( index == this.postProcessors.size() ) {
- this.postProcessors.add(pph);
- } else {
- this.postProcessors.add(index, pph);
- }
- this.updatePostProcessorCache();
- }
- }
-
- /**
- * Unbind a post processor
- */
- protected void unbindPostProcessor(final SlingPostProcessor processor, final Map<String, Object> properties) {
- synchronized ( this.postProcessors ) {
- final Iterator<PostProcessorHolder> i = this.postProcessors.iterator();
- while ( i.hasNext() ) {
- final PostProcessorHolder current = i.next();
- if ( current.processor == processor ) {
- i.remove();
- }
- }
- this.updatePostProcessorCache();
- }
- }
-
- /**
- * Update the post processor cache
- * This method is called by sync'ed methods, no need to add additional syncing.
- */
- private void updatePostProcessorCache() {
- final SlingPostProcessor[] localCache = new SlingPostProcessor[this.postProcessors.size()];
- int index = 0;
- for(final PostProcessorHolder current : this.postProcessors) {
- localCache[index] = current.processor;
- index++;
- }
- this.cachedPostProcessors = localCache;
- }
-
- /**
- * Bind a new node name generator
- */
- protected void bindNodeNameGenerator(final NodeNameGenerator generator, final Map<String, Object> properties) {
- final NodeNameGeneratorHolder nngh = new NodeNameGeneratorHolder();
- nngh.generator = generator;
- nngh.ranking = OsgiUtil.toInteger(properties.get(Constants.SERVICE_RANKING), 0);
-
- synchronized ( this.nodeNameGenerators ) {
- int index = 0;
- while ( index < this.nodeNameGenerators.size() &&
- nngh.ranking < this.nodeNameGenerators.get(index).ranking ) {
- index++;
- }
- if ( index == this.nodeNameGenerators.size() ) {
- this.nodeNameGenerators.add(nngh);
- } else {
- this.nodeNameGenerators.add(index, nngh);
- }
- this.updateNodeNameGeneratorCache();
- }
- }
-
- /**
- * Unbind a node name generator
- */
- protected void unbindNodeNameGenerator(final NodeNameGenerator generator, final Map<String, Object> properties) {
- synchronized ( this.nodeNameGenerators ) {
- final Iterator<NodeNameGeneratorHolder> i = this.nodeNameGenerators.iterator();
- while ( i.hasNext() ) {
- final NodeNameGeneratorHolder current = i.next();
- if ( current.generator == generator ) {
- i.remove();
- }
- }
- this.updateNodeNameGeneratorCache();
- }
- }
-
- /**
- * Update the node name generator cache
- * This method is called by sync'ed methods, no need to add additional syncing.
- */
- private void updateNodeNameGeneratorCache() {
- final NodeNameGenerator[] localCache = new NodeNameGenerator[this.nodeNameGenerators.size()];
- int index = 0;
- for(final NodeNameGeneratorHolder current : this.nodeNameGenerators) {
- localCache[index] = current.generator;
- index++;
- }
- this.cachedNodeNameGenerators = localCache;
- this.modifyOperation.setExtraNodeNameGenerators(this.cachedNodeNameGenerators);
- this.importOperation.setExtraNodeNameGenerators(this.cachedNodeNameGenerators);
- }
-
- /**
- * Bind a new post response creator
- */
- protected void bindPostResponseCreator(final PostResponseCreator creator, final Map<String, Object> properties) {
- final PostResponseCreatorHolder nngh = new PostResponseCreatorHolder();
- nngh.creator = creator;
- nngh.ranking = OsgiUtil.toInteger(properties.get(Constants.SERVICE_RANKING), 0);
-
- synchronized ( this.postResponseCreators ) {
- int index = 0;
- while ( index < this.postResponseCreators.size() &&
- nngh.ranking < this.postResponseCreators.get(index).ranking ) {
- index++;
- }
- if ( index == this.postResponseCreators.size() ) {
- this.postResponseCreators.add(nngh);
- } else {
- this.postResponseCreators.add(index, nngh);
- }
- this.updatePostResponseCreatorCache();
- }
- }
-
- /**
- * Unbind a post response creator
- */
- protected void unbindPostResponseCreator(final PostResponseCreator creator, final Map<String, Object> properties) {
- synchronized ( this.postResponseCreators ) {
- final Iterator<PostResponseCreatorHolder> i = this.postResponseCreators.iterator();
- while ( i.hasNext() ) {
- final PostResponseCreatorHolder current = i.next();
- if ( current.creator == creator ) {
- i.remove();
- }
- }
- this.updatePostResponseCreatorCache();
- }
- }
-
- /**
- * Update the post response creator cache
- * This method is called by sync'ed methods, no need to add additional syncing.
- */
- private void updatePostResponseCreatorCache() {
- final PostResponseCreator[] localCache = new PostResponseCreator[this.postResponseCreators.size()];
- int index = 0;
- for(final PostResponseCreatorHolder current : this.postResponseCreators) {
- localCache[index] = current.creator;
- index++;
- }
- this.cachedPostResponseCreators = localCache;
- }
-
- protected void bindContentImporter(final ContentImporter importer) {
- this.contentImporter = importer;
- importOperation.setContentImporter(importer);
- }
-
- protected void unbindContentImporter(final ContentImporter importer) {
- if ( this.contentImporter == importer ) {
- this.contentImporter = null;
- importOperation.setContentImporter(null);
- }
- }
-
- private VersioningConfiguration createBaseVersioningConfiguration(Map<?, ?> props) {
- VersioningConfiguration cfg = new VersioningConfiguration();
- cfg.setCheckinOnNewVersionableNode(OsgiUtil.toBoolean(
- props.get(PROP_CHECKIN_ON_CREATE), DEFAULT_CHECKIN_ON_CREATE));
- cfg.setAutoCheckout(OsgiUtil.toBoolean(
- props.get(PROP_AUTO_CHECKOUT), DEFAULT_AUTO_CHECKOUT));
- cfg.setAutoCheckin(OsgiUtil.toBoolean(
- props.get(PROP_AUTO_CHECKIN), DEFAULT_AUTO_CHECKIN));
- return cfg;
- }
-
- private VersioningConfiguration createRequestVersioningConfiguration(SlingHttpServletRequest request) {
- VersioningConfiguration cfg = baseVersioningConfiguration.clone();
-
- String paramValue = request.getParameter(PARAM_CHECKIN_ON_CREATE);
- if (paramValue != null) {
- cfg.setCheckinOnNewVersionableNode(Boolean.parseBoolean(paramValue));
- }
- paramValue = request.getParameter(PARAM_AUTO_CHECKOUT);
- if (paramValue != null) {
- cfg.setAutoCheckout(Boolean.parseBoolean(paramValue));
- }
- paramValue = request.getParameter(PARAM_AUTO_CHECKIN);
- if (paramValue != null) {
- cfg.setAutoCheckin(Boolean.parseBoolean(paramValue));
- }
- return cfg;
- }
-
- private static final class PostProcessorHolder {
- public SlingPostProcessor processor;
- public int ranking;
- }
-
- private static final class NodeNameGeneratorHolder {
- public NodeNameGenerator generator;
- public int ranking;
- }
-
- private static final class PostResponseCreatorHolder {
- public PostResponseCreator creator;
- public int ranking;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/Chunk.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/Chunk.java
deleted file mode 100644
index 148a14f..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/Chunk.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.helper;
-
-/**
- * <code>Chunk</code> enscapsulates all chunk upload attributes.
- *
- * @since 2.3.4
- */
-public class Chunk {
-
- private long offset;
-
- private long length;
-
- private boolean completed;
-
- /**
- * Return offset of the chunk.
- */
- public long getOffset() {
- return offset;
- }
-
- /**
- * Set offset value.
- */
- public void setOffsetValue(long offset) {
- this.offset = offset;
- }
-
- /**
- * Return length of the file parameter.
- */
- public long getLength() {
- return length;
- }
-
- /**
- * Set length of file parameter.
- */
- public void setLength(long length) {
- this.length = length;
- }
-
- /**
- * Return true if request contains last chunk as a result upload should be
- * finished. It is useful in scenarios where file streaming where file size
- * is not known in advance.
- */
- public boolean isCompleted() {
- return completed;
- }
-
- /**
- * Set complete flag
- */
- public void setCompleted(boolean complete) {
- this.completed = complete;
- }
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ChunkCleanUpTask.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ChunkCleanUpTask.java
deleted file mode 100644
index ea46e8b..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ChunkCleanUpTask.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.helper;
-
-import java.util.Map;
-
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.OsgiUtil;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>ChunkCleanUpTask</code> implements a job run at regular intervals
- * to find incomplete chunk uploads and remove them from the repository to
- * prevent littering the repository with incomplete chunks.
- * <p>
- * This task is configured with OSGi configuration for the PID
- * <code>org.apache.sling.servlets.post.impl.helper.ChunkCleanUpTask</code> with
- * property <code>scheduler.expression</code> being the schedule to execute the
- * task. The schedule is a cron job expression as described at <a
- * href="http://www.docjar.com/docs/api/org/quartz/CronTrigger.html">Cron
- * Trigger</a> with the default value configured to run twice a day at 0h41m31s
- * and 12h4131s.
- * <p>
- * The property <code>chunk.cleanup.age</code> specifies chunk's age in minutes
- * before it is considered for clean up.
- * <p>
- * Currently the cleanup tasks connects as the administrative user to the
- * default workspace assuming users are stored in that workspace and the
- * administrative user has full access.
- */
-@Component(metatype = true, label = "Apache Sling Post Chunk Upload : Cleanup Task", description = "Task to regularly purge incomplete chunks from the repository")
-@Service(value = Runnable.class)
-@Properties({
- @Property(name = "scheduler.expression", value = "31 41 0/12 * * ?", label = "Schedule", description = "Cron expression scheudling this job. Default is hourly 17m23s after the hour. "
- + "See http://www.docjar.com/docs/api/org/quartz/CronTrigger.html for a description "
- + "of the format for this value."),
- @Property(name = "service.description", value = "Periodic Chunk Cleanup Job", propertyPrivate = true),
- @Property(name = "service.vendor", value = "The Apache Software Foundation", propertyPrivate = true) })
-public class ChunkCleanUpTask implements Runnable {
-
- /** default log */
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Reference
- private SlingRepository repository;
-
- @Property(intValue = 360, description = "The chunk's age in minutes before it is considered for clean up.")
- private static final String CHUNK_CLEANUP_AGE = "chunk.cleanup.age";
-
- private SlingFileUploadHandler uploadhandler = new SlingFileUploadHandler();
-
- /**
- * Clean up age criterion in millisec.
- */
- private long chunkCleanUpAge;
-
- /**
- * Executes the job. Is called for each triggered schedule point.
- */
- public void run() {
- log.debug("ChunkCleanUpTask: Starting cleanup");
- cleanup();
- }
-
- /**
- * This method deletes chunks which are {@link #isEligibleForCleanUp(Node)}
- * for cleanup. It queries all
- * {@link SlingPostConstants#NT_SLING_CHUNK_MIXIN} nodes and filter nodes
- * which are {@link #isEligibleForCleanUp(Node)} for cleanup. It then
- * deletes old chunks upload.
- */
- private void cleanup() {
-
- long start = System.currentTimeMillis();
-
- int numCleaned = 0;
- int numLive = 0;
-
- Session admin = null;
- try {
- // assume chunks are stored in the default workspace
- admin = repository.loginAdministrative(null);
- QueryManager qm = admin.getWorkspace().getQueryManager();
-
- QueryResult queryres = qm.createQuery(
- "SELECT * FROM [sling:chunks] ", Query.JCR_SQL2).execute();
- NodeIterator nodeItr = queryres.getNodes();
- while (nodeItr.hasNext()) {
- Node node = nodeItr.nextNode();
- if (isEligibleForCleanUp(node)) {
- numCleaned++;
- uploadhandler.deleteChunks(node);
- } else {
- numLive++;
- }
- }
- if (admin.hasPendingChanges()) {
- try {
- admin.refresh(true);
- admin.save();
- } catch (InvalidItemStateException iise) {
- log.info("ChunkCleanUpTask: Concurrent modification to one or more of the chunk to be removed. Retrying later");
- } catch (RepositoryException re) {
- log.info("ChunkCleanUpTask: Failed persisting chunk removal. Retrying later");
- }
- }
-
- } catch (Throwable t) {
- log.error(
- "ChunkCleanUpTask: General failure while trying to cleanup chunks",
- t);
- } finally {
- if (admin != null) {
- admin.logout();
- }
- }
- long end = System.currentTimeMillis();
- log.info(
- "ChunkCleanUpTask finished: Removed {} chunk upload(s) in {}ms ({} chunk upload(s) still active)",
- new Object[] { numCleaned, (end - start), numLive });
- }
-
- /**
- * Check if {@link Node} is eligible of
- * {@link SlingPostConstants#NT_SLING_CHUNK_NODETYPE} cleanup. To be
- * eligible the age of last
- * {@link SlingPostConstants#NT_SLING_CHUNK_NODETYPE} uploaded should be
- * greater than @link {@link #chunkCleanUpAge}
- *
- * @param node {@link Node} containing
- * {@link SlingPostConstants#NT_SLING_CHUNK_NODETYPE}
- * {@link Node}s
- * @return true if eligible else false.
- * @throws RepositoryException
- */
- private boolean isEligibleForCleanUp(Node node) throws RepositoryException {
- Node lastChunkNode = uploadhandler.getLastChunk(node);
- return lastChunkNode != null
- && (System.currentTimeMillis() - lastChunkNode.getProperty(
- javax.jcr.Property.JCR_CREATED).getDate().getTimeInMillis()) > chunkCleanUpAge;
- }
-
- @Activate
- protected void activate(final ComponentContext context,
- final Map<String, Object> configuration) {
- chunkCleanUpAge = OsgiUtil.toInteger(
- configuration.get(CHUNK_CLEANUP_AGE), 1) * 60 * 1000;
- log.info("scheduler config [{}], chunkGarbageTime [{}] ms",
- OsgiUtil.toString(configuration.get("scheduler.expression"), ""),
- chunkCleanUpAge);
-
- }
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DateParser.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DateParser.java
deleted file mode 100644
index 913c6c6..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DateParser.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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.helper;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-
-import org.apache.jackrabbit.util.ISO8601;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Takes a string representation of a time-date string and tries for parse it
- * using different formats.
- */
-public class DateParser {
-
- /**
- * default log
- */
- private static final Logger log = LoggerFactory.getLogger(DateParser.class);
-
- /**
- * lits of formats
- */
- private final List<CalendarParserSupport> formats = new LinkedList<CalendarParserSupport>();
-
- /**
- * Registers a format string to the list of internally checked ones.
- * Uses the {@link SimpleDateFormat}.
- * @param format format as in {@link SimpleDateFormat}
- * @throws IllegalArgumentException if the format is not valid.
- */
- public void register(String format) {
- final CalendarParserSupport parser;
- if (Iso8601ParserSupport.FORMAT_MARKER.equalsIgnoreCase(format)) {
- parser = new Iso8601ParserSupport();
- } else {
- parser = new SimpleDateFormatParserSupport(format);
- }
- formats.add(parser);
- }
-
- /**
- * Parses the given source string and returns the respective calendar
- * instance. If no format matches returns <code>null</code>.
- * <p/>
- * Note: method is synchronized because SimpleDateFormat is not.
- *
- * @param source date time source string
- * @return calendar representation of the source or <code>null</code>
- */
- public synchronized Calendar parse(String source) {
- for (CalendarParserSupport fmt : formats) {
- try {
- final Calendar c = fmt.parse(source);
- if (log.isDebugEnabled()) {
- log.debug("Parsed " + source + " using " + fmt + " into "
- + c);
- }
- return c;
- } catch (ParseException e) {
- if (log.isDebugEnabled()) {
- log.debug("Failed parsing " + source + " using " + fmt);
- }
- }
- }
- return null;
- }
-
- /**
- * Parses the given source strings and returns the respective calendar
- * instances. If no format matches for any of the sources
- * returns <code>null</code>.
- * <p/>
- * Note: method is synchronized because SimpleDateFormat is not.
- *
- * @param sources date time source strings
- * @return calendar representations of the source or <code>null</code>
- */
- public synchronized Calendar[] parse(String sources[]) {
- Calendar ret[] = new Calendar[sources.length];
- for (int i=0; i< sources.length; i++) {
- if ((ret[i] = parse(sources[i])) == null) {
- return null;
- }
- }
- return ret;
- }
-
- /**
- * Parses the given source strings and returns the respective jcr date value
- * instances. If no format matches for any of the sources
- * returns <code>null</code>.
- * <p/>
- * Note: method is synchronized because SimpleDateFormat is not.
- *
- * @param sources date time source strings
- * @param factory the value factory
- * @return jcr date value representations of the source or <code>null</code>
- */
- public synchronized Value[] parse(String sources[], ValueFactory factory) {
- Value ret[] = new Value[sources.length];
- for (int i=0; i< sources.length; i++) {
- Calendar c = parse(sources[i]);
- if (c == null) {
- return null;
- }
- ret[i] = factory.createValue(c);
- }
- return ret;
- }
-
- private static interface CalendarParserSupport {
- Calendar parse(String dateTime) throws ParseException;
- }
-
- private static class SimpleDateFormatParserSupport implements CalendarParserSupport {
- private final SimpleDateFormat dateFormat;
-
- SimpleDateFormatParserSupport(String format) {
- this.dateFormat = new SimpleDateFormat(format, Locale.US);
- }
-
- public Calendar parse(String dateTime) throws ParseException {
- final Date d;
- synchronized (dateFormat) {
- d = dateFormat.parse(dateTime);
- }
-
- final Calendar c = Calendar.getInstance();
- c.setTime(d);
-
- return c;
- }
-
- @Override
- public String toString() {
- return "SimpleDateFormat:" + dateFormat.toPattern();
- }
- }
-
- private static class Iso8601ParserSupport implements CalendarParserSupport {
-
- static final String FORMAT_MARKER = "ISO8601";
-
- public Calendar parse(String dateTime) throws ParseException {
- try {
- final Calendar c = ISO8601.parse(dateTime);
- if (c == null) {
- throw new ParseException(dateTime
- + " cannot be parsed as ISO8601 formatted date string",
- 0);
- }
- return c;
- } catch (Exception e) {
- throw new ParseException(e.getMessage(), 0);
- }
- }
-
- @Override
- public String toString() {
- return "ISO8601 Parser";
- }
- }
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java
deleted file mode 100644
index 2fcd926..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/DefaultNodeNameGenerator.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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.helper;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.request.RequestParameter;
-import org.apache.sling.api.request.RequestParameterMap;
-import org.apache.sling.servlets.post.NodeNameGenerator;
-import org.apache.sling.servlets.post.SlingPostConstants;
-
-/**
- * Generates a node name based on a set of well-known request parameters
- * like title, description, etc.
- * See SLING-128.
- */
-public class DefaultNodeNameGenerator implements NodeNameGenerator {
-
- private final String[] parameterNames;
- private final NodeNameFilter filter = new NodeNameFilter();
-
- public static final int DEFAULT_MAX_NAME_LENGTH = 20;
-
- private int maxLength = DEFAULT_MAX_NAME_LENGTH;
- private int counter;
-
- public DefaultNodeNameGenerator() {
- this(null, -1);
- }
-
- public DefaultNodeNameGenerator(String[] parameterNames, int maxNameLength) {
- if (parameterNames == null) {
- this.parameterNames = new String[0];
- } else {
- this.parameterNames = parameterNames;
- }
-
- this.maxLength = (maxNameLength > 0)
- ? maxNameLength
- : DEFAULT_MAX_NAME_LENGTH;
- }
-
- /**
- * Get a "nice" node name, if possible, based on given request
- *
- * @param request the request
- * @param basePath the base path
- * @param requirePrefix <code>true</code> if the parameter names for
- * properties requires a prefix
- * @param defaultNodeNameGenerator a default generator
- * @return a nice node name
- */
- public String getNodeName(SlingHttpServletRequest request, String basePath,
- boolean requirePrefix, NodeNameGenerator defaultNodeNameGenerator) {
- RequestParameterMap parameters = request.getRequestParameterMap();
- String valueToUse = null;
- boolean doFilter = true;
-
- // find the first request parameter that matches one of
- // our parameterNames, in order, and has a value
- if (parameters!=null) {
- // we first check for the special sling parameters
- RequestParameter specialParam = parameters.getValue(SlingPostConstants.RP_NODE_NAME);
- if ( specialParam != null ) {
- if ( specialParam.getString() != null && specialParam.getString().length() > 0 ) {
- valueToUse = specialParam.getString();
- doFilter = false;
- }
- }
- if ( valueToUse == null ) {
- specialParam = parameters.getValue(SlingPostConstants.RP_NODE_NAME_HINT);
- if ( specialParam != null ) {
- if ( specialParam.getString() != null && specialParam.getString().length() > 0 ) {
- valueToUse = specialParam.getString();
- }
- }
- }
-
- if (valueToUse == null) {
- for (String param : parameterNames) {
- if (valueToUse != null) {
- break;
- }
- if (requirePrefix) {
- param = SlingPostConstants.ITEM_PREFIX_RELATIVE_CURRENT.concat(param);
- }
- final RequestParameter[] pp = parameters.get(param);
- if (pp != null) {
- for (RequestParameter p : pp) {
- valueToUse = p.getString();
- if (valueToUse != null && valueToUse.length() > 0) {
- break;
- }
- valueToUse = null;
- }
- }
- }
- }
- }
- String result;
- // should we filter?
- if (valueToUse != null) {
- if ( doFilter ) {
- // filter value so that it works as a node name
- result = filter.filter(valueToUse);
- } else {
- result = valueToUse;
- }
- } else {
- // default value if none provided
- result = nextCounter() + "_" + System.currentTimeMillis();
- }
-
- if ( doFilter ) {
- // max length
- if (result.length() > maxLength) {
- result = result.substring(0,maxLength);
- }
- }
-
- return result;
- }
-
- public synchronized int nextCounter() {
- return ++counter;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/HtmlPostResponseProxy.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/HtmlPostResponseProxy.java
deleted file mode 100644
index 6c967d0..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/HtmlPostResponseProxy.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.helper;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.servlets.HtmlResponse;
-import org.apache.sling.servlets.post.PostResponse;
-
-/**
- * The <code>HtmlPostResponseProxy</code> class implements the
- * {@link PostResponse} interface using a Sling API <code>HtmlResponse</code>.
- * <p>
- * This class is mainly used by the deprecated
- * {@link org.apache.sling.servlets.post.AbstractSlingPostOperation} for
- * bridging into the new
- * {@link org.apache.sling.servlets.post.AbstractPostOperation}.
- */
-public class HtmlPostResponseProxy implements PostResponse {
-
- private final HtmlResponse apiHtmlResponse;
-
- public HtmlPostResponseProxy(final HtmlResponse apiHtmlResponse) {
- this.apiHtmlResponse = apiHtmlResponse;
- }
-
- public HtmlResponse getHtmlResponse() {
- return apiHtmlResponse;
- }
-
- public Throwable getError() {
- return apiHtmlResponse.getError();
- }
-
- public String getLocation() {
- return apiHtmlResponse.getLocation();
- }
-
- public String getParentLocation() {
- return apiHtmlResponse.getParentLocation();
- }
-
- public String getPath() {
- return apiHtmlResponse.getPath();
- }
-
- public <Type> Type getProperty(String name, Class<Type> type) {
- return apiHtmlResponse.getProperty(name, type);
- }
-
- public Object getProperty(String name) {
- return apiHtmlResponse.getProperty(name);
- }
-
- public String getReferer() {
- return apiHtmlResponse.getReferer();
- }
-
- public int getStatusCode() {
- return apiHtmlResponse.getStatusCode();
- }
-
- public String getStatusMessage() {
- return apiHtmlResponse.getStatusMessage();
- }
-
- public boolean isCreateRequest() {
- return apiHtmlResponse.isCreateRequest();
- }
-
- public boolean isSuccessful() {
- return apiHtmlResponse.isSuccessful();
- }
-
- public void onChange(String type, String... arguments) {
- apiHtmlResponse.onChange(type, arguments);
- }
-
- public void onCopied(String srcPath, String dstPath) {
- apiHtmlResponse.onCopied(srcPath, dstPath);
- }
-
- public void onCreated(String path) {
- apiHtmlResponse.onCreated(path);
- }
-
- public void onDeleted(String path) {
- apiHtmlResponse.onDeleted(path);
- }
-
- public void onModified(String path) {
- apiHtmlResponse.onModified(path);
- }
-
- public void onMoved(String srcPath, String dstPath) {
- apiHtmlResponse.onMoved(srcPath, dstPath);
- }
-
- public void send(HttpServletResponse response, boolean setStatus)
- throws IOException {
- apiHtmlResponse.send(response, setStatus);
- }
-
- public void setCreateRequest(boolean isCreateRequest) {
- apiHtmlResponse.setCreateRequest(isCreateRequest);
- }
-
- public void setError(Throwable error) {
- apiHtmlResponse.setError(error);
- }
-
- public void setLocation(String location) {
- apiHtmlResponse.setLocation(location);
- }
-
- public void setParentLocation(String parentLocation) {
- apiHtmlResponse.setParentLocation(parentLocation);
- }
-
- public void setPath(String path) {
- apiHtmlResponse.setPath(path);
- }
-
- public void setProperty(String name, Object value) {
- apiHtmlResponse.setProperty(name, value);
- }
-
- public void setReferer(String referer) {
- apiHtmlResponse.setReferer(referer);
- }
-
- public void setStatus(int code, String message) {
- apiHtmlResponse.setStatus(code, message);
- }
-
- public void setTitle(String title) {
- apiHtmlResponse.setTitle(title);
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/HtmlResponseProxy.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/HtmlResponseProxy.java
deleted file mode 100644
index 492b9f0..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/HtmlResponseProxy.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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.helper;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.servlets.HtmlResponse;
-import org.apache.sling.servlets.post.PostResponse;
-
-/**
- * The <code>HtmlResponseProxy</code> extends the Sling API
- * <code>HtmlResponse</code> overwriting all public methods and redirecting to a
- * proxied {@link PostResponse}. As a consequence the underlying (extended)
- * Sling API <code>HtmlResponse</code> will not be fed with data and thus will
- * remain "empty".
- * <p>
- * This class is mainly used by the deprecated
- * {@link org.apache.sling.servlets.post.AbstractSlingPostOperation} for
- * bridging into the new
- * {@link org.apache.sling.servlets.post.AbstractPostOperation}.
- */
-public class HtmlResponseProxy extends HtmlResponse {
-
- private final PostResponse postResponse;
- private boolean createRequest;
-
- public HtmlResponseProxy(final PostResponse postResponse) {
- if(postResponse == null) {
- throw new IllegalArgumentException("Null PostResponse, cannot build HtmlResponseProxy");
- }
- this.postResponse = postResponse;
- postResponse.setCreateRequest(createRequest);
- }
-
- public PostResponse getPostResponse() {
- return postResponse;
- }
-
- public <Type> Type getProperty(String name, Class<Type> type) {
- // return postResponse.getProperty(name, type);
- return null;
- }
-
- public Object getProperty(String name) {
- // return postResponse.getProperty(name);
- return null;
- }
-
- public void setProperty(String name, Object value) {
- // postResponse.setProperty(name, value);
- }
-
- public Throwable getError() {
- return postResponse.getError();
- }
-
- public String getLocation() {
- return postResponse.getLocation();
- }
-
- public String getParentLocation() {
- return postResponse.getParentLocation();
- }
-
- public String getPath() {
- return postResponse.getPath();
- }
-
- public String getReferer() {
- return postResponse.getReferer();
- }
-
- public int getStatusCode() {
- return postResponse.getStatusCode();
- }
-
- public String getStatusMessage() {
- return postResponse.getStatusMessage();
- }
-
- public boolean isCreateRequest() {
- return postResponse.isCreateRequest();
- }
-
- public boolean isSuccessful() {
- return postResponse.isSuccessful();
- }
-
- public void onChange(String type, String... arguments) {
- postResponse.onChange(type, arguments);
- }
-
- public void onCopied(String srcPath, String dstPath) {
- postResponse.onCopied(srcPath, dstPath);
- }
-
- public void onCreated(String path) {
- postResponse.onCreated(path);
- }
-
- public void onDeleted(String path) {
- postResponse.onDeleted(path);
- }
-
- public void onModified(String path) {
- postResponse.onModified(path);
- }
-
- public void onMoved(String srcPath, String dstPath) {
- postResponse.onMoved(srcPath, dstPath);
- }
-
- public void send(HttpServletResponse response, boolean setStatus)
- throws IOException {
- postResponse.send(response, setStatus);
- }
-
- public void setCreateRequest(boolean isCreateRequest) {
- createRequest = isCreateRequest;
- if(postResponse != null) {
- // ugly...needed because of SLING-2453, this is called
- // by the base class's constructor before postResponse is set
- postResponse.setCreateRequest(isCreateRequest);
- }
- }
-
- public void setError(Throwable error) {
- postResponse.setError(error);
- }
-
- public void setLocation(String location) {
- postResponse.setLocation(location);
- }
-
- public void setParentLocation(String parentLocation) {
- postResponse.setParentLocation(parentLocation);
- }
-
- public void setPath(String path) {
- postResponse.setPath(path);
- }
-
- public void setReferer(String referer) {
- postResponse.setReferer(referer);
- }
-
- public void setStatus(int code, String message) {
- postResponse.setStatus(code, message);
- }
-
- public void setTitle(String title) {
- postResponse.setTitle(title);
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/MediaRangeList.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/MediaRangeList.java
deleted file mode 100644
index eedaa90..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/MediaRangeList.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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.helper;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Facilitates parsing of the Accept HTTP request header.
- * See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">RFC 2616 section 14.1</a>
- */
-public class MediaRangeList extends TreeSet<MediaRangeList.MediaRange> {
- public static final String HEADER_ACCEPT = "Accept";
- public static final String PARAM_ACCEPT = ":http-equiv-accept";
- public static final String WILDCARD = "*";
- boolean matchesAll = false;
-
- private static final Logger log = LoggerFactory.getLogger(MediaRangeList.class);
-
- /**
- * Constructs a <code>MediaRangeList</code> using information from the supplied <code>HttpServletRequest</code>.
- * if the request contains a {@link #PARAM_ACCEPT} query parameter, the query parameter value overrides any
- * {@link #HEADER_ACCEPT} header value.
- * If the request contains no {@link #PARAM_ACCEPT} parameter, or the parameter value is empty, the value of the
- * {@link #HEADER_ACCEPT} is used. If both values are missing, it is assumed that the client accepts all media types,
- * as per the RFC. See also {@link MediaRangeList#MediaRangeList(java.lang.String)}
- * @param request The <code>HttpServletRequest</code> to extract a <code>MediaRangeList</code> from
- */
- public MediaRangeList(HttpServletRequest request) {
- String queryParam = request.getParameter(PARAM_ACCEPT);
- if (queryParam != null && queryParam.trim().length() != 0) {
- init(queryParam);
- } else {
- init(request.getHeader(HEADER_ACCEPT));
- }
- }
-
- /**
- * Constructs a <code>MediaRangeList</code> using a list of media ranges specified in a <code>java.lang.String</code>.
- * The string is a comma-separated list of media ranges, as specified by the RFC.<br />
- * Examples:
- * <ul>
- * <li><code>text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5</code></li>
- * <li><code>text/html;q=0.8, application/json</code></li>
- * </ul>
- *
- * @param listStr The list of media range specifications
- */
- public MediaRangeList(String listStr) {
- try {
- init(listStr);
- } catch (Throwable t) {
- log.error("Error building MediaRangeList from '" + listStr + "' - will assume client accepts all media types", t);
- init(null);
- }
- }
-
- private void init(String headerValue) {
- if (headerValue == null || headerValue.trim().length() == 0) {
- // RFC 2616: "If no Accept header field is present,
- // then it is assumed that the client accepts all media types."
- this.matchesAll = true;
- this.add(new MediaRange(WILDCARD + "/" + WILDCARD));
- } else {
- String[] mediaTypes = headerValue.split(",");
- for (String type : mediaTypes) {
- try {
- MediaRange range = new MediaRange(type);
- this.add(range);
- if (range.matchesAll()) {
- this.matchesAll = true;
- }
- } catch (Throwable throwable) {
- log.warn("Error registering media type " + type, throwable);
- }
- }
- }
- }
-
- /**
- * Determines if this MediaRangeList contains a given media type.
- * @param mediaType A string on the form <code>type/subtype</code>. Neither <code>type</code>
- * or <code>subtype</code> should be wildcard (<code>*</code>).
- * @return <code>true</code> if this <code>MediaRangeList</code> contains a media type that matches
- * <code>mediaType</code>, <code>false</code> otherwise
- * @throws IllegalArgumentException if <code>mediaType</code> is not on an accepted form
- * @throws NullPointerException if <code>mediaType</code> is <code>null</code>
- */
- public boolean contains(String mediaType) {
- //noinspection SuspiciousMethodCalls
- MediaRange comp = new MediaRange(mediaType);
- return this.matchesAll || this.contains(comp);
- }
-
- /**
- * Given a list of media types, returns the one is preferred by this <code>MediaRangeList</code>.
- * @param mediaRanges An array of possible {@link org.apache.sling.servlets.post.impl.helper.MediaRangeList.MediaRange}s
- * @return One of the <code>mediaRanges</code> that this <code>MediaRangeList</code> prefers;
- * or <code>null</code> if this <code>MediaRangeList</code> does not contain any of the <code>mediaRanges</code>
- * @throws NullPointerException if <code>mediaRanges</code> is <code>null</code> or contains a <code>null</code> value
- */
- public MediaRange prefer(Set<MediaRange> mediaRanges) {
- for (MediaRange range : this) {
- for (MediaRange mediaType : mediaRanges) {
- if (range.equals(mediaType)) {
- return mediaType;
- }
- }
- }
- return null;
- }
-
- /**
- * Determines which of the <code>mediaRanges</code> specifiactions is prefered by this <code>MediaRangeList</code>.
- * @param mediaRanges String representations of <code>MediaRange</code>s. The strings must be
- * on the form required by {@link MediaRange#MediaRange(String)}
- * @see #prefer(java.util.Set)
- * @return the <code>toString</code> representation of the prefered <code>MediaRange</code>, or <code>null</code>
- * if this <code>MediaRangeList</code> does not contain any of the <code>mediaRanges</code>
- */
- public String prefer(String... mediaRanges) {
- Set<MediaRange> ranges = new HashSet<MediaRange>();
- for (String mediaRange : mediaRanges) {
- ranges.add(new MediaRange(mediaRange));
- }
- final MediaRange preferred = prefer(ranges);
- return(preferred == null ? null : preferred.toString());
- }
-
- /**
- * A code <code>MediaRange</code> represents an entry in a <code>MediaRangeList</code>.
- * The <code>MediaRange</code> consists of a <code>supertype</code> and a <code>subtype</code>,
- * optionally a quality factor parameter <code>q</code> and other arbitrary parameters.
- */
- public class MediaRange implements Comparable<MediaRange> {
- private String supertype;
- private double q = 1;
- private Map<String, String> parameters;
- private String subtype;
-
- /**
- * Constructs a <code>MediaRange</code> from a <code>String</code> expression.
- * @param exp The <code>String</code> to constuct the <code>MediaRange</code> from. The string is
- * expected to be on the form ( "*/*"
- * | ( type "/" "*" )
- * | ( type "/" subtype )
- * ) *( ";" parameter )<br/>
- * as specified by RFC 2616, section 14.1. <br/>
- * Examples:
- * <ul>
- * <li><code>text/html;q=0.8</code></li>
- * <li><code>text/html</code></li>
- * <li><code>text/html;level=3</code></li>
- * <li><code>text/html;level=3;q=0.7</code></li>
- * <li><code>text/*</code></li>
- * <li><code>*/*</code></li>
- * </ul>
- * Note that if the supertype component is wildcard (<code>*</code>), then the subtype component
- * must also be wildcard.<br />
- * The quality factor parameter must be between <code>0</code> and <code>1</code>, inclusive
- * (see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9">RFC 2616 section 3.9</a>).
- * If the expression does not contain a <code>q</code> parameter, the <code>MediaRange</code> is given
- * a default quality factor of <code>1</code>.
- * @throws IllegalArgumentException if <code>exp</code> can not be parsed to a valid media range
- * @throws NullPointerException if <code>exp</code> is <code>null</code>
- */
- public MediaRange(String exp) {
- String[] parts = exp.split(";");
- this.setType(parts[0].trim());
- if (parts.length > 1) {
- this.parameters = new HashMap<String, String>(parts.length - 1);
- }
- for (int i = 1, partsLength = parts.length; i < partsLength; i++) {
- String parameter = parts[i];
- String[] keyValue = parameter.split("=");
- if (keyValue[0].equals("q")) {
- this.q = Double.parseDouble(keyValue[1]);
- if (this.q < 0 || this.q > 1) {
- throw new IllegalArgumentException("Quality factor out of bounds: " + exp);
- }
- }
- this.parameters.put(keyValue[0], keyValue[1]);
- }
- }
-
- /**
- * Constructs a <code>MediaRange</code> of the given <code>supertype</code> and <code>subtype</code>.
- * The quality factor is given the default value of <code>1</code>.
- * @param supertype The super type of the media range
- * @param subtype The sub type of the media range
- */
- MediaRange(String supertype, String subtype) {
- this.setType(supertype, subtype);
- }
-
-
- /**
- * Returns <code>true</code> if this is a catch-all media range (<code>*/*</code>).
- * @return <code>true</code> if this range is a catch-all media range, <code>false</code> otherwise
- */
- public boolean matchesAll() {
- return this.supertype.equals(WILDCARD) && this.subtype.equals(WILDCARD);
- }
-
- private void setType(String supertype, String subtype) {
- this.supertype = supertype == null ? WILDCARD : supertype;
- this.subtype = subtype == null ? WILDCARD : subtype;
- if (this.supertype.equals(WILDCARD) && !this.subtype.equals(WILDCARD)) {
- throw new IllegalArgumentException("Supertype cannot be wildcard if subtype is not");
- }
- }
-
- private void setType(String typeDef) {
- String[] parts = typeDef.split("/");
- String superType = parts[0];
- String subType = WILDCARD;
- if(parts.length > 1){
- subType = parts[1];
- }
- this.setType(superType,subType);
- }
-
- MediaRange(String supertype, String subtype, double q) {
- this(supertype, subtype);
- this.q = q;
- }
-
-
- public String getParameter(String key) {
- if (parameters != null) {
- return parameters.get(key);
- } else {
- return null;
- }
- }
-
- public String getSupertype() {
- return supertype;
- }
-
- public String getSubtype() {
- return subtype;
- }
-
- /**
- * Get the value of the quality factor parameter (<code>q</code>).
- * @return the quality factor
- */
- public double getQ() {
- return q;
- }
-
- public Map<String, String> getParameters() {
- return parameters != null ? parameters : new HashMap<String, String>(0);
- }
-
- /* -- Comparable implementation -- */
- public int compareTo(MediaRange o) {
- double diff = this.q - o.getQ();
- if (diff == 0) {
- // Compare parameters
- int paramDiff = o.getParameters().size() - this.getParameters().size();
- if (paramDiff != 0) {
- return paramDiff;
- }
- // Compare wildcards
- if (this.supertype.equals(WILDCARD) && !o.getSupertype().equals(WILDCARD)) {
- return 1;
- } else if (!this.supertype.equals(WILDCARD) && o.getSupertype().equals(WILDCARD)) {
- return -1;
- }
- if (this.subtype.equals(WILDCARD) && !o.getSubtype().equals(WILDCARD)) {
- return 1;
- } else if (!this.subtype.equals(WILDCARD) && o.getSubtype().equals(WILDCARD)) {
- return -1;
- }
- // Compare names
- return this.toString().compareTo(o.toString());
- } else {
- return diff > 0 ? -1 : 1;
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof MediaRange) {
- MediaRange mr = (MediaRange) obj;
- return mr.getSupertype().equals(this.supertype) && mr.getSubtype().equals(this.subtype);
- }
- return super.equals(obj);
- }
-
- public boolean equals(String s) {
- return (this.supertype + "/" + this.subtype).equals(s);
- }
-
- @Override
- public String toString() {
- final StringBuilder buf = new StringBuilder(this.supertype);
- buf.append('/');
- buf.append(this.subtype);
- if (parameters != null) {
- String delimiter = ";";
- for (String key : parameters.keySet()) {
- buf.append(delimiter);
- buf.append(key).append("=").append(parameters.get(key));
- }
- }
- return buf.toString();
- }
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameFilter.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameFilter.java
deleted file mode 100644
index 15d6184..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/NodeNameFilter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.helper;
-
-
-/**
- * Filter a String so that it can be used as a NodeName.
- */
-public class NodeNameFilter {
-
- public static final String ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_";
- public static final char REPLACEMENT_CHAR = '_';
-
- public String filter(String nodeName) {
- final StringBuilder sb = new StringBuilder();
- char lastAdded = 0;
-
- nodeName = nodeName.toLowerCase();
- for(int i=0; i < nodeName.length(); i++) {
- final char c = nodeName.charAt(i);
- char toAdd = c;
-
- if (ALLOWED_CHARS.indexOf(c) < 0) {
- if (lastAdded == REPLACEMENT_CHAR) {
- // do not add several _ in a row
- continue;
- }
- toAdd = REPLACEMENT_CHAR;
-
- } else if(i == 0 && Character.isDigit(c)) {
- sb.append(REPLACEMENT_CHAR);
- }
-
- sb.append(toAdd);
- lastAdded = toAdd;
- }
-
- if (sb.length()==0) {
- sb.append(REPLACEMENT_CHAR);
- }
-
- return sb.toString();
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
deleted file mode 100644
index 8b8d81e..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.helper;
-
-import java.lang.reflect.Method;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Takes a string representation of a node (either a path or a uuid) and tries for parse it.
- */
-public class ReferenceParser {
-
- private final Session session;
-
- private static final Logger logger = LoggerFactory.getLogger(ReferenceParser.class);
-
- public ReferenceParser(Session session) {
- this.session = session;
- }
-
- /**
- * Parses the given source string and returns the correct Value object.
- * If no node matches returns <code>null</code>.
- * <p/>
- *
- * @param value a path or UUID
- * @param factory the value factory
- * @param weak true to create a WeakReference value
- * @return the value or <code>null</code>
- * @throws RepositoryException
- */
- public Value parse(String value, ValueFactory factory, boolean weak) throws RepositoryException {
- Node n = parse(value);
- if (n == null) {
- return null;
- }
- return createReferenceValue(n, factory, weak);
- }
-
- /**
- * Parses the given source strings and returns the respective reference value
- * instances. If no node matches for any of the sources
- * returns <code>null</code>.
- * <p/>
- *
- * @param values path or UUID strings
- * @param factory the value factory
- * @param weak true to create a WeakReference value
- * @return the values or <code>null</code>
- * @throws RepositoryException
- */
- public Value[] parse(String[] values, ValueFactory factory, boolean weak) throws RepositoryException {
- Value ret[] = new Value[values.length];
- for (int i=0; i< values.length; i++) {
- Node n = parse(values[i]);
- if (n == null) {
- return null;
- }
- ret[i] = createReferenceValue(n, factory, weak);
- }
- return ret;
- }
-
- private Value createReferenceValue(Node node, ValueFactory factory, boolean weak) throws RepositoryException {
- if (weak) {
- try {
- final Method m = factory.getClass().getMethod("createValue", new Class[] { Node.class, Boolean.TYPE });
- return (Value) m.invoke(factory, node, true);
- } catch (NoSuchMethodException e) {
- logger.warn("A WeakReference type hint was received, but JCR 2 isn't available. Falling back to Reference type.");
- return factory.createValue(node);
- } catch (Exception e) {
- logger.error("Unable to create WeakReference Value.", e);
- return null;
- }
- } else {
- return factory.createValue(node);
- }
- }
-
- private Node parse(String value) throws RepositoryException {
- try {
- if (session.itemExists(value)) {
- return (Node) session.getItem(value);
- }
- } catch (RepositoryException ignore) {
- // we ignore this
- }
- try {
- return session.getNodeByUUID(value);
- } catch (RepositoryException ignore) {
- // we ignore this
- }
- return null;
- }
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/RequestProperty.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/RequestProperty.java
deleted file mode 100644
index a8b2d13..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/RequestProperty.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * 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.helper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sling.api.request.RequestParameter;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.servlets.post.SlingPostConstants;
-
-/**
- * Encapsulates all infos from the respective request parameters that are needed
- * to create the repository property
- */
-public class RequestProperty {
-
- private static final RequestParameter[] EMPTY_PARAM_ARRAY = new RequestParameter[0];
-
- public static final String DEFAULT_IGNORE = SlingPostConstants.RP_PREFIX
- + "ignore";
-
- public static final String DEFAULT_NULL = SlingPostConstants.RP_PREFIX
- + "null";
-
- private final String path;
-
- private final String name;
-
- private final String parentPath;
-
- private RequestParameter[] values;
-
- private String[] stringValues;
-
- private String typeHint;
-
- private boolean hasMultiValueTypeHint;
-
- private RequestParameter[] defaultValues = EMPTY_PARAM_ARRAY;
-
- private boolean isDelete;
-
- private String repositoryResourcePath;
-
- private boolean isRepositoryResourceMove;
-
- private boolean ignoreBlanks;
-
- private boolean useDefaultWhenMissing;
-
- private boolean patch = false;
-
- private Chunk chunk;
-
- public RequestProperty(String path) {
- assert path.startsWith("/");
- this.path = ResourceUtil.normalize(path);
- this.parentPath = ResourceUtil.getParent(path);
- this.name = ResourceUtil.getName(path);
- }
-
- public String getTypeHint() {
- return typeHint;
- }
-
- public boolean hasMultiValueTypeHint() {
- return this.hasMultiValueTypeHint;
- }
-
- public void setTypeHintValue(String typeHint) {
- if ( typeHint != null && typeHint.endsWith("[]") ) {
- this.typeHint = typeHint.substring(0, typeHint.length() - 2);
- this.hasMultiValueTypeHint = true;
- } else {
- this.typeHint = typeHint;
- this.hasMultiValueTypeHint = false;
- }
- }
-
- public String getPath() {
- return path;
- }
-
- public String getName() {
- return name;
- }
-
- public String getParentPath() {
- return parentPath;
- }
-
- public boolean hasValues() {
- if (useDefaultWhenMissing && defaultValues != null && defaultValues.length > 0) {
- return true;
- } else {
- if (ignoreBlanks) {
- return (values != null && getStringValues().length > 0);
- } else {
- return values != null;
- }
- }
- }
-
- public RequestParameter[] getValues() {
- return values;
- }
-
- public void setValues(RequestParameter[] values) {
- this.values = values;
- }
-
- public RequestParameter[] getDefaultValues() {
- return defaultValues;
- }
-
- public void setDefaultValues(RequestParameter[] defaultValues) {
- if (defaultValues == null) {
- this.defaultValues = EMPTY_PARAM_ARRAY;
- } else {
- this.defaultValues = defaultValues;
- }
- }
-
- public boolean isFileUpload() {
- return values != null && !values[0].isFormField();
- }
-
- /**
- * Checks if this property provides any values. this is the case if one of
- * the values is not empty or if the default handling is not 'ignore'
- *
- * @return <code>true</code> if this property provides values
- */
- public boolean providesValue() {
- // should void double creation of string values
- String[] sv = getStringValues();
- if (sv == null) {
- // is missleading return type. but means that property should not
- // get auto-create values
- return true;
- }
- for (String s : sv) {
- if (!s.equals("")) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the assembled string array out of the provided request values and
- * default values.
- *
- * @return a String array or <code>null</code> if the property needs to be
- * removed.
- */
- public String[] getStringValues() {
- if (stringValues == null) {
- if (values == null && useDefaultWhenMissing) {
- stringValues = new String[] { defaultValues[0].getString() };
- } else if (values.length > 1) {
- // TODO: how the default values work for MV props is not very
- // clear
- List<String> stringValueList = new ArrayList<String>(values.length);
- for (int i = 0; i < values.length; i++) {
- String value = values[i].getString();
- if ((!ignoreBlanks) || value.length() > 0) {
- stringValueList.add(value);
- }
- }
- stringValues = stringValueList.toArray(new String[stringValueList.size()]);
- } else {
- String value = values[0].getString();
- if (value.equals("")) {
- if (ignoreBlanks) {
- return new String[0];
- } else {
- if (defaultValues.length == 1) {
- String defValue = defaultValues[0].getString();
- if (defValue.equals(DEFAULT_IGNORE)) {
- // ignore means, do not create empty values
- return new String[0];
- } else if (defValue.equals(DEFAULT_NULL)) {
- // null means, remove property if exist
- return null;
- }
- value = defValue;
- }
- }
- }
- stringValues = new String[] { value };
- }
- }
- return stringValues;
- }
-
- /**
- * Specifies whether this property should be deleted before any new content
- * is to be set according to the values stored.
- *
- * @param isDelete <code>true</code> if the repository item described by
- * this is to be deleted before any other operation.
- */
- public void setDelete(boolean isDelete) {
- this.isDelete = isDelete;
- }
-
- /**
- * Returns <code>true</code> if the repository item described by this is
- * to be deleted before setting new content to it.
- */
- public boolean isDelete() {
- return isDelete;
- }
-
- /**
- * Sets the path of the repository item from which the content for this
- * property is to be copied or moved. The path may be relative in which case
- * it will be resolved relative to the absolute path of this property.
- *
- * @param sourcePath The path of the repository item to get the content from
- * @param isMove <code>true</code> if the source content is to be moved,
- * otherwise the source content is copied from the repository
- * item.
- */
- public void setRepositorySource(String sourcePath, boolean isMove) {
-
- // make source path absolute
- if (!sourcePath.startsWith("/")) {
- sourcePath = getParentPath() + "/" + sourcePath;
- sourcePath = ResourceUtil.normalize(sourcePath);
- }
-
- this.repositoryResourcePath = sourcePath;
- this.isRepositoryResourceMove = isMove;
- }
-
- /**
- * Returns <code>true</code> if the content of this property is to be set
- * by moving content from another repository item.
- *
- * @see #getRepositorySource()
- */
- public boolean hasRepositoryMoveSource() {
- return isRepositoryResourceMove;
- }
-
- /**
- * Returns <code>true</code> if the content of this property is to be set
- * by copying content from another repository item.
- *
- * @see #getRepositorySource()
- */
- public boolean hasRepositoryCopySource() {
- return getRepositorySource() != null && !hasRepositoryMoveSource();
- }
-
- /**
- * Returns the absolute path of the repository item from which the content
- * for this property is to be copied or moved.
- *
- * @see #hasRepositoryCopySource()
- * @see #hasRepositoryMoveSource()
- * @see #setRepositorySource(String, boolean)
- */
- public String getRepositorySource() {
- return repositoryResourcePath;
- }
-
- public void setIgnoreBlanks(boolean b) {
- ignoreBlanks = b;
- }
-
- public void setUseDefaultWhenMissing(boolean b) {
- useDefaultWhenMissing = b;
- }
-
- public void setPatch(boolean b) {
- patch = b;
- }
-
- /**
- * Returns whether this property is to be handled as a multi-value property
- * seen as set.
- */
- public boolean isPatch() {
- return patch;
- }
-
- /**
- * Return true if request is chunk upload.
- */
- public boolean isChunkUpload() {
- return chunk != null;
- }
-
- public Chunk getChunk() {
- return chunk;
- }
-
- public void setChunk(Chunk chunk) {
- this.chunk = chunk;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingFileUploadHandler.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingFileUploadHandler.java
deleted file mode 100644
index 29eb674..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingFileUploadHandler.java
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * 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.helper;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.SequenceInputStream;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeManager;
-import javax.servlet.ServletContext;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.util.Text;
-import org.apache.sling.api.request.RequestParameter;
-import org.apache.sling.api.resource.ModifiableValueMap;
-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;
-
-/**
- * Handles file uploads.
- * <p/>
- *
- * Simple example:
- * <xmp>
- * <form action="/home/admin" method="POST" enctype="multipart/form-data">
- * <input type="file" name="./portrait" />
- * </form>
- * </xmp>
- *
- * this will create a nt:file node below "/home/admin" if the node type of
- * "admin" is (derived from) nt:folder, a nt:resource node otherwise.
- * <p/>
- *
- * Filename example:
- * <xmp>
- * <form action="/home/admin" method="POST" enctype="multipart/form-data">
- * <input type="file" name="./*" />
- * </form>
- * </xmp>
- *
- * same as above, but uses the filename of the uploaded file as name for the
- * new node.
- * <p/>
- *
- * Type hint example:
- * <xmp>
- * <form action="/home/admin" method="POST" enctype="multipart/form-data">
- * <input type="file" name="./portrait" />
- * <input type="hidden" name="./portrait@TypeHint" value="my:file" />
- * </form>
- * </xmp>
- *
- * this will create a new node with the type my:file below admin. if the hinted
- * type extends from nt:file an intermediate file node is created otherwise
- * directly a resource node.
- */
-public class SlingFileUploadHandler {
-
- // nodetype name string constants
- public static final String NT_FOLDER = "nt:folder";
- public static final String NT_FILE = "nt:file";
- public static final String NT_RESOURCE = "nt:resource";
- public static final String NT_UNSTRUCTURED = "nt:unstructured";
-
- // item name string constants
- public static final String JCR_CONTENT = "jcr:content";
- public static final String JCR_LASTMODIFIED = "jcr:lastModified";
- public static final String JCR_MIMETYPE = "jcr:mimeType";
- public static final String JCR_ENCODING = "jcr:encoding";
- public static final String JCR_DATA = "jcr:data";
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- /**
- * The servlet context.
- */
- private ServletContext servletContext;
-
- public void setServletContext(ServletContext servletContext) {
- this.servletContext = servletContext;
- }
-
- /**
- * Uses the file(s) in the request parameter for creation of new nodes.
- * if the parent node is a nt:folder a new nt:file is created. otherwise
- * just a nt:resource. if the <code>name</code> is '*', the filename of
- * the uploaded file is used.
- *
- * @param parent the parent node
- * @param prop the assembled property info
- * @throws RepositoryException if an error occurs
- */
- private void setFile(final Resource parentResource, final Node parent, final RequestProperty prop, RequestParameter value, final List<Modification> changes, String name, final String contentType)
- throws RepositoryException, PersistenceException {
- // check type hint. if the type is ok and extends from nt:file,
- // create an nt:file with that type. if it's invalid, drop it and let
- // the parent node type decide.
- boolean createNtFile = parent.isNodeType(NT_FOLDER);
- String typeHint = prop.getTypeHint();
- if (typeHint != null) {
- try {
- NodeTypeManager ntMgr = parent.getSession().getWorkspace().getNodeTypeManager();
- NodeType nt = ntMgr.getNodeType(typeHint);
- createNtFile = nt.isNodeType(NT_FILE);
- } catch (RepositoryException e) {
- // assuming type not valid.
- typeHint = null;
- }
- }
-
- // also create an nt:file if the name contains an extension
- // the rationale is that if the file name is "important" we want
- // an nt:file, and an image name with an extension is probably "important"
- if(!createNtFile && name.indexOf('.') > 0) {
- createNtFile = true;
- }
-
- // set empty type
- if (typeHint == null) {
- typeHint = createNtFile ? NT_FILE : NT_RESOURCE;
- }
-
- // create nt:file node if needed
- Resource resParent;
- if (createNtFile) {
- // create nt:file
- resParent = getOrCreateChildResource(parentResource, name, typeHint, changes);
- name = JCR_CONTENT;
- typeHint = NT_RESOURCE;
- } else {
- resParent = parentResource;
- }
-
- // create resource node
- Resource newResource = getOrCreateChildResource(resParent, name, typeHint, changes);
- Node res = newResource.adaptTo(Node.class);
-
- // set properties
- changes.add(Modification.onModified(
- res.setProperty(JCR_LASTMODIFIED, Calendar.getInstance()).getPath()
- ));
- changes.add(Modification.onModified(
- res.setProperty(JCR_MIMETYPE, contentType).getPath()
- ));
- try {
- // process chunk upload request separately
- if (prop.isChunkUpload()) {
- processChunk(resParent, res, prop, value, changes);
- } else {
- changes.add(Modification.onModified(res.setProperty(JCR_DATA,
- value.getInputStream()).getPath()));
- }
- } catch (IOException e) {
- throw new RepositoryException("Error while retrieving inputstream from parameter value.", e);
- }
- }
-
- /**
- * Uses the file(s) in the request parameter for creation of new nodes.
- * if the parent node is a nt:folder a new nt:file is created. otherwise
- * just a nt:resource. if the <code>name</code> is '*', the filename of
- * the uploaded file is used.
- *
- * @param parent the parent node
- * @param prop the assembled property info
- * @throws RepositoryException if an error occurs
- */
- private void setFile(final Resource parentResource, final RequestProperty prop, final RequestParameter value, final List<Modification> changes, String name, final String contentType)
- throws PersistenceException, RepositoryException {
- String typeHint = prop.getTypeHint();
- if ( typeHint == null ) {
- typeHint = NT_FILE;
- }
- if(prop.isChunkUpload()){
- // cannot process chunk upload if parent node doesn't
- // exists. throw exception
- throw new RepositoryException(
- "Cannot process chunk upload request. Parent resource ["
- + parentResource.getPath() + "] doesn't exists");
- }
- // create properties
- final Map<String, Object> props = new HashMap<String, Object>();
- props.put("sling:resourceType", typeHint);
- props.put(JCR_LASTMODIFIED, Calendar.getInstance());
- props.put(JCR_MIMETYPE, contentType);
- try {
- props.put(JCR_DATA, value.getInputStream());
- } catch (final IOException e) {
- throw new PersistenceException("Error while retrieving inputstream from parameter value.", e);
- }
-
- // get or create resource
- Resource result = parentResource.getChild(name);
- if ( result != null ) {
- final ModifiableValueMap vm = result.adaptTo(ModifiableValueMap.class);
- if ( vm == null ) {
- throw new PersistenceException("Resource at " + parentResource.getPath() + '/' + name + " is not modifiable.");
- }
- vm.putAll(props);
- } else {
- result = parentResource.getResourceResolver().create(parentResource, name, props);
- }
- for(final String key : props.keySet()) {
- changes.add(Modification.onModified(result.getPath() + '/' + key));
- }
- }
- /**
- * Process chunk upload. For first and intermediate chunks request persists
- * chunks at jcr:content/chunk_start_end/jcr:data or
- * nt:resource/chunk_start_end/jcr:data. For last last chunk,
- * merge all previous chunks and last chunk and replace binary at
- * destination.
- */
- private void processChunk(final Resource resParent, final Node res,
- final RequestProperty prop, RequestParameter value,
- final List<Modification> changes) throws RepositoryException {
- try {
- long chunkOffset = prop.getChunk().getOffset();
- if (chunkOffset == 0) {
- // first chunk
- // check if another chunk upload is already in progress. throw
- // exception
- NodeIterator itr = res.getNodes(SlingPostConstants.CHUNK_NODE_NAME
- + "*");
- if (itr.hasNext()) {
- throw new RepositoryException(
- "Chunk upload already in progress at {" + res.getPath()
- + "}");
- }
- res.addMixin(SlingPostConstants.NT_SLING_CHUNK_MIXIN);
- changes.add(Modification.onModified(res.setProperty(
- SlingPostConstants.NT_SLING_CHUNKS_LENGTH, 0).getPath()));
- if (!res.hasProperty(JCR_DATA)) {
- // create a empty jcr:data property
- res.setProperty(JCR_DATA,
- new ByteArrayInputStream("".getBytes()));
- }
- }
- if (!res.hasProperty(SlingPostConstants.NT_SLING_CHUNKS_LENGTH)) {
- throw new RepositoryException("no chunk upload found at {"
- + res.getPath() + "}");
- }
- long currentLength = res.getProperty(
- SlingPostConstants.NT_SLING_CHUNKS_LENGTH).getLong();
- long totalLength = prop.getChunk().getLength();
- if (chunkOffset != currentLength) {
- throw new RepositoryException("Chunk's offset {"
- + chunkOffset
- + "} doesn't match expected offset {"
- + res.getProperty(
- SlingPostConstants.NT_SLING_CHUNKS_LENGTH).getLong()
- + "}");
- }
- if (totalLength != 0) {
- if (res.hasProperty(SlingPostConstants.NT_SLING_FILE_LENGTH)) {
- long expectedLength = res.getProperty(
- SlingPostConstants.NT_SLING_FILE_LENGTH).getLong();
- if (totalLength != expectedLength) {
- throw new RepositoryException("File length {"
- + totalLength + "} doesn't match expected length {"
- + expectedLength + "}");
- }
- } else {
- res.setProperty(SlingPostConstants.NT_SLING_FILE_LENGTH,
- totalLength);
- }
- }
- NodeIterator itr = res.getNodes(SlingPostConstants.CHUNK_NODE_NAME
- + "_" + String.valueOf(chunkOffset) + "*");
- if (itr.hasNext()) {
- throw new RepositoryException("Chunk already present at {"
- + itr.nextNode().getPath() + "}");
- }
- String nodeName = SlingPostConstants.CHUNK_NODE_NAME + "_"
- + String.valueOf(chunkOffset) + "_"
- + String.valueOf(chunkOffset + value.getSize() - 1);
- if (totalLength == (currentLength + value.getSize())
- || prop.getChunk().isCompleted()) {
- File file = null;
- InputStream fileIns = null;
- try {
- file = mergeChunks(res, value.getInputStream());
- fileIns = new FileInputStream(file);
- changes.add(Modification.onModified(res.setProperty(
- JCR_DATA, fileIns).getPath()));
- NodeIterator nodeItr = res.getNodes(SlingPostConstants.CHUNK_NODE_NAME
- + "*");
- while (nodeItr.hasNext()) {
- Node nodeRange = nodeItr.nextNode();
- changes.add(Modification.onDeleted(nodeRange.getPath()));
- nodeRange.remove();
- }
- if (res.hasProperty(SlingPostConstants.NT_SLING_FILE_LENGTH)) {
- javax.jcr.Property expLenProp = res.getProperty(SlingPostConstants.NT_SLING_FILE_LENGTH);
- changes.add(Modification.onDeleted(expLenProp.getPath()));
- expLenProp.remove();
- }
- if (res.hasProperty(SlingPostConstants.NT_SLING_CHUNKS_LENGTH)) {
- javax.jcr.Property currLenProp = res.getProperty(SlingPostConstants.NT_SLING_CHUNKS_LENGTH);
- changes.add(Modification.onDeleted(currLenProp.getPath()));
- currLenProp.remove();
- }
- res.removeMixin(SlingPostConstants.NT_SLING_CHUNK_MIXIN);
- } finally {
- try {
- fileIns.close();
- file.delete();
- } catch (IOException ign) {
-
- }
-
- }
- } else {
- Node rangeNode = res.addNode(nodeName,
- SlingPostConstants.NT_SLING_CHUNK_NODETYPE);
- changes.add(Modification.onCreated(rangeNode.getPath()));
- changes.add(Modification.onModified(rangeNode.setProperty(
- JCR_DATA, value.getInputStream()).getPath()));
- changes.add(Modification.onModified(rangeNode.setProperty(
- SlingPostConstants.NT_SLING_CHUNK_OFFSET, chunkOffset).getPath()));
- changes.add(Modification.onModified(res.setProperty(
- SlingPostConstants.NT_SLING_CHUNKS_LENGTH,
- currentLength + value.getSize()).getPath()));
- }
- } catch (IOException e) {
- throw new RepositoryException(
- "Error while retrieving inputstream from parameter value.", e);
- }
- }
-
- /**
- * Merge all previous chunks with last chunk's stream into a temporary file
- * and return it.
- */
- private File mergeChunks(final Node parentNode,
- final InputStream lastChunkStream) throws PersistenceException,
- RepositoryException {
- OutputStream out = null;
- SequenceInputStream mergeStrm = null;
- File file = null;
- try {
- file = File.createTempFile("tmp-", "-mergechunk");
- out = new FileOutputStream(file);
- String startPattern = SlingPostConstants.CHUNK_NODE_NAME + "_"
- + "0_*";
- NodeIterator nodeItr = parentNode.getNodes(startPattern);
- InputStream ins = null;
- int i = 0;
- Set<InputStream> inpStrmSet = new LinkedHashSet<InputStream>();
- while (nodeItr.hasNext()) {
- if (nodeItr.getSize() > 1) {
- throw new RepositoryException(
- "more than one node found for pattern: " + startPattern);
- }
- Node rangeNode = nodeItr.nextNode();
-
- inpStrmSet.add(rangeNode.getProperty(
- javax.jcr.Property.JCR_DATA).getBinary().getStream());
- log.debug("added chunk {} to merge stream", rangeNode.getName());
- String[] indexBounds = rangeNode.getName().substring(
- (SlingPostConstants.CHUNK_NODE_NAME + "_").length()).split(
- "_");
- startPattern = SlingPostConstants.CHUNK_NODE_NAME + "_"
- + String.valueOf(Long.valueOf(indexBounds[1]) + 1) + "_*";
- nodeItr = parentNode.getNodes(startPattern);
- }
-
- inpStrmSet.add(lastChunkStream);
- mergeStrm = new SequenceInputStream(
- Collections.enumeration(inpStrmSet));
- IOUtils.copyLarge(mergeStrm, out);
- } catch (IOException e) {
- throw new PersistenceException("excepiton occured", e);
- } finally {
- IOUtils.closeQuietly(out);
- IOUtils.closeQuietly(mergeStrm);
-
- }
- return file;
- }
-
- /**
- * Delete all chunks saved within a node. If no chunks exist, it is no-op.
- */
- public void deleteChunks(final Node node) throws RepositoryException {
- // parent node containing all chunks and has mixin sling:chunks applied
- // on it.
- Node chunkParent = null;
- Node jcrContentNode = null;
- if (hasChunks(node)) {
- chunkParent = node;
- } else if (node.hasNode(JCR_CONTENT)
- && hasChunks((jcrContentNode = node.getNode(JCR_CONTENT)))) {
- chunkParent = jcrContentNode;
-
- }
- if (chunkParent != null) {
- NodeIterator nodeItr = chunkParent.getNodes(SlingPostConstants.CHUNK_NODE_NAME
- + "*");
- while (nodeItr.hasNext()) {
- Node rangeNode = nodeItr.nextNode();
- rangeNode.remove();
- }
- if (chunkParent.hasProperty(SlingPostConstants.NT_SLING_FILE_LENGTH)) {
- chunkParent.getProperty(SlingPostConstants.NT_SLING_FILE_LENGTH).remove();
- }
- if (chunkParent.hasProperty(SlingPostConstants.NT_SLING_CHUNKS_LENGTH)) {
- chunkParent.getProperty(
- SlingPostConstants.NT_SLING_CHUNKS_LENGTH).remove();
- }
- chunkParent.removeMixin(SlingPostConstants.NT_SLING_CHUNK_MIXIN);
- }
- }
-
- /**
- * Get the last {@link SlingPostConstants#NT_SLING_CHUNK_NODETYPE}
- * {@link Node}.
- *
- * @param node {@link Node} containing
- * {@link SlingPostConstants#NT_SLING_CHUNK_NODETYPE}
- * {@link Node}s
- * @return the {@link SlingPostConstants#NT_SLING_CHUNK_NODETYPE} chunk
- * node.
- * @throws RepositoryException
- */
- public Node getLastChunk(Node node) throws RepositoryException {
- // parent node containing all chunks and has mixin sling:chunks applied
- // on it.
- Node chunkParent = null;
- Node jcrContentNode = null;
- if (hasChunks(node)) {
- chunkParent = node;
- } else if (node.hasNode(JCR_CONTENT)
- && hasChunks((jcrContentNode = node.getNode(JCR_CONTENT)))) {
- chunkParent = jcrContentNode;
-
- }
- String startPattern = SlingPostConstants.CHUNK_NODE_NAME + "_" + "0_*";
- NodeIterator nodeItr = chunkParent.getNodes(startPattern);
- Node chunkNode = null;
- while (nodeItr.hasNext()) {
- if (nodeItr.getSize() > 1) {
- throw new RepositoryException(
- "more than one node found for pattern: " + startPattern);
- }
- chunkNode = nodeItr.nextNode();
-
- String[] indexBounds = chunkNode.getName().substring(
- (SlingPostConstants.CHUNK_NODE_NAME + "_").length()).split("_");
- startPattern = SlingPostConstants.CHUNK_NODE_NAME + "_"
- + String.valueOf(Long.valueOf(indexBounds[1]) + 1) + "_*";
- nodeItr = chunkParent.getNodes(startPattern);
- }
- return chunkNode;
- }
-
- /**
- * Return true if node has chunks stored in it, otherwise false.
- */
- private boolean hasChunks(final Node node) throws RepositoryException {
- for (NodeType nodeType : node.getMixinNodeTypes()) {
- if (nodeType.getName().equals(
- SlingPostConstants.NT_SLING_CHUNK_MIXIN)) {
- return true;
- }
- }
- return false;
- }
-
- private static final String MT_APP_OCTET = "application/octet-stream";
-
- /**
- * Uses the file(s) in the request parameter for creation of new nodes.
- * if the parent node is a nt:folder a new nt:file is created. otherwise
- * just a nt:resource. if the <code>name</code> is '*', the filename of
- * the uploaded file is used.
- *
- * @param parent the parent node
- * @param prop the assembled property info
- * @throws RepositoryException if an error occurs
- */
- public void setFile(final Resource parent, final RequestProperty prop, final List<Modification> changes)
- throws RepositoryException, PersistenceException {
- for (final RequestParameter value : prop.getValues()) {
-
- // ignore if a plain form field or empty
- if (value.isFormField() || value.getSize() <= 0) {
- continue;
- }
-
- // get node name
- String name = prop.getName();
- if (name.equals("*")) {
- name = value.getFileName();
- // strip of possible path (some browsers include the entire path)
- name = name.substring(name.lastIndexOf('/') + 1);
- name = name.substring(name.lastIndexOf('\\') + 1);
- }
- name = Text.escapeIllegalJcrChars(name);
-
- // get content type
- String contentType = value.getContentType();
- if (contentType != null) {
- int idx = contentType.indexOf(';');
- if (idx > 0) {
- contentType = contentType.substring(0, idx);
- }
- }
- if (contentType == null || contentType.equals(MT_APP_OCTET)) {
- // try to find a better content type
- ServletContext ctx = this.servletContext;
- if (ctx != null) {
- contentType = ctx.getMimeType(value.getFileName());
- }
- if (contentType == null || contentType.equals(MT_APP_OCTET)) {
- contentType = MT_APP_OCTET;
- }
- }
-
- final Node node = parent.adaptTo(Node.class);
- if ( node == null ) {
- this.setFile(parent, prop, value, changes, name, contentType);
- } else {
- this.setFile(parent, node, prop, value, changes, name, contentType);
- }
- }
-
- }
-
- private Resource getOrCreateChildResource(final Resource parent, final String name,
- final String typeHint,
- final List<Modification> changes)
- throws PersistenceException, RepositoryException {
- Resource result = parent.getChild(name);
- if ( result != null ) {
- final Node existing = result.adaptTo(Node.class);
- if ( existing != null && !existing.isNodeType(typeHint)) {
- existing.remove();
- result = createWithChanges(parent, name, typeHint, changes);
- }
- } else {
- result = createWithChanges(parent, name, typeHint, changes);
- }
- return result;
- }
-
- private Resource createWithChanges(final Resource parent, final String name,
- final String typeHint,
- final List<Modification> changes)
- throws PersistenceException {
- Map<String, Object> properties = null;
- if ( typeHint != null ) {
- properties = new HashMap<String, Object>();
- if ( parent.adaptTo(Node.class) != null ) {
- properties.put("jcr:primaryType", typeHint);
- } else {
- properties.put("sling:resourceType", typeHint);
- }
- }
- final Resource result = parent.getResourceResolver().create(parent, name, properties);
- changes.add(Modification.onCreated(result.getPath()));
- return result;
- }
-
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java b/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
deleted file mode 100644
index f36974b..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * 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.helper;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.PropertyDefinition;
-
-import org.apache.sling.api.resource.ModifiableValueMap;
-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;
-
-/**
- * Sets a Property on the given Node, in some cases with a specific type and
- * value. For example, "lastModified" with an empty value is stored as the
- * current Date.
- */
-public class SlingPropertyValueHandler {
-
- /**
- * Defins a map of auto properties
- */
- private static final Map<String, AutoType> AUTO_PROPS = new HashMap<String, AutoType>();
- static {
- AUTO_PROPS.put("created", AutoType.CREATED);
- AUTO_PROPS.put("createdBy", AutoType.CREATED_BY);
- AUTO_PROPS.put("jcr:created", AutoType.CREATED);
- AUTO_PROPS.put("jcr:createdBy", AutoType.CREATED_BY);
- AUTO_PROPS.put("lastModified", AutoType.MODIFIED);
- AUTO_PROPS.put("lastModifiedBy", AutoType.MODIFIED_BY);
- AUTO_PROPS.put("jcr:lastModified", AutoType.MODIFIED);
- AUTO_PROPS.put("jcr:lastModifiedBy", AutoType.MODIFIED_BY);
- }
-
- /**
- * the post processor
- */
- private final List<Modification> changes;
-
- private final DateParser dateParser;
-
- private final ReferenceParser referenceParser;
-
- /**
- * current date for all properties in this request
- */
- private final Calendar now = Calendar.getInstance();
-
- // hard-coding WEAKREFERENCE as propertyType = 10 because we don'
- // want to depend upon jcr 2 api just for the constant.
- private static final int PROPERTY_TYPE_WEAKREFERENCE = 10;
-
- /**
- * Constructs a propert value handler
- */
- public SlingPropertyValueHandler(DateParser dateParser, ReferenceParser referenceParser, List<Modification> changes) {
- this.dateParser = dateParser;
- this.referenceParser = referenceParser;
- this.changes = changes;
- }
-
- /** Return the AutoType for a given property name
- * @return null if not found
- * */
- static AutoType getAutoType(String propertyName) {
- return AUTO_PROPS.get(propertyName);
- }
-
- private PropertyDefinition searchPropertyDefinition(final NodeType nodeType, final String name) {
- if ( nodeType.getPropertyDefinitions() != null ) {
- for(final PropertyDefinition pd : nodeType.getPropertyDefinitions()) {
- if ( pd.getName().equals(name) ) {
- return pd;
- }
- }
- }
- // SLING-2877:
- // no need to search property definitions of super types, as nodeType.getPropertyDefinitions()
- // already includes those. see javadoc of {@link NodeType#getPropertyDefinitions()}
- return null;
- }
-
- private PropertyDefinition searchPropertyDefinition(final Node node, final String name)
- throws RepositoryException {
- PropertyDefinition result = searchPropertyDefinition(node.getPrimaryNodeType(), name);
- if ( result == null ) {
- if ( node.getMixinNodeTypes() != null ) {
- for(final NodeType mt : node.getMixinNodeTypes()) {
- result = this.searchPropertyDefinition(mt, name);
- if ( result != null ) {
- return result;
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Set property on given node, with some automatic values when user provides
- * the field name but no value.
- *
- * html example for testing:
- * <xmp>
- * <input type="hidden" name="created"/>
- * <input type="hidden" name="lastModified"/>
- * <input type="hidden" name="createdBy" />
- * <input type="hidden" name="lastModifiedBy"/>
- * </xmp>
- *
- * @param parent the parent node
- * @param prop the request property
- * @throws RepositoryException if a repository error occurs
- */
- public void setProperty(final Resource parent, final RequestProperty prop)
- throws RepositoryException, PersistenceException {
- final Modifiable mod = new Modifiable();
- mod.resource = parent;
- mod.node = parent.adaptTo(Node.class);
- mod.valueMap = parent.adaptTo(ModifiableValueMap.class);
- if ( mod.valueMap == null ) {
- throw new PersistenceException("Resource at '" + parent.getPath() + "' is not modifiable.");
- }
-
- final String name = prop.getName();
- if (prop.providesValue()) {
- // if user provided a value, don't mess with it
- setPropertyAsIs(mod, prop);
-
- } else if (AUTO_PROPS.containsKey(name)) {
- // check if this is a JCR resource and check node type
- if ( mod.node != null ) {
- final PropertyDefinition pd = this.searchPropertyDefinition(mod.node, name);
- if ( pd != null ) {
- // SLING-2877 (autocreated check is only required for new nodes)
- if ( (mod.node.isNew() && pd.isAutoCreated()) || pd.isProtected() ) {
- return;
- }
- }
- }
-
- // avoid collision with protected properties
- final boolean isNew = (mod.node != null ? mod.node.isNew() : true);
- switch (getAutoType(name)) {
- case CREATED:
- if (isNew) {
- setCurrentDate(mod, name);
- }
- break;
- case CREATED_BY:
- if (isNew) {
- setCurrentUser(mod, name);
- }
- break;
- case MODIFIED:
- setCurrentDate(mod, name);
- break;
- case MODIFIED_BY:
- setCurrentUser(mod, name);
- break;
- }
- } else {
- // no magic field, set value as provided
- setPropertyAsIs(mod, prop);
- }
- }
-
- /**
- * Sets the property to the given date
- * @param parent parent node
- * @param name name of the property
- * @throws RepositoryException if a repository error occurs
- */
- private void setCurrentDate(Modifiable parent, String name)
- throws RepositoryException, PersistenceException {
- removePropertyIfExists(parent, name);
- parent.valueMap.put(name, now);
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + name));
- }
-
- /**
- * set property to the current User id
- * @param parent parent node
- * @param name name of the property
- * @throws RepositoryException if a repository error occurs
- */
- private void setCurrentUser(Modifiable parent, String name)
- throws RepositoryException, PersistenceException {
- removePropertyIfExists(parent, name);
- final String user = parent.resource.getResourceResolver().getUserID();
- parent.valueMap.put(name, user);
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + name));
- }
-
- /**
- * Removes the property with the given name from the parent node if it
- * exists and if it's not a mandatory property.
- *
- * @param parent the parent node
- * @param name the name of the property to remove
- * @return path of the property that was removed or <code>null</code> if
- * it was not removed
- * @throws RepositoryException if a repository error occurs.
- */
- private String removePropertyIfExists(final Modifiable parent, final String name)
- throws RepositoryException, PersistenceException {
- if (parent.valueMap.containsKey(name) ) {
- if ( parent.node != null ) {
- final Property prop = parent.node.getProperty(name);
- if (!prop.getDefinition().isMandatory()) {
- final String path = prop.getPath();
- prop.remove();
- return path;
- }
- } else {
- parent.valueMap.remove(name);
- return parent.resource.getPath() + '/' + name;
- }
- }
- return null;
- }
-
- /**
- * set property without processing, except for type hints
- *
- * @param parent the parent node
- * @param prop the request property
- * @throws RepositoryException if a repository error occurs.
- */
- private void setPropertyAsIs(final Modifiable parent, final RequestProperty prop)
- throws RepositoryException, PersistenceException {
-
- String[] values = prop.getStringValues();
-
- if (values == null || (values.length == 1 && values[0].length() == 0)) {
- // if no value is present or a single empty string is given,
- // just remove the existing property (if any)
- removeProperty(parent, prop);
-
- } else if (values.length == 0) {
- // do not create new prop here, but clear existing
- clearProperty(parent, prop);
-
- } else {
- // when patching, simply update the value list using the patch operations
- if (prop.isPatch()) {
- values = patch(parent, prop.getName(), values);
- if (values == null) {
- return;
- }
- }
-
- final boolean multiValue = isMultiValue(parent, prop, values);
- final int type = getType(parent, prop);
-
- if (multiValue) {
- // converting single into multi value props requires deleting it first
- removeIfSingleValueProperty(parent, prop);
- }
-
- Session s = parent.resource.getResourceResolver().adaptTo(Session.class);
- if (s != null) {
- final ValueFactory valFac = s.getValueFactory();
- if (type == PropertyType.DATE) {
- if (storeAsDate(parent, prop.getName(), values, multiValue, valFac)) {
- return;
- }
- } else if (isReferencePropertyType(type)) {
- if (storeAsReference(parent, prop.getName(), values, type, multiValue, valFac)) {
- return;
- }
- }
- }
-
- store(parent, prop.getName(), values, type, multiValue);
- }
- }
-
- /**
- * Patches a multi-value property using add and remove operations per value.
- */
- private String[] patch(final Modifiable parent, String name, String[] values)
- throws RepositoryException, PersistenceException {
- // we do not use a Set here, as we want to be very restrictive in our
- // actions and avoid touching elements that are not modified through the
- // add/remove patch operations; e.g. if the value "foo" occurs twice
- // in the existing array, and is not touched, afterwards there should
- // still be two times "foo" in the list, even if this is not a real set.
- List<String> oldValues = new ArrayList<String>();
-
- if (parent.valueMap.containsKey(name)) {
- if ( parent.node != null ) {
- final Property p = parent.node.getProperty(name);
-
- // can only patch multi-value props
- if (!p.getDefinition().isMultiple()) {
- return null;
- }
-
- for (Value v : p.getValues()) {
- oldValues.add(v.getString());
- }
- } else {
- final String[] setValues = parent.valueMap.get(name, String[].class);
- if ( setValues != null ) {
- for(final String v : setValues) {
- oldValues.add(v);
- }
- }
- }
- }
-
- boolean modified = false;
- for (String v : values) {
- if (v != null && v.length() > 0) {
- final char op = v.charAt(0);
- final String val = v.substring(1);
-
- if (op == SlingPostConstants.PATCH_ADD) {
- if (!oldValues.contains(val)) {
- oldValues.add(val);
- modified = true;
- }
- } else if (op == SlingPostConstants.PATCH_REMOVE) {
- while (oldValues.remove(val)) {
- modified = true;
- }
- }
- }
- }
-
- // if the patch does not include any operations (e.g. invalid ops)
- // return null to indicate that nothing should be done
- if (modified) {
- return oldValues.toArray(new String[oldValues.size()]);
- }
-
- return null;
- }
-
-
- private boolean isReferencePropertyType(int propertyType) {
- return propertyType == PropertyType.REFERENCE || propertyType == PROPERTY_TYPE_WEAKREFERENCE;
- }
-
- private boolean isWeakReference(int propertyType) {
- return propertyType == PROPERTY_TYPE_WEAKREFERENCE;
- }
-
- /**
- * Returns the property type to use for the given property. This is defined
- * either by an explicit type hint in the request or simply the type of the
- * existing property.
- */
- private int getType(final Modifiable parent, RequestProperty prop) throws RepositoryException {
- // no explicit typehint
- int type = PropertyType.UNDEFINED;
- if (prop.getTypeHint() != null) {
- try {
- type = PropertyType.valueFromName(prop.getTypeHint());
- } catch (Exception e) {
- // ignore
- }
- }
- String[] values = prop.getStringValues();
- if ( type == PropertyType.UNDEFINED && values != null && values.length > 0 ) {
- if ( parent.node != null ) {
- if ( parent.node.hasProperty(prop.getName()) ) {
- type = parent.node.getProperty(prop.getName()).getType();
- }
- }
- }
- return type;
- }
-
- /**
- * Returns whether the property should be handled as multi-valued.
- */
- private boolean isMultiValue(final Modifiable parent, RequestProperty prop, String[] values) throws RepositoryException {
- // multiple values are provided
- if (values != null && values.length > 1) {
- return true;
- }
- // TypeHint with []
- if (prop.hasMultiValueTypeHint()) {
- return true;
- }
- // patch method requires multi value
- if (prop.isPatch()) {
- return true;
- }
- // nothing in the request, so check the current JCR property definition
- if ( parent.node != null ) {
- if (parent.node.hasProperty(prop.getName()) ) {
- return parent.node.getProperty(prop.getName()).getDefinition().isMultiple();
- }
- } else {
- final Object value = parent.valueMap.get(prop.getName());
- if ( value != null && value.getClass().isArray() ) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Clears a property: sets an empty string for single-value properties, and
- * removes multi-value properties.
- */
- private void clearProperty(final Modifiable parent, RequestProperty prop)
- throws RepositoryException, PersistenceException {
- if (parent.valueMap.containsKey(prop.getName())) {
- if ( parent.node != null ) {
- if (parent.node.getProperty(prop.getName()).getDefinition().isMultiple()) {
- //the existing property is multi-valued, so just delete it?
- final String removePath = removePropertyIfExists(parent, prop.getName());
- if ( removePath != null ) {
- changes.add(Modification.onDeleted(removePath));
- }
- } else {
- changes.add(Modification.onModified(
- parent.node.setProperty(prop.getName(), "").getPath()
- ));
- }
- } else {
- parent.valueMap.put(prop.getName(), "");
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + prop.getName()));
- }
- }
- }
-
- /**
- * Removes the property if it exists.
- */
- private void removeProperty(final Modifiable parent, RequestProperty prop)
- throws RepositoryException, PersistenceException {
- final String removePath = removePropertyIfExists(parent, prop.getName());
- if ( removePath != null ) {
- changes.add(Modification.onDeleted(removePath));
- }
- }
-
- /**
- * Removes the property if it exists and is single-valued.
- */
- private void removeIfSingleValueProperty(final Modifiable parent,
- final RequestProperty prop)
- throws RepositoryException, PersistenceException {
- if (parent.valueMap.containsKey(prop.getName())) {
- if ( parent.node != null ) {
- if (!parent.node.getProperty(prop.getName()).getDefinition().isMultiple()) {
- // the existing property is single-valued, so we have to delete it before setting the
- // multi-value variation
- final String removePath = removePropertyIfExists(parent, prop.getName());
- if ( removePath != null ) {
- changes.add(Modification.onDeleted(removePath));
- }
- }
- } else {
- final String removePath = removePropertyIfExists(parent, prop.getName());
- if ( removePath != null ) {
- changes.add(Modification.onDeleted(removePath));
- }
- }
- }
- }
-
- /**
- * Stores property value(s) as date(s). Will parse the date(s) from the string
- * value(s) in the {@link RequestProperty}.
- *
- * @return true only if parsing was successfull and the property was actually changed
- */
- private boolean storeAsDate(final Modifiable parent, String name, String[] values, boolean multiValued, ValueFactory valFac)
- throws RepositoryException, PersistenceException {
- if (multiValued) {
- final Value[] array = dateParser.parse(values, valFac);
- if (array != null) {
- if ( parent.node != null ) {
- parent.node.setProperty(name, array);
- } else {
- final Calendar[] dates = new Calendar[array.length];
- int index = 0;
- for(final Value v : array) {
- dates[index] = v.getDate();
- index++;
- }
- parent.valueMap.put(name, dates);
- }
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + name));
- return true;
- }
- } else {
- if (values.length >= 1) {
- final Calendar c = dateParser.parse(values[0]);
- if (c != null) {
- parent.valueMap.put(name, c);
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + name));
-
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Stores property value(s) as reference(s). Will parse the reference(s) from the string
- * value(s) in the {@link RequestProperty}.
- *
- * @return true only if parsing was successfull and the property was actually changed
- */
- private boolean storeAsReference(final Modifiable parent, String name, String[] values, int type, boolean multiValued, ValueFactory valFac)
- throws RepositoryException, PersistenceException {
- if ( parent.node == null ) {
- // TODO
- throw new PersistenceException("Resource " + parent.resource.getPath() + " does not support reference properties.");
- }
- if (multiValued) {
- Value[] array = referenceParser.parse(values, valFac, isWeakReference(type));
- if (array != null) {
- changes.add(Modification.onModified(
- parent.node.setProperty(name, array).getPath()
- ));
- return true;
- }
- } else {
- if (values.length >= 1) {
- Value v = referenceParser.parse(values[0], valFac, isWeakReference(type));
- if (v != null) {
- changes.add(Modification.onModified(
- parent.node.setProperty(name, v).getPath()
- ));
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Stores the property as string or via a string value, but with an explicit
- * type. Both multi-value or single-value.
- */
- private void store(final Modifiable parent,
- final String name,
- final String[] values,
- final int type,
- final boolean multiValued)
- throws RepositoryException, PersistenceException {
- if ( parent.node != null ) {
- Property p = null;
-
- if (multiValued) {
- if (type == PropertyType.UNDEFINED) {
- p = parent.node.setProperty(name, values);
- } else {
- p = parent.node.setProperty(name, values, type);
- }
- } else if (values.length >= 1) {
- if (type == PropertyType.UNDEFINED) {
- p = parent.node.setProperty(name, values[0]);
- } else {
- p = parent.node.setProperty(name, values[0], type);
- }
- }
-
- if (p != null) {
- changes.add(Modification.onModified(p.getPath()));
- }
- } else {
- if (multiValued) {
- parent.valueMap.put(name, toJavaObject(values, type));
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + name));
- } else if (values.length >= 1) {
- parent.valueMap.put(name, toJavaObject(values[0], type));
- changes.add(Modification.onModified(parent.resource.getPath() + '/' + name));
- }
- }
- }
-
- /** Converts a value */
- private static Object toJavaObject(final String value, final int type) {
- final boolean isEmpty = value == null || value.trim().length() == 0;
- switch (type) {
- case PropertyType.DECIMAL:
- return isEmpty ? BigDecimal.ZERO : new BigDecimal(value);
- case PropertyType.BOOLEAN:
- return isEmpty ? Boolean.FALSE : Boolean.valueOf(value);
- case PropertyType.DOUBLE:
- return isEmpty ? (double)0.0 : Double.valueOf(value);
- case PropertyType.LONG:
- return isEmpty ? 0 : Long.valueOf(value);
- default: // fallback
- return value;
- }
- }
-
- /** Converts a value */
- private static Object toJavaObject(final String values[], final int type) {
- final Object[] result = new Object[values.length];
- for (int i = 0; i < values.length; i++) {
- if (values[i] != null ) {
- result[i] = toJavaObject(values[i], type);
- }
- }
- return result;
- }
-
-
- /**
- * Defines an auto property behavior
- */
- private enum AutoType {
- CREATED,
- CREATED_BY,
- MODIFIED,
- MODIFIED_BY
- }
-
- public final static class Modifiable {
- public Resource resource;
- public ModifiableValueMap valueMap;
- public Node node;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
deleted file mode 100644
index d2b3902..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.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.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;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-
-/**
- * The <code>AbstractCopyMoveOperation</code> is the abstract base close for
- * the {@link CopyOperation} and {@link MoveOperation} classes implementing
- * commong behaviour.
- */
-abstract class AbstractCopyMoveOperation extends AbstractPostOperation {
-
- @Override
- protected final void doRun(SlingHttpServletRequest request,
- PostResponse response,
- List<Modification> changes)
- throws RepositoryException {
- Session session = request.getResourceResolver().adaptTo(Session.class);
-
- VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
-
- 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);
- dest = removeAndValidateWorkspace(dest, session);
-
- // 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);
- }
-
- } 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);
- }
-
- 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) {
- response.setStatus(HttpServletResponse.SC_NOT_FOUND,
- "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
- orderNode(request, destItem, changes);
- }
-
- /**
- * Returns a short name to be used in log and status messages.
- */
- protected abstract String getOperationName();
-
- /**
- * Actually executes the operation.
- *
- * @param response The <code>HtmlResponse</code> used to record success of
- * the operation.
- * @param source The source item to act upon.
- * @param destParent The absolute path of the parent of the target item.
- * @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
- * the operation.
- */
- protected abstract Item execute(List<Modification> changes, Item source,
- String destParent, String destName,
- VersioningConfiguration versioningConfiguration) throws RepositoryException;
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java
deleted file mode 100644
index 5db84c2..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * 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.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-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;
-import org.apache.sling.api.request.RequestParameterMap;
-import org.apache.sling.api.resource.ModifiableValueMap;
-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;
-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;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-import org.apache.sling.servlets.post.impl.helper.Chunk;
-import org.apache.sling.servlets.post.impl.helper.DefaultNodeNameGenerator;
-import org.apache.sling.servlets.post.impl.helper.RequestProperty;
-
-abstract class AbstractCreateOperation extends AbstractPostOperation {
- private final Random randomCollisionIndex = new Random();
-
- /**
- * The default node name generator
- */
- private NodeNameGenerator defaultNodeNameGenerator;
-
- /**
- * utility class for generating node names
- */
- private NodeNameGenerator[] extraNodeNameGenerators;
-
- /**
- * regular expression for parameters to ignore
- */
- private Pattern ignoredParameterNamePattern;
-
- protected AbstractCreateOperation() {
- this.defaultNodeNameGenerator = new DefaultNodeNameGenerator();
- this.ignoredParameterNamePattern = null;
- }
-
- public void setDefaultNodeNameGenerator(
- NodeNameGenerator defaultNodeNameGenerator) {
- this.defaultNodeNameGenerator = defaultNodeNameGenerator;
- }
-
- public void setExtraNodeNameGenerators(
- NodeNameGenerator[] extraNodeNameGenerators) {
- this.extraNodeNameGenerators = extraNodeNameGenerators;
- }
-
- public void setIgnoredParameterNamePattern(
- final Pattern ignoredParameterNamePattern) {
- this.ignoredParameterNamePattern = ignoredParameterNamePattern;
- }
-
- /**
- * Create node(s) according to current request
- *
- * @throws RepositoryException if a repository error occurs
- */
- protected void processCreate(final ResourceResolver resolver,
- final Map<String, RequestProperty> reqProperties,
- final PostResponse response,
- final List<Modification> changes,
- final VersioningConfiguration versioningConfiguration)
- throws PersistenceException, RepositoryException {
-
- final String path = response.getPath();
-
- if ( resolver.getResource(path) == null ) {
-
- deepGetOrCreateNode(resolver, path, reqProperties, changes, versioningConfiguration);
- response.setCreateRequest(true);
-
- } else {
- updateNodeType(resolver, path, reqProperties, changes, versioningConfiguration);
- updateMixins(resolver, path, reqProperties, changes, versioningConfiguration);
- }
- }
-
- protected void updateNodeType(final ResourceResolver resolver,
- final String path,
- final Map<String, RequestProperty> reqProperties,
- final List<Modification> changes,
- final VersioningConfiguration versioningConfiguration)
- throws RepositoryException {
- final String nodeType = getPrimaryType(reqProperties, path);
- if (nodeType != null) {
- final Resource rsrc = resolver.getResource(path);
- final ModifiableValueMap mvm = rsrc.adaptTo(ModifiableValueMap.class);
- if ( mvm != null ) {
- final Node node = rsrc.adaptTo(Node.class);
- final boolean wasVersionable = (node == null ? false : isVersionable(node));
-
- if ( node != null ) {
- checkoutIfNecessary(node, changes, versioningConfiguration);
- node.setPrimaryType(nodeType);
- } else {
- mvm.put("jcr:primaryType", nodeType);
- }
-
- if ( node != null ) {
- // this is a bit of a cheat; there isn't a formal checkout, but assigning
- // the mix:versionable mixin does an implicit checkout
- if (!wasVersionable &&
- versioningConfiguration.isCheckinOnNewVersionableNode() &&
- isVersionable(node)) {
- changes.add(Modification.onCheckout(path));
- }
- }
- }
- }
- }
-
- protected void updateMixins(final ResourceResolver resolver,
- final String path,
- final Map<String, RequestProperty> reqProperties,
- final List<Modification> changes,
- final VersioningConfiguration versioningConfiguration)
- throws RepositoryException {
- final String[] mixins = getMixinTypes(reqProperties, path);
- if (mixins != null) {
-
- final Resource rsrc = resolver.getResource(path);
- final ModifiableValueMap mvm = rsrc.adaptTo(ModifiableValueMap.class);
- if ( mvm != null ) {
- final Node node = rsrc.adaptTo(Node.class);
-
- final Set<String> newMixins = new HashSet<String>();
- newMixins.addAll(Arrays.asList(mixins));
-
- // clear existing mixins first
- if ( node != null ) {
- checkoutIfNecessary(node, changes, versioningConfiguration);
- for (NodeType mixin : node.getMixinNodeTypes()) {
- String mixinName = mixin.getName();
- if (!newMixins.remove(mixinName)) {
- node.removeMixin(mixinName);
- }
- }
-
- // add new mixins
- for (String mixin : newMixins) {
- node.addMixin(mixin);
- // this is a bit of a cheat; there isn't a formal checkout, but assigning
- // the mix:versionable mixin does an implicit checkout
- if (mixin.equals("mix:versionable") &&
- versioningConfiguration.isCheckinOnNewVersionableNode()) {
- changes.add(Modification.onCheckout(path));
- }
- }
- } else {
- mvm.put("jcr:mixinTypes", mixins);
- }
-
- }
- }
- }
-
- /**
- * Collects the properties that form the content to be written back to the
- * resource tree.
- *
- * @throws RepositoryException if a repository error occurs
- * @throws ServletException if an internal error occurs
- */
- protected Map<String, RequestProperty> collectContent(
- final SlingHttpServletRequest request,
- final PostResponse response) {
-
- final boolean requireItemPrefix = requireItemPathPrefix(request);
-
- // walk the request parameters and collect the properties
- final LinkedHashMap<String, RequestProperty> reqProperties = new LinkedHashMap<String, RequestProperty>();
- for (final Map.Entry<String, RequestParameter[]> e : request.getRequestParameterMap().entrySet()) {
- final String paramName = e.getKey();
-
- if (ignoreParameter(paramName)) {
- continue;
- }
-
- // skip parameters that do not start with the save prefix
- if (requireItemPrefix && !hasItemPathPrefix(paramName)) {
- continue;
- }
-
- // ensure the paramName is an absolute property name
- final String propPath = toPropertyPath(paramName, response);
-
- // @TypeHint example
- // <input type="text" name="./age" />
- // <input type="hidden" name="./age@TypeHint" value="long" />
- // causes the setProperty using the 'long' property type
- if (propPath.endsWith(SlingPostConstants.TYPE_HINT_SUFFIX)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.TYPE_HINT_SUFFIX);
-
- final RequestParameter[] rp = e.getValue();
- if (rp.length > 0) {
- prop.setTypeHintValue(rp[0].getString());
- }
-
- continue;
- }
-
- // @DefaultValue
- if (propPath.endsWith(SlingPostConstants.DEFAULT_VALUE_SUFFIX)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.DEFAULT_VALUE_SUFFIX);
-
- prop.setDefaultValues(e.getValue());
-
- continue;
- }
-
- // SLING-130: VALUE_FROM_SUFFIX means take the value of this
- // property from a different field
- // @ValueFrom example:
- // <input name="./Text@ValueFrom" type="hidden" value="fulltext" />
- // causes the JCR Text property to be set to the value of the
- // fulltext form field.
- if (propPath.endsWith(SlingPostConstants.VALUE_FROM_SUFFIX)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.VALUE_FROM_SUFFIX);
-
- // @ValueFrom params must have exactly one value, else ignored
- if (e.getValue().length == 1) {
- final String refName = e.getValue()[0].getString();
- final RequestParameter[] refValues = request.getRequestParameters(refName);
- if (refValues != null) {
- prop.setValues(refValues);
- }
- }
-
- continue;
- }
-
- // SLING-458: Allow Removal of properties prior to update
- // @Delete example:
- // <input name="./Text@Delete" type="hidden" />
- // causes the JCR Text property to be deleted before update
- if (propPath.endsWith(SlingPostConstants.SUFFIX_DELETE)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath, SlingPostConstants.SUFFIX_DELETE);
-
- prop.setDelete(true);
-
- continue;
- }
-
- // SLING-455: @MoveFrom means moving content to another location
- // @MoveFrom example:
- // <input name="./Text@MoveFrom" type="hidden" value="/tmp/path" />
- // causes the JCR Text property to be set by moving the /tmp/path
- // property to Text.
- if (propPath.endsWith(SlingPostConstants.SUFFIX_MOVE_FROM)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_MOVE_FROM);
-
- // @MoveFrom params must have exactly one value, else ignored
- if (e.getValue().length == 1) {
- final String sourcePath = e.getValue()[0].getString();
- prop.setRepositorySource(sourcePath, true);
- }
-
- continue;
- }
-
- // SLING-455: @CopyFrom means moving content to another location
- // @CopyFrom example:
- // <input name="./Text@CopyFrom" type="hidden" value="/tmp/path" />
- // causes the JCR Text property to be set by copying the /tmp/path
- // property to Text.
- if (propPath.endsWith(SlingPostConstants.SUFFIX_COPY_FROM)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_COPY_FROM);
-
- // @MoveFrom params must have exactly one value, else ignored
- if (e.getValue().length == 1) {
- final String sourcePath = e.getValue()[0].getString();
- prop.setRepositorySource(sourcePath, false);
- }
-
- continue;
- }
-
- // SLING-1412: @IgnoreBlanks
- // @Ignore example:
- // <input name="./Text" type="hidden" value="test" />
- // <input name="./Text" type="hidden" value="" />
- // <input name="./Text@String[]" type="hidden" value="true" />
- // <input name="./Text@IgnoreBlanks" type="hidden" value="true" />
- // causes the JCR Text property to be set by copying the /tmp/path
- // property to Text.
- if (propPath.endsWith(SlingPostConstants.SUFFIX_IGNORE_BLANKS)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_IGNORE_BLANKS);
-
- if (e.getValue().length == 1) {
- prop.setIgnoreBlanks(true);
- }
-
- continue;
- }
-
- if (propPath.endsWith(SlingPostConstants.SUFFIX_USE_DEFAULT_WHEN_MISSING)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_USE_DEFAULT_WHEN_MISSING);
-
- if (e.getValue().length == 1) {
- prop.setUseDefaultWhenMissing(true);
- }
-
- continue;
- }
- // @Patch
- // Example:
- // <input name="tags@TypeHint" value="String[]" type="hidden" />
- // <input name="tags@Patch" value="true" type="hidden" />
- // <input name="tags" value="+apple" type="hidden" />
- // <input name="tags" value="-orange" type="hidden" />
- if (propPath.endsWith(SlingPostConstants.SUFFIX_PATCH)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_PATCH);
-
- prop.setPatch(true);
-
- continue;
- }
- if (propPath.endsWith(SlingPostConstants.SUFFIX_OFFSET)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_OFFSET);
- if (e.getValue().length == 1) {
- Chunk chunk = prop.getChunk();
- if(chunk == null){
- chunk = new Chunk();
- }
- chunk.setOffsetValue(Long.parseLong(e.getValue()[0].toString()));
- prop.setChunk(chunk);
- }
- continue;
- }
-
- if (propPath.endsWith(SlingPostConstants.SUFFIX_COMPLETED)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_COMPLETED);
- if (e.getValue().length == 1) {
- Chunk chunk = prop.getChunk();
- if(chunk == null){
- chunk = new Chunk();
- }
- chunk.setCompleted(Boolean.parseBoolean((e.getValue()[0].toString())));
- prop.setChunk(chunk);
- }
- continue;
- }
-
- if (propPath.endsWith(SlingPostConstants.SUFFIX_LENGTH)) {
- final RequestProperty prop = getOrCreateRequestProperty(
- reqProperties, propPath,
- SlingPostConstants.SUFFIX_LENGTH);
- if (e.getValue().length == 1) {
- Chunk chunk = prop.getChunk();
- if(chunk == null){
- chunk = new Chunk();
- }
- chunk.setLength(Long.parseLong(e.getValue()[0].toString()));
- prop.setChunk(chunk);
- }
- continue;
- }
-
- // plain property, create from values
- final RequestProperty prop = getOrCreateRequestProperty(reqProperties,
- propPath, null);
- prop.setValues(e.getValue());
- }
-
- return reqProperties;
- }
-
- /**
- * Returns <code>true</code> if the parameter of the given name should be
- * ignored.
- */
- private boolean ignoreParameter(final String paramName) {
- // do not store parameters with names starting with sling:post
- if (paramName.startsWith(SlingPostConstants.RP_PREFIX)) {
- return true;
- }
-
- // SLING-298: skip form encoding parameter
- if (paramName.equals("_charset_")) {
- return true;
- }
-
- // SLING-2120: ignore parameter match ignoredParameterNamePattern
- if (this.ignoredParameterNamePattern != null
- && this.ignoredParameterNamePattern.matcher(paramName).matches()) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Returns the <code>paramName</code> as an absolute (unnormalized) property
- * path by prepending the response path (<code>response.getPath</code>) to
- * the parameter name if not already absolute.
- */
- private String toPropertyPath(String paramName, PostResponse response) {
- if (!paramName.startsWith("/")) {
- paramName = ResourceUtil.normalize(response.getPath() + '/' + paramName);
- }
-
- return paramName;
- }
-
- /**
- * Returns the request property for the given property path. If such a
- * request property does not exist yet it is created and stored in the
- * <code>props</code>.
- *
- * @param props The map of already seen request properties.
- * @param paramName The absolute path of the property including the
- * <code>suffix</code> to be looked up.
- * @param suffix The (optional) suffix to remove from the
- * <code>paramName</code> before looking it up.
- * @return The {@link RequestProperty} for the <code>paramName</code>.
- */
- private RequestProperty getOrCreateRequestProperty(
- Map<String, RequestProperty> props, String paramName, String suffix) {
- if (suffix != null && paramName.endsWith(suffix)) {
- paramName = paramName.substring(0, paramName.length()
- - suffix.length());
- }
-
- RequestProperty prop = props.get(paramName);
- if (prop == null) {
- prop = new RequestProperty(paramName);
- props.put(paramName, prop);
- }
-
- return prop;
- }
-
-
- /**
- * Deep gets or creates a node, parent-padding with default nodes nodes. If
- * the path is empty, the given parent node is returned.
- *
- * @param path path to node that needs to be deep-created
- * @param checkedOutNodes
- * @return node at path
- * @throws RepositoryException if an error occurs
- * @throws IllegalArgumentException if the path is relative and parent is
- * <code>null</code>
- */
- protected Resource deepGetOrCreateNode(final ResourceResolver resolver,
- final String path,
- final Map<String, RequestProperty> reqProperties,
- final List<Modification> changes,
- final VersioningConfiguration versioningConfiguration)
- throws PersistenceException, RepositoryException {
- if (log.isDebugEnabled()) {
- log.debug("Deep-creating resource '{}'", path);
- }
- if (path == null || !path.startsWith("/")) {
- throw new IllegalArgumentException("path must be an absolute path.");
- }
- // get the starting resource
- String startingResourcePath = path;
- Resource startingResource = null;
- while (startingResource == null) {
- if (startingResourcePath.equals("/")) {
- startingResource = resolver.getResource("/");
- if (startingResource == null){
- throw new PersistenceException("Access denied for root resource, resource can't be created: " + path);
- }
- } else if (resolver.getResource(startingResourcePath) != null) {
- startingResource = resolver.getResource(startingResourcePath);
- updateNodeType(resolver, startingResourcePath, reqProperties, changes, versioningConfiguration);
- updateMixins(resolver, startingResourcePath, reqProperties, changes, versioningConfiguration);
- } else {
- int pos = startingResourcePath.lastIndexOf('/');
- if (pos > 0) {
- startingResourcePath = startingResourcePath.substring(0, pos);
- } else {
- startingResourcePath = "/";
- }
- }
- }
- // is the searched resource already existing?
- if (startingResourcePath.length() == path.length()) {
- return startingResource;
- }
- // create nodes
- int from = (startingResourcePath.length() == 1
- ? 1
- : startingResourcePath.length() + 1);
- Resource resource = startingResource;
- while (from > 0) {
- final int to = path.indexOf('/', from);
- final String name = to < 0 ? path.substring(from) : path.substring(
- from, to);
- // although the resource should not exist (according to the first test
- // above)
- // we do a sanety check.
- if (resource.getChild(name) != null) {
- resource = resource.getChild(name);
- updateNodeType(resolver, resource.getPath(), reqProperties, changes, versioningConfiguration);
- updateMixins(resolver, resource.getPath(), reqProperties, changes, versioningConfiguration);
- } else {
- final String tmpPath = to < 0 ? path : path.substring(0, to);
- // check for node type
- final String nodeType = getPrimaryType(reqProperties, tmpPath);
-
- final Node node = resource.adaptTo(Node.class);
- if ( node != null ) {
- checkoutIfNecessary(node, changes, versioningConfiguration);
- }
-
- try {
- final Map<String, Object> props = new HashMap<String, Object>();
- if (nodeType != null) {
- props.put("jcr:primaryType", nodeType);
- }
- // check for mixin types
- final String[] mixinTypes = getMixinTypes(reqProperties,
- tmpPath);
- if (mixinTypes != null) {
- props.put("jcr:mixinTypes", mixinTypes);
- }
-
- resource = resolver.create(resource, name, props);
- } catch (final PersistenceException e) {
- log.error("Unable to create resource named " + name + " in " + resource.getPath());
- throw e;
- }
- changes.add(Modification.onCreated(resource.getPath()));
- }
- from = to + 1;
- }
- return resource;
- }
-
- /**
- * Checks the collected content for a jcr:primaryType property at the
- * specified path.
- *
- * @param path path to check
- * @return the primary type or <code>null</code>
- */
- private String getPrimaryType(Map<String, RequestProperty> reqProperties,
- String path) {
- RequestProperty prop = reqProperties.get(path + "/jcr:primaryType");
- return prop == null ? null : prop.getStringValues()[0];
- }
-
- /**
- * Checks the collected content for a jcr:mixinTypes property at the
- * specified path.
- *
- * @param path path to check
- * @return the mixin types or <code>null</code>
- */
- private String[] getMixinTypes(Map<String, RequestProperty> reqProperties,
- String path) {
- RequestProperty prop = reqProperties.get(path + "/jcr:mixinTypes");
- return (prop == null) || !prop.hasValues() ? null : prop.getStringValues();
- }
-
-
- protected String generateName(SlingHttpServletRequest request, String basePath)
- throws RepositoryException {
-
- // SLING-1091: If a :name parameter is supplied, the (first) value of this parameter is used unmodified as the name
- // for the new node. If the name is illegally formed with respect to JCR name requirements, an exception will be
- // thrown when trying to create the node. The assumption with the :name parameter is, that the caller knows what
- // he (or she) is supplying and should get the exact result if possible.
- RequestParameterMap parameters = request.getRequestParameterMap();
- RequestParameter specialParam = parameters.getValue(SlingPostConstants.RP_NODE_NAME);
- if ( specialParam != null ) {
- if ( specialParam.getString() != null && specialParam.getString().length() > 0 ) {
- // If the path ends with a *, create a node under its parent, with
- // a generated node name
- 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) {
- throw new RepositoryException(
- "Collision in node names for path=" + basePath);
- }
-
- return basePath;
- }
- }
-
- // no :name value was supplied, so generate a name
- boolean requirePrefix = requireItemPathPrefix(request);
-
- String generatedName = null;
- if (extraNodeNameGenerators != null) {
- for (NodeNameGenerator generator : extraNodeNameGenerators) {
- generatedName = generator.getNodeName(request, basePath, requirePrefix, defaultNodeNameGenerator);
- if (generatedName != null) {
- break;
- }
- }
- }
- if (generatedName == null) {
- generatedName = defaultNodeNameGenerator.getNodeName(request, basePath, requirePrefix, defaultNodeNameGenerator);
- }
-
- // If the path ends with a *, create a node under its parent, with
- // a generated node name
- basePath += "/" + generatedName;
-
- basePath = ensureUniquePath(request, basePath);
-
- return basePath;
- }
-
- /** Generate a unique path in case the node name generator didn't */
- 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 ) {
- for(int i=0; i < MAX_TRIES; i++) {
- final int uniqueIndex = Math.abs(randomCollisionIndex.nextInt());
- String newPath = jcrPath + "_" + uniqueIndex;
- if (resolver.getResource(newPath) == null) {
- basePath = basePath + "_" + uniqueIndex;
- jcrPath = newPath;
- break;
- }
- }
-
- // Give up after MAX_TRIES
- if (resolver.getResource(jcrPath) != null ) {
- throw new RepositoryException(
- "Collision in generated node names under " + basePath + ", generated path " + jcrPath + " already exists");
- }
- }
-
- return basePath;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
deleted file mode 100644
index 3aca8c8..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.servlet.http.HttpServletResponse;
-
-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;
-
-/**
- * The <code>CheckinOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_CHECKIN checkin}
- * operation for the Sling default POST servlet.
- */
-public class CheckinOperation extends AbstractPostOperation {
-
- @Override
- protected void doRun(SlingHttpServletRequest request, PostResponse response, List<Modification> changes)
- throws RepositoryException {
- 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();
- Node node = resource.adaptTo(Node.class);
- if (node != null) {
- node.checkin();
- changes.add(Modification.onCheckin(resource.getPath()));
- }
- }
-
- }
-
- }
-
- /**
- * Checkin operation always checks in.
- */
- @Override
- protected boolean isSkipCheckin(SlingHttpServletRequest request) {
- return false;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
deleted file mode 100644
index a0cb1a3..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.servlet.http.HttpServletResponse;
-
-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;
-
-/**
- * The <code>CheckoutOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_CHECKOUT checkout}
- * operation for the Sling default POST servlet.
- */
-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) {
-
- 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();
- Node node = resource.adaptTo(Node.class);
- if (node != null) {
- node.checkout();
- changes.add(Modification.onCheckout(resource.getPath()));
- }
- }
-
- }
-
- }
-
- /**
- * Checkout operation is always skipping checkin.
- */
- @Override
- protected boolean isSkipCheckin(SlingHttpServletRequest request) {
- return true;
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
deleted file mode 100644
index 0530965..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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.Item;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.sling.servlets.post.Modification;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-
-/**
- * The <code>CopyOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_COPY copy}
- * operation for the Sling default POST servlet.
- */
-public class CopyOperation extends AbstractCopyMoveOperation {
-
- @Override
- protected String getOperationName() {
- return "copy";
- }
-
- @Override
- protected Item execute(List<Modification> changes, Item source,
- String destParent, String destName,
- VersioningConfiguration versioningConfiguration) throws RepositoryException {
-
- Item destItem = copy(source, (Node) source.getSession().getItem(destParent), destName);
-
- String dest = destParent + "/" + destName;
- changes.add(Modification.onCopied(source.getPath(), dest));
- log.debug("copy {} to {}", source, dest);
- return destItem;
- }
-
- /**
- * Copy the <code>src</code> item into the <code>dstParent</code> node.
- * The name of the newly created item is set to <code>name</code>.
- *
- * @param src The item to copy to the new location
- * @param dstParent The node into which the <code>src</code> node is to be
- * copied
- * @param name The name of the newly created item. If this is
- * <code>null</code> the new item gets the same name as the
- * <code>src</code> item.
- * @throws RepositoryException May be thrown in case of any problem copying
- * the content.
- * @see #copy(Node, Node, String)
- * @see #copy(Property, Node, String)
- */
- static Item copy(Item src, Node dstParent, String name)
- throws RepositoryException {
- if (src.isNode()) {
- return copy((Node) src, dstParent, name);
- }
- return copy((Property) src, dstParent, name);
- }
-
- /**
- * Copy the <code>src</code> node into the <code>dstParent</code> node.
- * The name of the newly created node is set to <code>name</code>.
- * <p>
- * This method does a recursive (deep) copy of the subtree rooted at the
- * source node to the destination. Any protected child nodes and and
- * properties are not copied.
- *
- * @param src The node to copy to the new location
- * @param dstParent The node into which the <code>src</code> node is to be
- * copied
- * @param name The name of the newly created node. If this is
- * <code>null</code> the new node gets the same name as the
- * <code>src</code> node.
- * @throws RepositoryException May be thrown in case of any problem copying
- * the content.
- */
- static Item copy(Node src, Node dstParent, String name)
- throws RepositoryException {
-
- if(isAncestorOrSameNode(src, dstParent)) {
- throw new RepositoryException(
- "Cannot copy ancestor " + src.getPath() + " to descendant " + dstParent.getPath());
- }
-
- // ensure destination name
- if (name == null) {
- name = src.getName();
- }
-
- // ensure new node creation
- if (dstParent.hasNode(name)) {
- dstParent.getNode(name).remove();
- }
-
- // create new node
- Node dst = dstParent.addNode(name, src.getPrimaryNodeType().getName());
- for (NodeType mix : src.getMixinNodeTypes()) {
- dst.addMixin(mix.getName());
- }
-
- // copy the properties
- for (PropertyIterator iter = src.getProperties(); iter.hasNext();) {
- copy(iter.nextProperty(), dst, null);
- }
-
- // copy the child nodes
- for (NodeIterator iter = src.getNodes(); iter.hasNext();) {
- Node n = iter.nextNode();
- if (!n.getDefinition().isProtected()) {
- copy(n, dst, null);
- }
- }
- 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 {
- if(src.getPath().equals("/")) {
- return true;
- } else if(src.getPath().equals(dest.getPath())) {
- return true;
- } else if(dest.getPath().startsWith(src.getPath() + "/")) {
- return true;
- }
- return false;
- }
-
- /**
- * Copy the <code>src</code> property into the <code>dstParent</code>
- * node. The name of the newly created property is set to <code>name</code>.
- * <p>
- * If the source property is protected, this method does nothing.
- *
- * @param src The property to copy to the new location
- * @param dstParent The node into which the <code>src</code> property is
- * to be copied
- * @param name The name of the newly created property. If this is
- * <code>null</code> the new property gets the same name as the
- * <code>src</code> property.
- * @throws RepositoryException May be thrown in case of any problem copying
- * the content.
- */
- static Item copy(Property src, Node dstParent, String name)
- throws RepositoryException {
- if (!src.getDefinition().isProtected()) {
- if (name == null) {
- name = src.getName();
- }
-
- // ensure new property creation
- if (dstParent.hasProperty(name)) {
- dstParent.getProperty(name).remove();
- }
-
- if (src.getDefinition().isMultiple()) {
- return dstParent.setProperty(name, src.getValues());
- }
- return dstParent.setProperty(name, src.getValue());
- }
- return null;
- }
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
deleted file mode 100644
index ed23eae..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-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;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-import org.apache.sling.servlets.post.impl.helper.SlingFileUploadHandler;
-
-/**
- * The <code>DeleteOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_DELETE
- * delete} operation for the Sling default POST servlet.
- */
-public class DeleteOperation extends AbstractPostOperation {
-
- /**
- * handler that deals with file upload
- */
- private final SlingFileUploadHandler uploadHandler;
-
- public DeleteOperation() {
- this.uploadHandler = new SlingFileUploadHandler();
- }
-
- @Override
- protected void doRun(final SlingHttpServletRequest request,
- final PostResponse response, final List<Modification> changes)
- throws RepositoryException {
-
- // SLING-3203: selectors, extension and suffix make no sense here and
- // might lead to deleting other resources than the one the user means.
- final RequestPathInfo rpi = request.getRequestPathInfo();
- if( (rpi.getSelectors() != null && rpi.getSelectors().length > 0)
- || (rpi.getExtension() != null && rpi.getExtension().length() > 0)
- || (rpi.getSuffix() != null && rpi.getSuffix().length() > 0)) {
- response.setStatus(
- HttpServletResponse.SC_FORBIDDEN,
- "DeleteOperation request cannot include any selectors, extension or suffix");
- return;
- }
-
- 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();
- deleteResource(resource, changes, versioningConfiguration,
- deleteChunks);
- }
-
- }
- }
-
- /**
- * Delete chunks if
- * {@link DeleteOperation#isDeleteChunkRequest(SlingHttpServletRequest)} is
- * true otherwise delete resource.
- */
- private void deleteResource(final Resource resource,
- final List<Modification> changes,
- VersioningConfiguration versioningConfiguration,
- boolean deleteChunks) throws RepositoryException {
- final Node node = resource.adaptTo(Node.class);
- if (node != null) {
- if (deleteChunks) {
- uploadHandler.deleteChunks(node);
- } else {
- checkoutIfNecessary(node.getParent(), changes,
- versioningConfiguration);
- node.remove();
- }
-
- } else {
- try {
- resource.getResourceResolver().delete(resource);
- } catch (final PersistenceException pe) {
- if (pe.getCause() instanceof RepositoryException) {
- throw (RepositoryException) pe.getCause();
- }
- throw new RepositoryException(pe);
- }
- }
- changes.add(Modification.onDeleted(resource.getPath()));
- }
-
- /**
- * Return true if request is to delete chunks. To return true, request will
- * should parameter ":applyToChunks" and it should be true.
- */
- protected boolean isDeleteChunkRequest(SlingHttpServletRequest request) {
-
- return Boolean.parseBoolean(request.getParameter(SlingPostConstants.RP_APPLY_TO_CHUNKS));
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
deleted file mode 100644
index dba0934..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ImportOperation.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * 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.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-
-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.request.RequestParameter;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.jcr.contentloader.ContentImportListener;
-import org.apache.sling.jcr.contentloader.ContentImporter;
-import org.apache.sling.jcr.contentloader.ImportOptions;
-import org.apache.sling.servlets.post.Modification;
-import org.apache.sling.servlets.post.ModificationType;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-import org.apache.sling.servlets.post.impl.helper.RequestProperty;
-
-/**
- * The <code>ImportOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_IMPORT}
- * import operation for the Sling default POST servlet.
- */
-public class ImportOperation extends AbstractCreateOperation {
-
- /**
- * Reference to the content importer service
- */
- private ContentImporter contentImporter;
-
- public void setContentImporter(ContentImporter importer) {
- this.contentImporter = importer;
- }
-
- private String getRequestParamAsString(SlingHttpServletRequest request, String key) {
- RequestParameter requestParameter = request.getRequestParameter(key);
- if (requestParameter == null) {
- return null;
- }
- return requestParameter.getString();
- }
-
- @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);
-
- 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);
- basePath = removeAndValidateWorkspace(basePath, request.getResourceResolver().adaptTo(Session.class));
- 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");
- 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() {
-
- public void onReorder(String orderedPath, String beforeSibbling) {
- changes.add(Modification.onOrder(orderedPath, beforeSibbling));
- }
-
- public void onMove(String srcPath, String destPath) {
- changes.add(Modification.onMoved(srcPath, destPath));
- }
-
- public void onModify(String srcPath) {
- changes.add(Modification.onModified(srcPath));
- }
-
- public void onDelete(String srcPath) {
- changes.add(Modification.onDeleted(srcPath));
- }
-
- public void onCreate(String srcPath) {
- changes.add(Modification.onCreated(srcPath));
- }
-
- public void onCopy(String srcPath, String destPath) {
- changes.add(Modification.onCopied(srcPath, destPath));
- }
-
- public void onCheckin(String srcPath) {
- changes.add(Modification.onCheckin(srcPath));
- }
- 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 RepositoryException(e);
- }
- }
-}
\ No newline at end of file
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
deleted file mode 100644
index 19fbdab..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * 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 java.util.Map;
-
-import javax.jcr.Item;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.servlet.ServletContext;
-
-import org.apache.sling.api.SlingException;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.resource.ModifiableValueMap;
-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;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.servlets.post.Modification;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-import org.apache.sling.servlets.post.impl.helper.DateParser;
-import org.apache.sling.servlets.post.impl.helper.ReferenceParser;
-import org.apache.sling.servlets.post.impl.helper.RequestProperty;
-import org.apache.sling.servlets.post.impl.helper.SlingFileUploadHandler;
-import org.apache.sling.servlets.post.impl.helper.SlingPropertyValueHandler;
-
-/**
- * The <code>ModifyOperation</code> class implements the default operation
- * called by the Sling default POST servlet if no operation is requested by the
- * client. This operation is able to create and/or modify content.
- */
-public class ModifyOperation extends AbstractCreateOperation {
-
- private DateParser dateParser;
-
- /**
- * handler that deals with file upload
- */
- private final SlingFileUploadHandler uploadHandler;
-
- public ModifyOperation() {
- this.dateParser = new DateParser();
- this.uploadHandler = new SlingFileUploadHandler();
- }
-
- public void setServletContext(final ServletContext servletContext) {
- this.uploadHandler.setServletContext(servletContext);
- }
-
- public void setDateParser(final DateParser dateParser) {
- this.dateParser = dateParser;
- }
-
- @Override
- protected void doRun(final SlingHttpServletRequest request,
- final PostResponse response,
- final List<Modification> changes)
- throws RepositoryException {
-
- try {
- final Map<String, RequestProperty> reqProperties = collectContent(request, response);
-
- final VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
-
- // do not change order unless you have a very good reason.
-
- // ensure root of new content
- processCreate(request.getResourceResolver(), reqProperties, response, changes, versioningConfiguration);
-
- // write content from existing content (@Move/CopyFrom parameters)
- processMoves(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);
- processCopies(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);
-
- // cleanup any old content (@Delete parameters)
- processDeletes(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);
-
- // write content from form
- writeContent(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);
-
- // 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);
- }
- }
-
- @Override
- protected String getItemPath(SlingHttpServletRequest request) {
-
- // calculate the paths
- StringBuilder rootPathBuf = new StringBuilder();
- String suffix;
- Resource currentResource = request.getResource();
- if (ResourceUtil.isSyntheticResource(currentResource)) {
-
- // no resource, treat the missing resource path as suffix
- suffix = currentResource.getPath();
-
- } else {
-
- // resource for part of the path, use request suffix
- suffix = request.getRequestPathInfo().getSuffix();
-
- if (suffix != null) {
- // cut off any selectors/extension from the suffix
- int dotPos = suffix.indexOf('.');
- if (dotPos > 0) {
- suffix = suffix.substring(0, dotPos);
- }
- }
-
- // and preset the path buffer with the resource path
- rootPathBuf.append(currentResource.getPath());
-
- }
-
- // check for extensions or create suffix in the suffix
- boolean doGenerateName = false;
- if (suffix != null) {
-
- // check whether it is a create request (trailing /)
- if (suffix.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX)) {
- suffix = suffix.substring(0, suffix.length()
- - SlingPostConstants.DEFAULT_CREATE_SUFFIX.length());
- doGenerateName = true;
-
- // or with the star suffix /*
- } else if (suffix.endsWith(SlingPostConstants.STAR_CREATE_SUFFIX)) {
- suffix = suffix.substring(0, suffix.length()
- - SlingPostConstants.STAR_CREATE_SUFFIX.length());
- doGenerateName = true;
- }
-
- // append the remains of the suffix to the path buffer
- rootPathBuf.append(suffix);
-
- }
-
- String path = rootPathBuf.toString();
-
- if (doGenerateName) {
- try {
- path = generateName(request, path);
- } catch (RepositoryException re) {
- throw new SlingException("Failed to generate name", re);
- }
- }
-
- return path;
- }
-
- /**
- * Moves all repository content listed as repository move source in the
- * request properties to the locations indicated by the resource properties.
- * @param checkedOutNodes
- */
- private void processMoves(final ResourceResolver resolver,
- Map<String, RequestProperty> reqProperties, List<Modification> changes,
- VersioningConfiguration versioningConfiguration)
- throws RepositoryException, PersistenceException {
-
- for (RequestProperty property : reqProperties.values()) {
- if (property.hasRepositoryMoveSource()) {
- processMovesCopiesInternal(property, true, resolver,
- reqProperties, changes, versioningConfiguration);
- }
- }
- }
-
- /**
- * Copies all repository content listed as repository copy source in the
- * request properties to the locations indicated by the resource properties.
- * @param checkedOutNodes
- */
- private void processCopies(final ResourceResolver resolver,
- Map<String, RequestProperty> reqProperties, List<Modification> changes,
- VersioningConfiguration versioningConfiguration)
- throws RepositoryException, PersistenceException {
-
- for (RequestProperty property : reqProperties.values()) {
- if (property.hasRepositoryCopySource()) {
- processMovesCopiesInternal(property, false, resolver,
- reqProperties, changes, versioningConfiguration);
- }
- }
- }
-
- /**
- * Internal implementation of the
- * {@link #processCopies(Session, Map, HtmlResponse)} and
- * {@link #processMoves(Session, Map, HtmlResponse)} methods taking into
- * account whether the source is actually a property or a node.
- * <p>
- * Any intermediary nodes to the destination as indicated by the
- * <code>property</code> path are created using the
- * <code>reqProperties</code> as indications for required node types.
- *
- * @param property The {@link RequestProperty} identifying the source
- * content of the operation.
- * @param isMove <code>true</code> if the source item is to be moved.
- * Otherwise the source item is just copied.
- * @param session The repository session to use to access the content
- * @param reqProperties All accepted request properties. This is used to
- * create intermediary nodes along the property path.
- * @param response The <code>HtmlResponse</code> into which successfull
- * copies and moves as well as intermediary node creations are
- * recorded.
- * @throws RepositoryException May be thrown if an error occurrs.
- */
- private void processMovesCopiesInternal(
- RequestProperty property,
- boolean isMove, final ResourceResolver resolver,
- Map<String, RequestProperty> reqProperties, List<Modification> changes,
- VersioningConfiguration versioningConfiguration)
- throws RepositoryException, PersistenceException {
-
- final Session session = resolver.adaptTo(Session.class);
- String propPath = property.getPath();
- String source = property.getRepositorySource();
-
- // only continue here, if the source really exists
- if (session.itemExists(source)) {
-
- // if the destination item already exists, remove it
- // first, otherwise ensure the parent location
- if (session.itemExists(propPath)) {
- Node parent = session.getItem(propPath).getParent();
- checkoutIfNecessary(parent, changes, versioningConfiguration);
-
- session.getItem(propPath).remove();
- changes.add(Modification.onDeleted(propPath));
- } else {
- Resource parent = deepGetOrCreateNode(resolver, property.getParentPath(),
- reqProperties, changes, versioningConfiguration);
- final Node node = parent.adaptTo(Node.class);
- if ( node != null ) {
- checkoutIfNecessary(node, changes, versioningConfiguration);
- }
- }
-
- // move through the session and record operation
- Item sourceItem = session.getItem(source);
- if (sourceItem.isNode()) {
-
- // node move/copy through session
- if (isMove) {
- checkoutIfNecessary(sourceItem.getParent(), changes, versioningConfiguration);
- session.move(source, propPath);
- } else {
- Node sourceNode = (Node) sourceItem;
- Node destParent = (Node) session.getItem(property.getParentPath());
- checkoutIfNecessary(destParent, changes, versioningConfiguration);
- CopyOperation.copy(sourceNode, destParent,
- property.getName());
- }
-
- } else {
-
- // property move manually
- Property sourceProperty = (Property) sourceItem;
-
- // create destination property
- Node destParent = (Node) session.getItem(property.getParentPath());
- checkoutIfNecessary(destParent, changes, versioningConfiguration);
- CopyOperation.copy(sourceProperty, destParent, null);
-
- // remove source property (if not just copying)
- if (isMove) {
- checkoutIfNecessary(sourceProperty.getParent(), changes, versioningConfiguration);
- sourceProperty.remove();
- }
- }
-
- // make sure the property is not deleted even in case for a given
- // property both @MoveFrom and @Delete is set
- property.setDelete(false);
-
- // record successful move
- if (isMove) {
- changes.add(Modification.onMoved(source, propPath));
- } else {
- changes.add(Modification.onCopied(source, propPath));
- }
- }
- }
-
- /**
- * Removes all properties listed as {@link RequestProperty#isDelete()} from
- * the resource.
- *
- * @param resolver The <code>ResourceResolver</code> used to access the
- * resources to delete the properties.
- * @param reqProperties The map of request properties to check for
- * properties to be removed.
- * @param response The <code>HtmlResponse</code> to be updated with
- * information on deleted properties.
- * @throws RepositoryException Is thrown if an error occurrs checking or
- * removing properties.
- */
- private void processDeletes(final ResourceResolver resolver,
- final Map<String, RequestProperty> reqProperties,
- final List<Modification> changes,
- final VersioningConfiguration versioningConfiguration)
- throws RepositoryException, PersistenceException {
-
- for (final RequestProperty property : reqProperties.values()) {
-
- if (property.isDelete()) {
- final Resource parent = resolver.getResource(property.getParentPath());
- if ( parent == null ) {
- continue;
- }
- final Node parentNode = parent.adaptTo(Node.class);
-
- if ( parentNode != null ) {
- checkoutIfNecessary(parentNode, changes, versioningConfiguration);
-
- if (property.getName().equals("jcr:mixinTypes")) {
-
- // clear all mixins
- for (NodeType mixin : parentNode.getMixinNodeTypes()) {
- parentNode.removeMixin(mixin.getName());
- }
-
- } else {
- if ( parentNode.hasProperty(property.getName())) {
- parentNode.getProperty(property.getName()).remove();
- } else if ( parentNode.hasNode(property.getName())) {
- parentNode.getNode(property.getName()).remove();
- }
- }
-
- } else {
- final ValueMap vm = parent.adaptTo(ModifiableValueMap.class);
- if ( vm == null ) {
- throw new PersistenceException("Resource '" + parent.getPath() + "' is not modifiable.");
- }
- vm.remove(property.getName());
- }
-
- changes.add(Modification.onDeleted(property.getPath()));
- }
- }
-
- }
-
- /**
- * Writes back the content
- *
- * @throws RepositoryException if a repository error occurs
- * @throws PersistenceException if a persistence error occurs
- */
- private void writeContent(final ResourceResolver resolver,
- final Map<String, RequestProperty> reqProperties,
- final List<Modification> changes,
- final VersioningConfiguration versioningConfiguration)
- throws RepositoryException, PersistenceException {
-
- final SlingPropertyValueHandler propHandler = new SlingPropertyValueHandler(
- dateParser, new ReferenceParser(resolver.adaptTo(Session.class)), changes);
-
- for (final RequestProperty prop : reqProperties.values()) {
- if (prop.hasValues()) {
- final Resource parent = deepGetOrCreateNode(resolver,
- prop.getParentPath(), reqProperties, changes, versioningConfiguration);
-
- final Node parentNode = parent.adaptTo(Node.class);
- if ( parentNode != null ) {
- checkoutIfNecessary(parentNode, changes, versioningConfiguration);
- }
-
- // skip jcr special properties
- if (prop.getName().equals("jcr:primaryType")
- || prop.getName().equals("jcr:mixinTypes")) {
- continue;
- }
-
- if (prop.isFileUpload()) {
- uploadHandler.setFile(parent, prop, changes);
- } else {
- propHandler.setProperty(parent, prop);
- }
- }
- }
- }
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
deleted file mode 100644
index 1a680ef..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.Item;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.sling.servlets.post.Modification;
-import org.apache.sling.servlets.post.VersioningConfiguration;
-
-/**
- * The <code>MoveOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_MOVE move}
- * operation for the Sling default POST servlet.
- */
-public class MoveOperation extends AbstractCopyMoveOperation {
-
- @Override
- protected String getOperationName() {
- return "move";
- }
-
- @Override
- protected Item execute(List<Modification> changes, Item source,
- String destParent, String destName,
- VersioningConfiguration versioningConfiguration) throws RepositoryException {
-
- if (destName == null) {
- destName = source.getName();
- }
-
- String sourcePath = source.getPath();
- if (destParent.equals("/")) {
- destParent = "";
- }
- String destPath = destParent + "/" + destName;
- Session session = source.getSession();
-
- checkoutIfNecessary(source.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);
- }
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/NopOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/NopOperation.java
deleted file mode 100644
index e4e6f8a..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/NopOperation.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.PostOperation;
-import org.apache.sling.servlets.post.SlingPostProcessor;
-
-/**
- * The <code>NopOperation</code> class implements no operation at all. It just
- * sets the response status accroding to the <i>:nopstatus</i> parameter if
- * availables. Otherwise the status is set as 200/OK.
- */
-public class NopOperation implements PostOperation {
-
- public void run(SlingHttpServletRequest request, PostResponse response,
- SlingPostProcessor[] processors) {
-
- // get the :nopstatus parameter for a specific code
- int status = SlingPostConstants.NOPSTATUS_VALUE_DEFAULT;
- String nopStatusString = request.getParameter(SlingPostConstants.RP_NOP_STATUS);
- if (nopStatusString != null) {
- try {
- int nopStatusPar = Integer.parseInt(nopStatusString);
- if (nopStatusPar >= 100 && nopStatusPar <= 999) {
- status = nopStatusPar;
- }
- } catch (NumberFormatException nfe) {
- // illegal number, use default
- }
- }
-
- response.setStatus(status, "Null Operation Status: " + status);
- }
-
-}
diff --git a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java b/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
deleted file mode 100644
index 4a6c16b..0000000
--- a/post/src/main/java/org/apache/sling/servlets/post/impl/operations/RestoreOperation.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionManager;
-import javax.servlet.http.HttpServletResponse;
-
-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;
-
-/**
- * The <code>RestoreOperation</code> class implements the
- * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_RESTORE restore}
- * operation for the Sling default POST servlet.
- */
-public class RestoreOperation extends AbstractPostOperation {
-
- @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;
- }
- 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));
- }
- }
- }
- }
-
- private void restore(Node node, String versionSpecifier, boolean removeExisting)
- throws RepositoryException {
- final VersionManager vm = node.getSession().getWorkspace().getVersionManager();
- final VersionHistory history = vm.getVersionHistory(node.getPath());
- final Version version;
- if (history.hasVersionLabel(versionSpecifier)) {
- version = history.getVersionByLabel(versionSpecifier);
- } else if (history.hasNode(versionSpecifier)) {
- version = history.getVersion(versionSpecifier);
- } else {
- throw new IllegalArgumentException("Unable to process restore. Invalid version: "
- + versionSpecifier);
- }
- vm.restore(version, removeExisting);
- }
-}
diff --git a/post/src/main/resources/OSGI-INF/metatype/metatype.properties b/post/src/main/resources/OSGI-INF/metatype/metatype.properties
deleted file mode 100644
index 11e9dec..0000000
--- a/post/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# 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.
-#
-
-
-#
-# This file contains localization strings for configuration labels and
-# descriptions as used in the metatype.xml descriptor generated by the
-# the Sling SCR plugin
-
-servlet.post.name = Apache Sling POST Servlet
-servlet.post.description = The Sling POST Servlet is registered as the default \
- servlet to handle POST requests in Sling.
-servlet.post.dateFormats.name = Date Format
-servlet.post.dateFormats.description = List SimpleDateFormat strings for date \
- formats supported for parsing from request input to data fields. The special \
- format "ISO8601" (without the quotes) can be used to designate strict ISO-8601 \
- parser which is able to parse strings generated by the Property.getString() \
- method for Date properties. The default \
- value is [ "EEE MMM dd yyyy HH:mm:ss 'GMT'Z", "ISO8601", \
- "yyyy-MM-dd'T'HH:mm:ss.SSSZ", \
- "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd", "dd.MM.yyyy HH:mm:ss", "dd.MM.yyyy" ].
-servlet.post.nodeNameHints.name = Node Name Hint Properties
-servlet.post.nodeNameHints.description = The list of properties whose values \
- may be used to derive a name for newly created nodes. When handling a request \
- to create a new node, the name of the node is automatically generated if the \
- request URL ends with a star ("*") or a slash ("/"). In this case the request \
- parameters listed in this configuration value may be used to create the name. \
- Default value is [ "title", "jcr:title", "name", "description", \
- "jcr:description", "abstract", "text", "jcr:text" ].
-servlet.post.nodeNameMaxLength.name = Maximum Node Name Length
-servlet.post.nodeNameMaxLength.description = Maximum number of characters to \
- use for automatically generated node names. The default value is 20. Note, \
- that actual node names may be generated with at most 4 more characters if the \
- numeric suffixes must be appended to make the name unique.
-servlet.post.checkinNewVersionableNodes.name = Checkin New Versionable Nodes
-servlet.post.checkinNewVersionableNodes.description = If true, newly created \
- versionable nodes or non-versionable nodes which are made versionable by the \
- addition of the mix:versionable mixin are checked in. By default, false.
-servlet.post.autoCheckout.name = Auto Checkout Nodes
-servlet.post.autoCheckout.description = If true, checked in nodes are \
- checked out when necessary. By default, false.
-servlet.post.autoCheckin.name = Auto Checkin Nodes
-servlet.post.autoCheckin.description = If true, nodes which are checked out \
- by the post servlet are checked in. By default, true.
-servlet.post.ignorePattern.name = Ignored Parameters
-servlet.post.ignorePattern.description = Configures a regular expression \
- pattern to select request parameters which should be ignored when wrinting \
- content to the repository. By default this is "j_.*" thus ignoring all \
- request parameters starting with j_ such as j_username.
\ No newline at end of file
diff --git a/post/src/main/resources/SLING-INF/nodetypes/chunk.cnd b/post/src/main/resources/SLING-INF/nodetypes/chunk.cnd
deleted file mode 100644
index 5f5afab..0000000
--- a/post/src/main/resources/SLING-INF/nodetypes/chunk.cnd
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// 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.
-//
-
-<sling = 'http://sling.apache.org/jcr/sling/1.0'>
-
-//-----------------------------------------------------------------------------
-// node type to store chunk
-// offset: offset of chunk in file
-// jcr:data: binary of chunk
-[sling:chunk] > nt:hierarchyNode
- primaryitem jcr:data
- - sling:offset (long) mandatory
- - jcr:data (binary) mandatory
-
- //-----------------------------------------------------------------------------
- // Mixin type to identify that a node has chunks
- // sling:fileLength : length of complete file
- // sling:length: cumulative length of all uploaded chunks
-[sling:chunks]
- mixin
- - sling:fileLength (long)
- - sling:length (long)
- + * (sling:chunk) multiple
diff --git a/post/src/main/resources/org/apache/sling/servlets/post/HtmlNoGoBackResponse.html b/post/src/main/resources/org/apache/sling/servlets/post/HtmlNoGoBackResponse.html
deleted file mode 100644
index c498dc5..0000000
--- a/post/src/main/resources/org/apache/sling/servlets/post/HtmlNoGoBackResponse.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<html>
-<head>
- <title>${title}</title>
-</head>
- <body>
- <h1>${title}</h1>
- <table>
- <tbody>
- <tr>
- <td>Status</td>
- <td><div id="Status">${status.code}</div></td>
- </tr>
- <tr>
- <td>Message</td>
- <td><div id="Message">${status.message}</div></td>
- </tr>
- <tr>
- <td>Location</td>
- <td><a href="${location}" id="Location">${location}</a></td>
- </tr>
- <tr>
- <td>Parent Location</td>
- <td><a href="${parentLocation}" id="ParentLocation">${parentLocation}</a></td>
- </tr>
- <tr>
- <td>Path</td>
- <td><div id="Path">${path}</div></td>
- </tr>
- <tr>
- <td>Referer</td>
- <td><div id="Referer">${referer}</div></td>
- </tr>
- <tr>
- <td>ChangeLog</td>
- <td><div id="ChangeLog">${changeLog}</div></td>
- </tr>
- </tbody>
- </table>
- <p><a href="${location}">Modified Resource</a></p>
- <p><a href="${parentLocation}">Parent of Modified Resource</a></p>
- </body>
-</html>
\ No newline at end of file
diff --git a/post/src/main/resources/org/apache/sling/servlets/post/HtmlResponse.html b/post/src/main/resources/org/apache/sling/servlets/post/HtmlResponse.html
deleted file mode 100644
index 11c80ce..0000000
--- a/post/src/main/resources/org/apache/sling/servlets/post/HtmlResponse.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<html>
-<head>
- <title>${title}</title>
-</head>
- <body>
- <h1>${title}</h1>
- <table>
- <tbody>
- <tr>
- <td>Status</td>
- <td><div id="Status">${status.code}</div></td>
- </tr>
- <tr>
- <td>Message</td>
- <td><div id="Message">${status.message}</div></td>
- </tr>
- <tr>
- <td>Location</td>
- <td><a href="${location}" id="Location">${location}</a></td>
- </tr>
- <tr>
- <td>Parent Location</td>
- <td><a href="${parentLocation}" id="ParentLocation">${parentLocation}</a></td>
- </tr>
- <tr>
- <td>Path</td>
- <td><div id="Path">${path}</div></td>
- </tr>
- <tr>
- <td>Referer</td>
- <td><a href="${referer}" id="Referer">${referer}</a></td>
- </tr>
- <tr>
- <td>ChangeLog</td>
- <td><div id="ChangeLog">${changeLog}</div></td>
- </tr>
- </tbody>
- </table>
- <p><a href="${referer}">Go Back</a></p>
- <p><a href="${location}">Modified Resource</a></p>
- <p><a href="${parentLocation}">Parent of Modified Resource</a></p>
- </body>
-</html>
\ No newline at end of file
diff --git a/post/src/main/resources/system/sling.js b/post/src/main/resources/system/sling.js
deleted file mode 100644
index 28b884d..0000000
--- a/post/src/main/resources/system/sling.js
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * The sling javascript client gives access to a JCR repository
- * from client-side java code, using the sling post servlet as a back-end.
- *
- * @version $Rev: $, $Date: 2007-03-27 16:30:52 +0200 (Tue, 27 Mar 2007) $
- */
-
-var Sling = null;
-
-// start sling code scope
-(function() {
-
- Sling = new Object();
- Sling.NAME_OF_THIS_FILE = "sling.js";
- Sling.PATH_OF_THIS_FILE = "/system/sling.js";
-
- /** This method tries to figure out what to do with a page */
- Sling.wizard = function() {
- //TODO add lots of magic here
- var form=document.getElementById("slingform");
- if (!form) form=document.forms[0];
- if (form) {
- var sp=new Object();
- sp.formElement=form;
- Sling.setupPage(sp);
- }
-
- }
- /** Call this to merge sling data in an HTML page
- TODO deprecate other functions
- */
- Sling.setupPage = function(options) {
- var tree = Sling.getContent(Sling._getJsonUrl(),1);
-
- if(options.formElement) {
- Sling._setFormValues(options.formElement,Sling._getJsonUrl(),tree);
- }
-
- if(options.displayElement) {
- Sling.displayValues(options.displayElement,tree);
- }
- }
-
- /**
- * HTTP GET XHR Helper
- * @param {String} url The URL
- * @return the XHR object, use .responseText for the data
- * @type String
- */
- Sling.httpGet = function(url) {
- var httpcon = Sling.getXHR();
- if (httpcon) {
- httpcon.open('GET', url, false);
- httpcon.send(null);
- return httpcon;
- } else {
- return null;
- }
- }
- /**
- * Produces a "sort-of-json" string representation of a object
- * for debugging purposes only
- * @param {Object} obj The object
- * @param {int} level The indentation level
- * @return The result
- * @type String
- */
- Sling.dumpObj = function(obj, level) {
- var res="";
- for (var a in obj) {
- if (typeof(obj[a])!="object") {
- res+=a+":"+obj[a]+" ";
- } else {
- res+=a+": { ";
- res+=Sling.dumpObj(obj[a])+"} ";
- }
- }
- return (res);
- }
-
- /** Produces an aggregate of get all the property names used
- * in a tree as a helper for table oriented display
- * @param {Object} obj The Content Tree object
- * @param {Object} names internal object used for collecting all
- * the names during the recursion
- * @return An Array of names of properties that exist in a tree
- * @type Array
- */
- Sling.getAllPropNames = function(obj, names) {
- var root=false;
- if (!names) {
- names=new Object();
- root=true;
- }
- for (var a in obj) {
- if (typeof(obj[a])!="object") {
- names[a]="1";
- } else {
- getAllPropNames(obj[a], names);
- }
- }
- if (root) {
- var ar=new Array();
- var i=0;
- for (var a in ar) {
- ar[i]=a;
- i++;
- }
- names=ar;
- }
- return (names);
- }
-
- /** Reads a tree of items given a maxlevel from the repository as JSON
- * @param {String} path Path into the current workspace
- * @param {int} maxlevel maximum depth to traverse to
- * @param {Array} filters filter only these properties
- * @return An Object tree of content nodes and properties, null if not found
- * @type Object
- */
- Sling.getContent = function(path, maxlevels, filter) {
- var obj=new Object();
- if (!path) {
- path=Sling.currentPath;
- }
- if (path.indexOf("/")==0) {
- /*
- this assumes that paths that start with a slash
- are meant to be workspace paths rather than URLs
- and therefore need some additions before they are sent
- to the server
- */
- if(maxlevels == "0" || maxlevels) {
- maxlevels = "." + maxlevels;
- } else {
- maxlevels = "";
- }
- path=Sling.baseurl + path + maxlevels + ".json";
- }
- //checking for a trailing "/*"
- if (path.indexOf("/*")>=0) return obj;
-
- // TODO for now we explicitely defeat caching on this...there must be a better way
- // but in tests IE6 tends to cache too much
- var passThroughCacheParam = "?clock=" + new Date().getTime();
- var res=Sling.httpGet(path + passThroughCacheParam + (maxlevels?"&maxlevels="+maxlevels:""));
-
- if(res.status == 200) {
- var obj=Sling.evalString(res.responseText);
- if (!filter) {
- for (var a in obj) {
- if (a.indexOf("jcr:")==0) delete(obj[a]);
- }
- }
- return obj;
- }
- return null;
- }
-
- /** Remove content by path */
- Sling.removeContent = function(path) {
- var httpcon = Sling.getXHR();
- if (httpcon) {
- var params = ":operation=delete";
- httpcon.open('POST', Sling.baseurl + path, false);
-
- // Send the proper header information along with the request
- httpcon.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- httpcon.setRequestHeader("Content-length", params.length);
- httpcon.setRequestHeader("Connection", "close");
- httpcon.send(params);
- return httpcon;
- } else {
- return false;
- }
- }
-
- /** eval str, accepting various object delimiters */
- Sling.evalString = function(str) {
- var obj = null;
- if(str.indexOf('[')==0) {
- eval("obj="+str);
- } else if(str.indexOf('{')==0) {
- eval("obj="+str);
- } else {
- eval("obj={"+str+"}");
- }
- return obj;
- }
-
- /** Get "session info" from repository. Mainly answers the question: "Who am I"
- * and "Which workspace am I logged into.
- * @return An Object tree containing the session information, null if server status <> 200
- * @type Object
- */
- Sling.getSessionInfo = function() {
- var res=Sling.httpGet(Sling.baseurl+"/system/sling/info.sessionInfo.json");
- if(res.status == 200) {
- return Sling.evalString(res.responseText);
- }
- return null;
- }
-
- /** Replace extension in a path */
- Sling._replaceExtension = function(path,newExtension) {
- var i = path.lastIndexOf(".");
- if(i >= 0) path = path.substring(0,i);
- i = path.lastIndexOf(".");
- if(i >= 0) path = path.substring(0,i);
- return path + newExtension;
- }
-
- /** Get the JSON data URL that for the current page
- * (assuming a .extension for the current page, .html or something else)
- */
- Sling._getJsonUrl = function() {
- return Sling._replaceExtension(window.location.href,".json");
- }
-
- /** Get the content repository path from the URL
- * (assuming a .extension for the current page, .html or something else)
- */
- Sling._getPath = function() {
-
- var noextensions=Sling._replaceExtension(window.location.href,"");
- var path=noextensions.substring(Sling.baseurl.length);
- return (path);
- }
-
- /** Display values inside a container: an element inside given container,
- * with an id like ./stuff, has its innerHTML set to the value of stuff
- * in the tree, if it exists.
- */
- Sling.displayValues = function(container,tree) {
- if(!tree) {
- tree = Sling.getContent(Sling._getJsonUrl(),1);
- }
-
- var elements = container.getElementsByTagName("*");
- var toSet = new Array();
- for (var i = 0; i < elements.length; i++) {
- var value = Sling._getElementValue(elements[i],tree);
- if(value) {
- toSet[toSet.length] = { e:elements[i], v:value };
- }
- }
-
- for(var i = 0; i < toSet.length; i++) {
- toSet[i].e.innerHTML = toSet[i].v;
- }
- }
-
- /** If e has an ID that matches a property of tree, set e's innerHTML accordingly */
- Sling._getElementValue = function(e,tree) {
- var id = e.getAttribute("id");
- if(id) {
- return tree[id.substring(2)];
- }
- }
-
-
- /** Set form elements based on the tree of items passed into the method
- * @param {IdOrElement} form the Form element to set, or its id
- * @param {String} path passes a string specifying the path
- * @param {Object} tree optionally pass the content that you want the
- * form to be populated with. This assumes an item tree as returned by
- * getContent().
- * Returns an object indicating whether data was found on the server.
- *
- */
- Sling._setFormValues = function(form, path, tree) {
- var result = new Object();
-
- /** TODO: deal with abolute paths?
- * TODO: deal with @ValueFrom
- */
- if (!path) return;
-
- form.setAttribute("action", path);
-
- if (!tree) {
- tree=Sling.getContent(path,1);
- }
-
- var elems=form.elements;
- var i=0;
- formfieldprefix="";
-
- while (elems.length > i) {
- var elem=elems[i];
- var a=elem.name;
- if (a.indexOf("./")==0) {
- formfieldprefix="./";
- break;
- }
- i++;
- }
-
- var i=0;
- while (elems.length > i) {
- var elem=elems[i];
- var a=elem.name;
-
- if (a.indexOf("/")==0) {
- var nodepath=a.substring(0,a.lastIndexOf("/"));
- var propname=a.substring(a.lastIndexOf("/")+1);
- var node=Sling.getContent(nodepath);
- var propval=node[propname];
- } else if (a.indexOf(formfieldprefix)==0) {
- var propname=a.substring(formfieldprefix.length);
- var propval=tree[propname];
- }
-
- if (propval) {
- if (elem.type == "file") {
- // cannot edit uplodaded files for now
- } else if (elem.type == "checkbox") {
- var vals;
- if (typeof(propval)=="object") vals=propval;
- else {
- vals=new Array();
- vals[0]=propval;
- }
- var j=0;
- while (vals.length > j) {
- if (vals[j] == elem.value) elem.checked=true;
- j++;
- }
- } else {
- elem.value=propval;
- }
- }
- i++;
- }
-
- }
-
- /** return Path as specified as the URL Parameter
- * @param URL
- * @return The Path parameter isolated from the URL
- * @type String
- */
- Sling.TODO_NOT_USED_isolatePathFromUrl = function(url) {
- var pattern = "[\\?&]Path=([^&#]*)";
- var regex = new RegExp( pattern );
- var results = regex.exec( url );
- if( results == null )
- // none found
- return "";
- else
- // found
- return unescape(results[1]);
- }
-
- /**
- * Get an XMLHttpRequest in a portable way
- *
- */
- Sling.getXHR = function () {
- var xhr=null;
-
- if(!xhr) {
- try {
- // built-in (firefox, recent Opera versions, etc)
- xhr=new XMLHttpRequest();
- } catch (e) {
- // ignore
- }
- }
-
- if(!xhr) {
- try {
- // IE, newer versions
- xhr=new ActiveXObject("Msxml2.XMLHTTP");
- } catch (e) {
- // ignore
- }
- }
-
- if(!xhr) {
- try {
- // IE, older versions
- xhr=new ActiveXObject("Microsoft.XMLHTTP");
- } catch (e) {
- // ignore
- }
- }
-
- if(!xhr) {
- alert("Unable to access XMLHttpRequest object, sling will not work!");
- }
-
- return xhr;
- }
-
- // obtain the base_url to communicate with sling on the server
- var scripts = document.getElementsByTagName("SCRIPT")
- for (var i = 0; i < scripts.length; i++) {
- var scriptSrc = scripts[i].src
- if (scriptSrc.match(Sling.PATH_OF_THIS_FILE+"$")) {
- Sling.baseurl = scriptSrc.substring(0,scriptSrc.length - Sling.PATH_OF_THIS_FILE.length);
- Sling.currentPath = Sling._getPath();
- Sling.isNew = (Sling.currentPath.indexOf("/*")>=0)?true:false;
-
- break;
- }
- }
-
-// end sling code scope
-})();
diff --git a/post/src/test/java/org/apache/sling/servlets/post/JsonResponseTest.java b/post/src/test/java/org/apache/sling/servlets/post/JsonResponseTest.java
deleted file mode 100644
index 6ad8b37..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/JsonResponseTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
-import junit.framework.TestCase;
-
-import org.apache.sling.commons.json.JSONArray;
-import org.apache.sling.commons.json.JSONException;
-import org.apache.sling.commons.json.JSONObject;
-import org.apache.sling.commons.testing.sling.MockSlingHttpServletResponse;
-
-public class JsonResponseTest extends TestCase {
- protected JSONResponse res;
-
- public void setUp() throws Exception {
- res = new JSONResponse();
- super.setUp();
- }
-
- public void testOnChange() throws Exception {
- res.onChange("modified", "argument1", "argument2");
- Object prop = res.getProperty("changes");
- JSONArray changes = assertInstanceOf(prop, JSONArray.class);
- assertEquals(1, changes.length());
- Object obj = changes.get(0);
- JSONObject change = assertInstanceOf(obj, JSONObject.class);
- assertEquals("modified", assertProperty(change, JSONResponse.PROP_TYPE, String.class));
- JSONArray arguments = assertProperty(change, JSONResponse.PROP_ARGUMENT, JSONArray.class);
- assertEquals(2, arguments.length());
- }
-
- public void testSetProperty() throws Exception {
- res.setProperty("prop", "value");
- assertProperty(res.getJson(), "prop", String.class);
- }
-
- @SuppressWarnings({"ThrowableInstanceNeverThrown"})
- public void testSetError() throws IOException, JSONException {
- String errMsg = "Dummy error";
- res.setError(new Error(errMsg));
- MockSlingHttpServletResponse resp = new MockSlingHttpServletResponse();
- res.send(resp, true);
- JSONObject json = res.getJson();
- JSONObject error = assertProperty(json, "error", JSONObject.class);
- assertProperty(error, "class", Error.class.getName());
- assertProperty(error, "message", errMsg);
- }
-
- public void testSend() throws Exception {
- res.onChange("modified", "argument1");
- MockSlingHttpServletResponse response = new MockSlingHttpServletResponse();
- res.send(response, true);
- JSONObject result = new JSONObject(response.getOutput().toString());
- assertProperty(result, HtmlResponse.PN_STATUS_CODE, HttpServletResponse.SC_OK);
- assertEquals(JSONResponse.RESPONSE_CONTENT_TYPE, response.getContentType());
- assertEquals(JSONResponse.RESPONSE_CHARSET, response.getCharacterEncoding());
- }
-
- public void testSend_201() throws Exception {
- final String location = "http://example.com/test_location";
- res.onChange("modified", "argument1");
- res.setStatus(HttpServletResponse.SC_CREATED, "Created");
- res.setLocation(location);
- MockResponseWithHeader response = new MockResponseWithHeader();
- res.send(response, true);
- JSONObject result = new JSONObject(response.getOutput().toString());
- assertProperty(result, HtmlResponse.PN_STATUS_CODE, HttpServletResponse.SC_CREATED);
- assertEquals(location, response.getHeader("Location"));
- }
-
- public void testSend_3xx() throws Exception {
- final String location = "http://example.com/test_location";
- res.onChange("modified", "argument1");
-
- for (int status = 300; status < 308; status++) {
- res.setStatus(status, "3xx Status");
- res.setLocation(location);
- MockResponseWithHeader response = new MockResponseWithHeader();
- res.send(response, true);
- JSONObject result = new JSONObject(response.getOutput().toString());
- assertProperty(result, HtmlResponse.PN_STATUS_CODE, status);
- assertEquals(location, response.getHeader("Location"));
- }
- }
-
- private static <T> T assertProperty(JSONObject obj, String key, Class<T> clazz) throws JSONException {
- assertTrue("JSON object does not have property " + key, obj.has(key));
- return assertInstanceOf(obj.get(key), clazz);
- }
-
- @SuppressWarnings({"unchecked"})
- private static <T> T assertProperty(JSONObject obj, String key, T expected) throws JSONException {
- T res = (T) assertProperty(obj, key, expected.getClass());
- assertEquals(expected, res);
- return res;
- }
-
- @SuppressWarnings({"unchecked"})
- private static <T> T assertInstanceOf(Object obj, Class<T> clazz) {
- try {
- return (T) obj;
- } catch (ClassCastException e) {
- TestCase.fail("Object is of unexpected type. Expected: " + clazz.getName() + ", actual: " + obj.getClass().getName());
- return null;
- }
- }
-
- private static class MockResponseWithHeader extends MockSlingHttpServletResponse {
- private final Map<String, Object> headers = new HashMap<String, Object>();
-
- @Override
- public void setHeader(String name, String value) {
- this.headers.put(name, value);
- }
-
- public String getHeader(String name) {
- Object result = this.headers.get(name);
- if (result instanceof String) {
- return (String) result;
- } else if (result instanceof String[]) {
- return ((String[]) result)[0];
- } else {
- return null;
- }
- }
- }
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/NodeNameFilterTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/NodeNameFilterTest.java
deleted file mode 100644
index 8039ca4..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/NodeNameFilterTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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;
-
-import junit.framework.TestCase;
-
-import org.apache.sling.servlets.post.impl.helper.NodeNameFilter;
-
-public class NodeNameFilterTest extends TestCase {
- private final NodeNameFilter filter = new NodeNameFilter();
-
- protected void runTest(String [] data) {
- for(int i=0; i < data.length; i++) {
- final String input = data[i];
- i++;
- final String expected = data[i];
- final String actual = filter.filter(input);
- assertEquals(expected, actual);
- }
- }
-
- public void testBasicFiltering() {
- final String [] data = {
- "test", "test",
- "t?st", "t_st",
- "t??st", "t_st"
- };
-
- runTest(data);
- }
-
- public void testNoInitialNumber() {
- final String [] data = {
- "1234", "_1234",
- "1", "_1"
- };
-
- runTest(data);
- }
-}
\ No newline at end of file
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/RequestPropertyTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/RequestPropertyTest.java
deleted file mode 100644
index ade82b3..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/RequestPropertyTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * 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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-
-import junitx.util.PrivateAccessor;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.request.RequestParameter;
-import org.apache.sling.api.request.RequestParameterMap;
-import org.apache.sling.servlets.post.HtmlResponse;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.impl.helper.RequestProperty;
-import org.apache.sling.servlets.post.impl.operations.ModifyOperation;
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.jmock.integration.junit4.JMock;
-import org.jmock.integration.junit4.JUnit4Mockery;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * This is primary a series of tests of the hasValues(), providesValues(), and getStringValues() methods of
- * RequestProperty. It uses the collectContent() method of ModifyOperation to make the test cases more readable.
- */
-@RunWith(JMock.class)
-public class RequestPropertyTest {
-
- private Mockery context = new JUnit4Mockery();
-
- @Test
- public void testSingleValue() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "true"));
-
- assertEquals(1, props.size());
- assertTrue(props.get("/test/path/param").hasValues());
- assertTrue(props.get("/test/path/param").providesValue());
- assertEquals(1, props.get("/test/path/param").getStringValues().length);
- assertEquals("true", props.get("/test/path/param").getStringValues()[0]);
- }
-
- @Test
- public void testSingleValueWithBlank() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", ""));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertFalse(prop.providesValue());
- assertEquals(1, prop.getStringValues().length);
- assertEquals("", prop.getStringValues()[0]);
- }
-
- @Test
- public void testNullSingleValueWithDefaultToIgnore() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param@DefaultValue", ":ignore"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertFalse(prop.hasValues());
- }
-
- @Test
- public void testSingleValueWithDefaultToIgnore() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", ""), p("./param@DefaultValue", ":ignore"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertFalse(prop.providesValue());
- assertEquals(0, prop.getStringValues().length);
- }
-
- @Test
- public void testSingleValueWithDefaultToNull() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", ""), p("./param@DefaultValue", ":null"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertTrue(prop.providesValue());
- assertNull(prop.getStringValues());
- }
-
- @Test
- public void testSingleValueIgnoringBlanks() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", ""), p("./param@IgnoreBlanks", "true"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertFalse(prop.hasValues());
- }
-
- @Test
- public void testMultiValue() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "true", "false"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertTrue(prop.providesValue());
- assertEquals(2, prop.getStringValues().length);
- assertEquals("true", prop.getStringValues()[0]);
- assertEquals("false", prop.getStringValues()[1]);
- }
-
- @Test
- public void testMultiValueWithBlank() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "true", ""));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertTrue(prop.providesValue());
- assertEquals(2, prop.getStringValues().length);
- assertEquals("true", prop.getStringValues()[0]);
- assertEquals("", prop.getStringValues()[1]);
- }
-
- @Test
- public void testMultiValueWithBlanks() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "true", "", ""));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertTrue(prop.providesValue());
- assertEquals(3, prop.getStringValues().length);
- assertEquals("true", prop.getStringValues()[0]);
- assertEquals("", prop.getStringValues()[1]);
- assertEquals("", prop.getStringValues()[2]);
- }
-
- @Test
- public void testMultiValueWithAllBlanks() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "", "", ""));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertFalse(prop.providesValue());
- assertEquals(3, prop.getStringValues().length);
- assertEquals("", prop.getStringValues()[0]);
- assertEquals("", prop.getStringValues()[1]);
- assertEquals("", prop.getStringValues()[2]);
- }
-
- @Test
- public void testMultiValueWithBlankIgnoringBlanks() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "true", ""));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertTrue(prop.providesValue());
- assertEquals(2, prop.getStringValues().length);
- assertEquals("true", prop.getStringValues()[0]);
- assertEquals("", prop.getStringValues()[1]);
- }
-
- @Test
- public void testMultiValueWithBlanksIgnoringBlanks() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "true", "", ""), p("./param@IgnoreBlanks", "true"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertTrue(prop.hasValues());
- assertTrue(prop.providesValue());
- assertEquals(1, prop.getStringValues().length);
- assertEquals("true", prop.getStringValues()[0]);
- }
-
- @Test
- public void testMultiValueWithAllBlanksIgnoringBlanks() throws Throwable {
- Map<String, RequestProperty> props = collectContent(p("./param", "", "", ""), p("./param@IgnoreBlanks", "true"));
-
- assertEquals(1, props.size());
- RequestProperty prop = props.get("/test/path/param");
- assertFalse(prop.hasValues());
- }
-
- private static final Class[] COLLECT_CLASSES = new Class[] { SlingHttpServletRequest.class, PostResponse.class };
-
- private class Param {
- String key;
- String[] value;
- }
-
- private Param p(String key, String... value) {
- Param kv = new Param();
- kv.key = key;
- kv.value = value;
- return kv;
- }
-
- @SuppressWarnings("unchecked")
- private Map<String, RequestProperty> collectContent(Param... kvs) throws Throwable {
- final List<Map.Entry<String, RequestParameter>> params = new ArrayList<Map.Entry<String, RequestParameter>>();
- for (int i = 0; i < kvs.length; i++) {
- final Param kv = kvs[i];
- final RequestParameter[] param = new RequestParameter[kv.value.length];
- for (int j = 0; j < kv.value.length; j++) {
- final String strValue = kv.value[j];
- final RequestParameter aparam = context.mock(RequestParameter.class, "requestParameter" + i + "#" + j);
- context.checking(new Expectations() {
- {
- allowing(aparam).getString();
- will(returnValue(strValue));
- }
- });
- param[j] = aparam;
- }
- final Map.Entry<String, RequestParameter> entry = context.mock(Map.Entry.class, "entry" + i);
- context.checking(new Expectations() {
- {
- allowing(entry).getKey();
- will(returnValue(kv.key));
- allowing(entry).getValue();
- will(returnValue(param));
-
- }
- });
- params.add(entry);
- }
-
- final Set set = context.mock(Set.class);
- context.checking(new Expectations() {
- {
- one(set).iterator();
- will(returnValue(params.iterator()));
- }
- });
-
- final RequestParameterMap map = context.mock(RequestParameterMap.class);
- context.checking(new Expectations() {
- {
- one(map).entrySet();
- will(returnValue(set));
-
- }
- });
-
- final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class);
- context.checking(new Expectations() {
- {
- Vector names = new Vector();
- names.add("./param");
-
- one(request).getParameterNames();
- will(returnValue(names.elements()));
- one(request).getRequestParameterMap();
- will(returnValue(map));
-
- }
- });
- final HtmlResponse response = new HtmlResponse();
- response.setPath("/test/path");
-
- Map<String, RequestProperty> props = (Map<String, RequestProperty>) PrivateAccessor.invoke(
- new ModifyOperation(), "collectContent", COLLECT_CLASSES,
- new Object[] { request, response });
- return props;
- }
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java
deleted file mode 100644
index 4df21a6..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.StringTokenizer;
-
-import junit.framework.TestCase;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
-import org.apache.sling.commons.testing.sling.MockSlingHttpServletResponse;
-import org.apache.sling.servlets.post.HtmlResponse;
-import org.apache.sling.servlets.post.JSONResponse;
-import org.apache.sling.servlets.post.PostResponse;
-import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.impl.helper.MediaRangeList;
-
-public class SlingPostServletTest extends TestCase {
-
- private SlingPostServlet servlet;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- servlet = new SlingPostServlet();
- }
-
- public void testIsSetStatus() {
- StatusParamSlingHttpServletRequest req = new StatusParamSlingHttpServletRequest();
-
- // 1. null parameter, expect true
- req.setStatusParam(null);
- assertTrue("Standard status expected for null param",
- servlet.isSetStatus(req));
-
- // 2. "standard" parameter, expect true
- req.setStatusParam(SlingPostConstants.STATUS_VALUE_STANDARD);
- assertTrue("Standard status expected for '"
- + SlingPostConstants.STATUS_VALUE_STANDARD + "' param",
- servlet.isSetStatus(req));
-
- // 3. "browser" parameter, expect false
- req.setStatusParam(SlingPostConstants.STATUS_VALUE_BROWSER);
- assertFalse("Browser status expected for '"
- + SlingPostConstants.STATUS_VALUE_BROWSER + "' param",
- servlet.isSetStatus(req));
-
- // 4. any parameter, expect true
- String param = "knocking on heaven's door";
- req.setStatusParam(param);
- assertTrue("Standard status expected for '" + param + "' param",
- servlet.isSetStatus(req));
- }
-
- public void testGetJsonResponse() {
- MockSlingHttpServletRequest req = new MockSlingHttpServletRequest(null, null, null, null, null) {
- @Override
- public String getHeader(String name) {
- return name.equals(MediaRangeList.HEADER_ACCEPT) ? "application/json" : super.getHeader(name);
- }
-
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- return null;
- }
- };
- PostResponse result = servlet.createPostResponse(req);
- assertTrue(result instanceof JSONResponse);
- }
-
- public void testRedirection() throws Exception {
- String utf8Path = "\u0414\u0440\u0443\u0433\u0430";
- String encodedUtf8 = "%D0%94%D1%80%D1%83%D0%B3%D0%B0";
- testRedirection("/", "/fred", "*.html", "/fred.html");
- testRedirection("/xyz/", "/xyz/"+utf8Path, "*", "/xyz/"+encodedUtf8);
- testRedirection("/", "/fred/"+utf8Path, "/xyz/*", "/xyz/"+encodedUtf8);
- testRedirection("/", "/fred/"+utf8Path, null, null);
- // test redirect with host information
- testRedirection("/", "/fred/abc", "http://forced", null);
- testRedirection("/", "/fred/abc", "//forced.com/test", null);
- testRedirection("/", "/fred/abc", "https://forced.com/test", null);
- // invalid URI
- testRedirection("/", "/fred/abc", "file://c:\\Users\\workspace\\test.java", null);
- }
-
- private void testRedirection(String requestPath, String resourcePath, String redirect, String expected)
- throws Exception {
- RedirectServletResponse resp = new RedirectServletResponse();
- SlingHttpServletRequest request = new RedirectServletRequest(redirect, requestPath);
- PostResponse htmlResponse = new HtmlResponse();
- htmlResponse.setPath(resourcePath);
- assertEquals(expected != null, servlet.redirectIfNeeded(request, htmlResponse, resp));
- assertEquals(expected, resp.redirectLocation);
- }
-
- /**
- *
- */
- private final class RedirectServletRequest extends MockSlingHttpServletRequest {
-
- private String requestPath;
- private String redirect;
-
- private RedirectServletRequest(String redirect, String requestPath) {
- super(null, null, null, null, null);
- this.requestPath = requestPath;
- this.redirect = redirect;
- }
-
- public String getPathInfo() {
- return requestPath;
- }
-
- @Override
- public String getParameter(String name) {
- return SlingPostConstants.RP_REDIRECT_TO.equals(name) ? redirect : null;
- }
- }
-
- private final class RedirectServletResponse extends MockSlingHttpServletResponse {
-
- private String redirectLocation;
-
- @Override
- public String encodeRedirectURL(String s) {
- StringTokenizer st = new StringTokenizer(s, "/", true);
- StringBuilder sb = new StringBuilder();
- try {
- while (st.hasMoreTokens()) {
- String token = st.nextToken();
- if ("/".equals(token)) {
- sb.append(token);
- } else {
- sb.append(URLEncoder.encode(token, "UTF-8"));
- }
- }
- } catch (UnsupportedEncodingException e) {
- fail("Should have UTF-8?? " + e);
- return null;
- }
- return sb.toString();
- }
-
- @Override
- public void sendRedirect(String s) throws IOException {
- redirectLocation = s;
- }
- }
-
- private static class StatusParamSlingHttpServletRequest extends
- MockSlingHttpServletRequest {
-
- private String statusParam;
-
- public StatusParamSlingHttpServletRequest() {
- // nothing to setup, we don't care
- super(null, null, null, null, null);
- }
-
- @Override
- public String getParameter(String name) {
- if (SlingPostConstants.RP_STATUS.equals(name)) {
- return statusParam;
- }
-
- return super.getParameter(name);
- }
-
- void setStatusParam(String statusParam) {
- this.statusParam = statusParam;
- }
-
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- return null;
- }
- }
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/helper/HtmlResponseProxyTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/helper/HtmlResponseProxyTest.java
deleted file mode 100644
index 2249e18..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/helper/HtmlResponseProxyTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.helper;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.servlets.post.PostResponse;
-import org.junit.Test;
-
-public class HtmlResponseProxyTest {
-
- @Test
- public void testConstructor() {
- new HtmlResponseProxy(POST_RESPONSE);
- }
-
- private static final PostResponse POST_RESPONSE = new PostResponse() {
-
- public void setTitle(String title) {
- }
-
- public void setStatus(int code, String message) {
- }
-
- public void setReferer(String referer) {
- }
-
- public void setPath(String path) {
- }
-
- public void setParentLocation(String parentLocation) {
- }
-
- public void setLocation(String location) {
- }
-
- public void setError(Throwable error) {
- }
-
- public void setCreateRequest(boolean isCreateRequest) {
- }
-
- public void send(HttpServletResponse response, boolean setStatus) throws IOException {
- }
-
- public void onMoved(String srcPath, String dstPath) {
- }
-
- public void onModified(String path) {
- }
-
- public void onDeleted(String path) {
- }
-
- public void onCreated(String path) {
- }
-
- public void onCopied(String srcPath, String dstPath) {
- }
-
- public void onChange(String type, String... arguments) {
- }
-
- public boolean isSuccessful() {
- return false;
- }
-
- public boolean isCreateRequest() {
- return false;
- }
-
- public String getStatusMessage() {
- return null;
- }
-
- public int getStatusCode() {
- return 0;
- }
-
- public String getReferer() {
- return null;
- }
-
- public String getPath() {
- return null;
- }
-
- public String getParentLocation() {
- return null;
- }
-
- public String getLocation() {
- return null;
- }
-
- public Throwable getError() {
- return null;
- }
- };
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/helper/MediaRangeListTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/helper/MediaRangeListTest.java
deleted file mode 100644
index 460b6f3..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/helper/MediaRangeListTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.helper;
-
-import junit.framework.TestCase;
-import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
-
-public class MediaRangeListTest extends TestCase {
- protected MediaRangeList rangeList;
-
- public void setUp() throws Exception {
- super.setUp();
- rangeList = new MediaRangeList("text/*;q=0.3, text/html;q=0.7, text/html;level=1,\n" +
- " text/html;level=2;q=0.4, */*;q=0.5");
- }
-
- public void testContains() throws Exception {
- assertTrue(rangeList.contains("text/html"));
- assertTrue(rangeList.contains("application/json")); // Since rangeList contains */*
- assertTrue(rangeList.contains("text/plain"));
- }
-
- public void testPrefer() throws Exception {
- assertEquals("text/html;level=1", rangeList.prefer("text/html;level=1", "*/*"));
- }
-
- public void testPreferJson() {
- MediaRangeList rangeList = new MediaRangeList("text/html;q=0.8, application/json");
- assertEquals("application/json", rangeList.prefer("text/html", "application/json"));
- }
-
- public void testHttpEquivParam() {
- MockSlingHttpServletRequest req = new MockSlingHttpServletRequest(null, null, null, null, null) {
- @Override
- public String getHeader(String name) {
- return name.equals(MediaRangeList.HEADER_ACCEPT) ? "text/plain" : super.getHeader(name);
- }
-
- @Override
- public String getParameter(String name) {
- return name.equals(MediaRangeList.PARAM_ACCEPT) ? "text/html" : super.getParameter(name);
- }
-
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- return null;
- }
- };
- MediaRangeList rangeList = new MediaRangeList(req);
- assertTrue("Did not contain media type from query param", rangeList.contains("text/html"));
- assertFalse("Contained media type from overridden Accept header", rangeList.contains("text/plain"));
- }
-
- public void testInvalidJdkAcceptHeader() {
- //This header is sent by Java client which make use of URLConnection on Oracle JDK
- //See acceptHeader at http://hg.openjdk.java.net/jdk6/jdk6-gate/jdk/file/tip/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
- //To support such case the MediaRange parser has to be made bit linient
- final String invalidHeader = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";
- MockSlingHttpServletRequest req = new MockSlingHttpServletRequest(null, null, null, null, null) {
- @Override
- public String getHeader(String name) {
- return name.equals(MediaRangeList.HEADER_ACCEPT) ? invalidHeader : super.getHeader(name);
- }
-
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- return null;
- }
- };
- MediaRangeList rangeList = new MediaRangeList(req);
- assertTrue("Did not contain media type from query param", rangeList.contains("text/html"));
- }
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java
deleted file mode 100644
index 0860747..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.helper;
-
-import static org.junit.Assert.assertEquals;
-import org.junit.Test;
-
-/** Verify the AutoType values of property names for which
- * we automatically set values.
- */
-public class SlingPropertyValueHandlerAutotypeTest {
- private void assertAlias(String propertyNameA) {
- final String propertyNameB = "jcr:" + propertyNameA;
-
- assertEquals("Expecting same AutotType for " + propertyNameA + " and " + propertyNameB,
- SlingPropertyValueHandler.getAutoType(propertyNameA),
- SlingPropertyValueHandler.getAutoType(propertyNameB)
- );
- }
- @Test
- public void checkPropertyAliases() {
- assertAlias("created");
- assertAlias("createdBy");
- assertAlias("lastModified");
- assertAlias("lastModifiedBy");
- }
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperationTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperationTest.java
deleted file mode 100644
index af81486..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperationTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.lang.reflect.Method;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import junit.framework.TestCase;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.servlets.post.Modification;
-import org.apache.sling.servlets.post.PostResponse;
-
-public class AbstractCreateOperationTest extends TestCase {
-
- private AbstractCreateOperation op = new AbstractCreateOperation() {
-
- @Override
- protected void doRun(SlingHttpServletRequest request,
- PostResponse response, List<Modification> changes) {
- // none here
- }
- };
-
- public void test_ignoreParameter() throws Exception {
- Method ip = getMethod("ignoreParameter", String.class);
-
- // default setup without matching regexp
- assertEquals(true, ip.invoke(op, "_charset_"));
- assertEquals(true, ip.invoke(op, ":operation"));
- assertEquals(false, ip.invoke(op, "j_username"));
- assertEquals(false, ip.invoke(op, "j_password"));
- assertEquals(false, ip.invoke(op, "some_random_j_name"));
-
- // setup: j_.*
- op.setIgnoredParameterNamePattern(Pattern.compile("j_.*"));
- assertEquals(true, ip.invoke(op, "_charset_"));
- assertEquals(true, ip.invoke(op, ":operation"));
- assertEquals(true, ip.invoke(op, "j_username"));
- assertEquals(true, ip.invoke(op, "j_password"));
- assertEquals(false, ip.invoke(op, "some_random_j_name"));
-
- // setup: .*j_.*
- op.setIgnoredParameterNamePattern(Pattern.compile(".*j_.*"));
- assertEquals(true, ip.invoke(op, "_charset_"));
- assertEquals(true, ip.invoke(op, ":operation"));
- assertEquals(true, ip.invoke(op, "j_username"));
- assertEquals(true, ip.invoke(op, "j_password"));
- assertEquals(true, ip.invoke(op, "some_random_j_name"));
-
- // setup: .+j_.*
- op.setIgnoredParameterNamePattern(Pattern.compile(".+j_.*"));
- assertEquals(true, ip.invoke(op, "_charset_"));
- assertEquals(true, ip.invoke(op, ":operation"));
- assertEquals(false, ip.invoke(op, "j_username"));
- assertEquals(false, ip.invoke(op, "j_password"));
- assertEquals(true, ip.invoke(op, "some_random_j_name"));
- }
-
- private Method getMethod(String name, Class... parameterTypes) {
- try {
- Method m = AbstractCreateOperation.class.getDeclaredMethod(name,
- parameterTypes);
- m.setAccessible(true);
- return m;
- } catch (Throwable t) {
- fail(t.toString());
- return null; // compiler wants this
- }
- }
-
-}
diff --git a/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java b/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java
deleted file mode 100644
index 4e3fa9d..0000000
--- a/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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 javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import junit.framework.TestCase;
-
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.jmock.integration.junit4.JMock;
-import org.jmock.integration.junit4.JUnit4Mockery;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(JMock.class)
-public class CopyOperationTest extends TestCase {
- private Mockery context = new JUnit4Mockery();
- private int counter;
-
- private void assertResult(final String srcPath, final String destPath, Boolean expectedResult) throws RepositoryException {
- counter++;
- final Node src = context.mock(Node.class, "src" + counter);
- final Node dest = context.mock(Node.class, "dest" + counter);
-
- context.checking(new Expectations() {
- {
- allowing(src).getPath();
- will(returnValue(srcPath));
- allowing(dest).getPath();
- will(returnValue(destPath));
- }
- });
-
- final boolean result = CopyOperation.isAncestorOrSameNode(src, dest);
- assertEquals(
- "Expecting isAncestorOrSameNode to be " + expectedResult + " for " + srcPath + " and " + destPath,
- expectedResult.booleanValue(), result);
- }
-
- @Test
- public void testIsAncestorOrSameNode() throws RepositoryException {
- final Object [] testCases = {
- "/", "/", true,
- "/a", "/a", true,
- "/a/bee/ceee", "/a/bee/ceee", true,
- "/", "/tmp", true,
- "/a", "/a/b", true,
- "/a", "/a/b/c/dee/eeee", true,
- "/a", "/ab", false,
- "/ab/cd", "/ab/cde", false,
- "/ab", "/cd", false,
- };
-
- for(int i=0; i < testCases.length; i+=3) {
- assertResult((String)testCases[i], (String)testCases[i+1], (Boolean)(testCases[i+2]));
- }
-
- }
-}
\ No newline at end of file