You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:46:47 UTC
[sling-org-apache-sling-jcr-contentloader] 21/36: SLING-766 : Don't
uninstall content when bundle is stopped. The content is now only
uninstalled when the bundle is uninstalled. During installation a string
array containing all paths that will be removed later on is collected which
makes the uninstall easier. Also refactored the classes and packages a
little bit.
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.4-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git
commit 5736f529eee826aebb640984215f426f0049ce55
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Dec 16 13:32:17 2008 +0000
SLING-766 : Don't uninstall content when bundle is stopped. The content is now only uninstalled when the bundle is uninstalled. During installation a string
array containing all paths that will be removed later on is collected which makes the uninstall easier. Also refactored the classes and packages a little bit.
git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@727047 13f79535-47bb-0310-9956-ffa450edef68
---
.../jcr/contentloader/internal/ContentCreator.java | 2 +-
.../internal/ContentLoaderService.java | 40 +++-
.../jcr/contentloader/internal/ContentReader.java | 2 +-
...ntentLoader.java => DefaultContentCreator.java} | 52 ++++-
.../jcr/contentloader/internal/ImportProvider.java | 4 +-
.../sling/jcr/contentloader/internal/Loader.java | 238 +++++++--------------
.../internal/{ => readers}/JsonReader.java | 9 +-
.../internal/{ => readers}/XmlReader.java | 7 +-
.../internal/{ => readers}/ZipReader.java | 11 +-
.../jcr/contentloader/internal/JsonReaderTest.java | 1 +
10 files changed, 177 insertions(+), 189 deletions(-)
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentCreator.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentCreator.java
index 4390f4e..3e93ac1 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentCreator.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentCreator.java
@@ -28,7 +28,7 @@ import javax.jcr.RepositoryException;
*
* @since 2.0.4
*/
-interface ContentCreator {
+public interface ContentCreator {
/**
* Create a new node.
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index 341fda5..9781ce5 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -21,6 +21,7 @@ package org.apache.sling.jcr.contentloader.internal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
@@ -28,6 +29,7 @@ import java.util.StringTokenizer;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.Value;
import javax.jcr.lock.LockException;
import org.apache.sling.commons.mime.MimeTypeService;
@@ -56,6 +58,11 @@ import org.slf4j.LoggerFactory;
public class ContentLoaderService implements SynchronousBundleListener {
public static final String PROPERTY_CONTENT_LOADED = "content-loaded";
+ private static final String PROPERTY_CONTENT_LOADED_AT = "content-load-time";
+ private static final String PROPERTY_CONTENT_LOADED_BY = "content-loaded-by";
+ private static final String PROPERTY_CONTENT_UNLOADED_AT = "content-unload-time";
+ private static final String PROPERTY_CONTENT_UNLOADED_BY = "content-unloaded-by";
+ public static final String PROPERTY_UNINSTALL_PATHS = "uninstall-paths";
public static final String BUNDLE_CONTENT_NODE = "/var/sling/bundle-content";
@@ -140,7 +147,7 @@ public class ContentLoaderService implements SynchronousBundleListener {
// we will use this info when the new start event is triggered
this.updatedBundles.add(event.getBundle().getSymbolicName());
break;
- case BundleEvent.STOPPED:
+ case BundleEvent.UNINSTALLED:
try {
Session session = getAdminSession();
initialContentLoader.unregisterBundle(session, event.getBundle());
@@ -269,11 +276,14 @@ public class ContentLoaderService implements SynchronousBundleListener {
* @return The map of bundle content info or null.
* @throws RepositoryException
*/
- public Map<String, Object> getBundleContentInfo(final Session session, final Bundle bundle)
+ public Map<String, Object> getBundleContentInfo(final Session session, final Bundle bundle, boolean create)
throws RepositoryException {
final String nodeName = bundle.getSymbolicName();
final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
if ( !parentNode.hasNode(nodeName) ) {
+ if ( !create ) {
+ return null;
+ }
try {
final Node bcNode = parentNode.addNode(nodeName, "nt:unstructured");
bcNode.addMixin("mix:lockable");
@@ -300,22 +310,34 @@ public class ContentLoaderService implements SynchronousBundleListener {
} else {
info.put(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
}
+ if ( bcNode.hasProperty(ContentLoaderService.PROPERTY_UNINSTALL_PATHS) ) {
+ final Value[] values = bcNode.getProperty(PROPERTY_UNINSTALL_PATHS).getValues();
+ final String[] s = new String[values.length];
+ for(int i=0; i<values.length; i++) {
+ s[i] = values[i].getString();
+ }
+ info.put(ContentLoaderService.PROPERTY_UNINSTALL_PATHS, s);
+ }
return info;
}
public void unlockBundleContentInfo(final Session session,
final Bundle bundle,
- final boolean contentLoaded)
+ final boolean contentLoaded,
+ final List<String> createdNodes)
throws RepositoryException {
final String nodeName = bundle.getSymbolicName();
final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
final Node bcNode = parentNode.getNode(nodeName);
if ( contentLoaded ) {
bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, contentLoaded);
- bcNode.setProperty("content-load-time", Calendar.getInstance());
- bcNode.setProperty("content-loaded-by", this.slingId);
- bcNode.setProperty("content-unload-time", (String)null);
- bcNode.setProperty("content-unloaded-by", (String)null);
+ bcNode.setProperty(PROPERTY_CONTENT_LOADED_AT, Calendar.getInstance());
+ bcNode.setProperty(PROPERTY_CONTENT_LOADED_BY, this.slingId);
+ bcNode.setProperty(PROPERTY_CONTENT_UNLOADED_AT, (String)null);
+ bcNode.setProperty(PROPERTY_CONTENT_UNLOADED_BY, (String)null);
+ if ( createdNodes != null && createdNodes.size() > 0 ) {
+ bcNode.setProperty(PROPERTY_UNINSTALL_PATHS, createdNodes.toArray(new String[createdNodes.size()]));
+ }
bcNode.save();
}
bcNode.unlock();
@@ -329,8 +351,8 @@ public class ContentLoaderService implements SynchronousBundleListener {
if ( parentNode.hasNode(nodeName) ) {
final Node bcNode = parentNode.getNode(nodeName);
bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
- bcNode.setProperty("content-unload-time", Calendar.getInstance());
- bcNode.setProperty("content-unloaded-by", this.slingId);
+ bcNode.setProperty(PROPERTY_CONTENT_UNLOADED_AT, Calendar.getInstance());
+ bcNode.setProperty(PROPERTY_CONTENT_UNLOADED_BY, this.slingId);
bcNode.save();
}
} catch (RepositoryException re) {
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentReader.java
index b36fa7d..2d5aaf1 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentReader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentReader.java
@@ -27,7 +27,7 @@ import javax.jcr.RepositoryException;
* The <code>ContentReader</code>
* A content reader is provided by an {@link ImportProvider}.
*/
-interface ContentReader {
+public interface ContentReader {
/**
* Read the content from the input stream and create the
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
similarity index 92%
rename from src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoader.java
rename to src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
index a9c656a..c22b509 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
@@ -41,7 +41,7 @@ import javax.jcr.ValueFactory;
* The <code>ContentLoader</code> creates the nodes and properties.
* @since 2.0.4
*/
-public class ContentLoader implements ContentCreator {
+public class DefaultContentCreator implements ContentCreator {
private PathEntry configuration;
@@ -65,21 +65,32 @@ public class ContentLoader implements ContentCreator {
// default content type for createFile()
private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
+ /** Helper class to get the mime type of a file. */
private final ContentLoaderService jcrContentHelper;
+ /** List of active import providers mapped by extension. */
private Map<String, ImportProvider> importProviders;
- public ContentLoader(ContentLoaderService jcrContentHelper) {
+ /** Optional list of created nodes (for uninstall) */
+ private List<String> createdNodes;
+
+ /**
+ * Constructor.
+ * @param jcrContentHelper Helper class to get the mime type of a file
+ */
+ public DefaultContentCreator(ContentLoaderService jcrContentHelper) {
this.jcrContentHelper = jcrContentHelper;
}
/**
* Initialize this component.
- * @param pathEntry
+ * @param pathEntry The configuration for this import.
+ * @param defaultImportProviders List of all import providers.
+ * @param createdNodes Optional list to store new nodes (for uninstall)
*/
public void init(final PathEntry pathEntry,
- final Map<String, ImportProvider> defaultImportProviders) {
-
+ final Map<String, ImportProvider> defaultImportProviders,
+ final List<String> createdNodes) {
this.configuration = pathEntry;
// create list of allowed import providers
this.importProviders = new HashMap<String, ImportProvider>();
@@ -90,6 +101,7 @@ public class ContentLoader implements ContentCreator {
importProviders.put(current.getKey(), current.getValue());
}
}
+ this.createdNodes = createdNodes;
}
/**
@@ -121,6 +133,10 @@ public class ContentLoader implements ContentCreator {
this.versionables.clear();
}
+ /**
+ * Set the ignore overwrite flag.
+ * @param flag
+ */
public void setIgnoreOverwriteFlag(boolean flag) {
this.ignoreOverwriteFlag = flag;
}
@@ -132,10 +148,19 @@ public class ContentLoader implements ContentCreator {
return this.rootNode;
}
+ /**
+ * Get all active import providers.
+ * @return A map of providers
+ */
public Map<String, ImportProvider> getImportProviders() {
return this.importProviders;
}
+ /**
+ * Return the import provider for the name
+ * @param name The file name.
+ * @return The provider or <code>null</code>
+ */
public ImportProvider getImportProvider(String name) {
ImportProvider provider = null;
final Iterator<String> ipIter = importProviders.keySet().iterator();
@@ -148,6 +173,11 @@ public class ContentLoader implements ContentCreator {
return provider;
}
+ /**
+ * Get the extension of the file name.
+ * @param name The file name.
+ * @return The extension a provider is registered for - or <code>null</code>
+ */
public String getImportProviderExtension(String name) {
String providerExt = null;
final Iterator<String> ipIter = importProviders.keySet().iterator();
@@ -188,16 +218,21 @@ public class ContentLoader implements ContentCreator {
// use existing node
node = parentNode.getNode(name);
-
} else if (primaryNodeType == null) {
// no explicit node type, use repository default
node = parentNode.addNode(name);
+ if ( this.createdNodes != null ) {
+ this.createdNodes.add(node.getPath());
+ }
} else {
// explicit primary node type
node = parentNode.addNode(name, primaryNodeType);
+ if ( this.createdNodes != null ) {
+ this.createdNodes.add(node.getPath());
+ }
}
// ammend mixin node types
@@ -557,7 +592,10 @@ public class ContentLoader implements ContentCreator {
if ( newNodeType == null ) {
return false;
}
- node.addNode(token, newNodeType);
+ final Node n = node.addNode(token, newNodeType);
+ if ( this.createdNodes != null ) {
+ this.createdNodes.add(n.getPath());
+ }
}
node = node.getNode(token);
}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
index 2cf8340..cfd85f6 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
@@ -20,8 +20,8 @@ package org.apache.sling.jcr.contentloader.internal;
import java.io.IOException;
-interface ImportProvider {
+public interface ImportProvider {
ContentReader getReader() throws IOException;
-
+
}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
index 83622af..8db1b94 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -26,15 +26,15 @@ import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.StringTokenizer;
import javax.jcr.InvalidSerializedDataException;
@@ -43,6 +43,9 @@ import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import org.apache.sling.jcr.contentloader.internal.readers.JsonReader;
+import org.apache.sling.jcr.contentloader.internal.readers.XmlReader;
+import org.apache.sling.jcr.contentloader.internal.readers.ZipReader;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,14 +75,14 @@ public class Loader {
/** All available import providers. */
private Map<String, ImportProvider> defaultImportProviders;
- private final ContentLoader contentCreator;
+ private final DefaultContentCreator contentCreator;
// bundles whose registration failed and should be retried
private List<Bundle> delayedBundles;
public Loader(ContentLoaderService jcrContentHelper) {
this.jcrContentHelper = jcrContentHelper;
- this.contentCreator = new ContentLoader(jcrContentHelper);
+ this.contentCreator = new DefaultContentCreator(jcrContentHelper);
this.delayedBundles = new LinkedList<Bundle>();
defaultImportProviders = new LinkedHashMap<String, ImportProvider>();
@@ -108,6 +111,10 @@ public class Loader {
public void registerBundle(final Session session,
final Bundle bundle,
final boolean isUpdate) {
+ // if this is an update, we have to uninstall the old content first
+ if ( isUpdate ) {
+ this.unregisterBundle(session, bundle);
+ }
log.debug("Registering bundle {} for content loading.",
bundle.getSymbolicName());
@@ -153,7 +160,7 @@ public class Loader {
// check if the content has already been loaded
final Map<String, Object> bundleContentInfo = jcrContentHelper.getBundleContentInfo(
- session, bundle);
+ session, bundle, true);
// if we don't get an info, someone else is currently loading
if (bundleContentInfo == null) {
@@ -161,6 +168,7 @@ public class Loader {
}
boolean success = false;
+ List<String> createdNodes = null;
try {
final boolean contentAlreadyLoaded = ((Boolean) bundleContentInfo.get(ContentLoaderService.PROPERTY_CONTENT_LOADED)).booleanValue();
@@ -172,7 +180,7 @@ public class Loader {
} else {
- installContent(session, bundle, pathIter,
+ createdNodes = installContent(session, bundle, pathIter,
contentAlreadyLoaded);
if (isRetry) {
@@ -189,7 +197,7 @@ public class Loader {
} finally {
jcrContentHelper.unlockBundleContentInfo(session, bundle,
- success);
+ success, createdNodes);
}
} catch (RepositoryException re) {
@@ -211,29 +219,48 @@ public class Loader {
*/
public void unregisterBundle(final Session session, final Bundle bundle) {
- // check if bundle has initial content
- final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
if (delayedBundles.contains(bundle)) {
delayedBundles.remove(bundle);
} else {
+ try {
+ final Map<String, Object> bundleContentInfo = jcrContentHelper.getBundleContentInfo(
+ session, bundle, false);
- if (pathIter != null) {
- uninstallContent(session, bundle, pathIter);
- jcrContentHelper.contentIsUninstalled(session, bundle);
- }
+ // if we don't get an info, someone else is currently loading or unloading
+ // or the bundle is already uninstalled
+ if (bundleContentInfo == null) {
+ return;
+ }
+ try {
+ uninstallContent(session, bundle, (String[])bundleContentInfo.get(ContentLoaderService.PROPERTY_UNINSTALL_PATHS));
+ jcrContentHelper.contentIsUninstalled(session, bundle);
+ } finally {
+ jcrContentHelper.unlockBundleContentInfo(session, bundle, false, null);
+
+ }
+ } catch (RepositoryException re) {
+ log.error("Cannot remove initial content for bundle "
+ + bundle.getSymbolicName() + " : " + re.getMessage(), re);
+ }
}
}
// ---------- internal -----------------------------------------------------
- private void installContent(final Session session,
- final Bundle bundle,
- final Iterator<PathEntry> pathIter,
- final boolean contentAlreadyLoaded)
+ /**
+ * Install the content from the bundle.
+ * @return If the content should be removed on uninstall, a list of top nodes
+ */
+ private List<String> installContent(final Session session,
+ final Bundle bundle,
+ final Iterator<PathEntry> pathIter,
+ final boolean contentAlreadyLoaded)
throws RepositoryException {
+ final List<String> createdNodes = new ArrayList<String>();
+
log.debug("Installing initial content from bundle {}",
bundle.getSymbolicName());
try {
@@ -245,7 +272,23 @@ public class Loader {
final Node targetNode = getTargetNode(session, entry.getTarget());
if (targetNode != null) {
- installFromPath(bundle, entry.getPath(), entry, targetNode);
+ installFromPath(bundle, entry.getPath(), entry, targetNode,
+ entry.isUninstall() ? createdNodes : null);
+ }
+ }
+ }
+
+ // now optimize created nodes list
+ Collections.sort(createdNodes);
+ if ( createdNodes.size() > 1) {
+ final Iterator<String> i = createdNodes.iterator();
+ String previous = i.next() + '/';
+ while ( i.hasNext() ) {
+ final String current = i.next();
+ if ( current.startsWith(previous) ) {
+ i.remove();
+ } else {
+ previous = current + '/';
}
}
}
@@ -274,6 +317,7 @@ public class Loader {
log.debug("Done installing initial content from bundle {}",
bundle.getSymbolicName());
+ return createdNodes;
}
/**
@@ -283,12 +327,14 @@ public class Loader {
* @param path The path
* @param overwrite Should the content be overwritten.
* @param parent The parent node.
+ * @param createdNodes An optional list to store all new nodes. This list is used for an uninstall
* @throws RepositoryException
*/
private void installFromPath(final Bundle bundle,
final String path,
final PathEntry configuration,
- final Node parent)
+ final Node parent,
+ final List<String> createdNodes)
throws RepositoryException {
@SuppressWarnings("unchecked")
@@ -298,7 +344,7 @@ public class Loader {
return;
}
// init content creator
- this.contentCreator.init(configuration, this.defaultImportProviders);
+ this.contentCreator.init(configuration, this.defaultImportProviders, createdNodes);
final Map<URL, Node> processedEntries = new HashMap<URL, Node>();
// potential root node import/extension
@@ -342,7 +388,7 @@ public class Loader {
// walk down the line
if (node != null) {
- installFromPath(bundle, entry, configuration, node);
+ installFromPath(bundle, entry, configuration, node, createdNodes);
}
} else {
@@ -377,7 +423,7 @@ public class Loader {
// otherwise just place as file
if ( node == null ) {
try {
- createFile(configuration, parent, file);
+ createFile(configuration, parent, file, createdNodes);
node = parent.getNode(name);
} catch (IOException ioe) {
log.warn("Cannot create file node for {}", file, ioe);
@@ -455,21 +501,6 @@ public class Loader {
}
/**
- * Delete the node from the initial content.
- *
- * @param parent
- * @param name
- * @param nodeXML
- * @throws RepositoryException
- */
- private void deleteNode(Node parent, String name)
- throws RepositoryException {
- if (parent.hasNode(name)) {
- parent.getNode(name).remove();
- }
- }
-
- /**
* Create a folder
*
* @param parent The parent node.
@@ -499,7 +530,7 @@ public class Loader {
* @throws IOException
* @throws RepositoryException
*/
- private void createFile(PathEntry configuration, Node parent, URL source)
+ private void createFile(PathEntry configuration, Node parent, URL source, List<String> createdNodes)
throws IOException, RepositoryException {
final String srcPath = source.getPath();
int pos = srcPath.lastIndexOf("/");
@@ -511,7 +542,7 @@ public class Loader {
path = srcPath.substring(0, pos + 1) + name;
}
- this.contentCreator.init(configuration, defaultImportProviders);
+ this.contentCreator.init(configuration, defaultImportProviders, createdNodes);
this.contentCreator.prepareParsing(parent, name);
final URLConnection conn = source.openConnection();
final long lastModified = conn.getLastModified();
@@ -523,22 +554,6 @@ public class Loader {
}
/**
- * Delete the file from the given url.
- *
- * @param parent
- * @param source
- * @throws IOException
- * @throws RepositoryException
- */
- private void deleteFile(Node parent, URL source) throws IOException,
- RepositoryException {
- String name = getName(source.getPath());
- if (parent.hasNode(name)) {
- parent.getNode(name).remove();
- }
- }
-
- /**
* Gets and decods the name part of the <code>path</code>. The name is
* the part of the path after the last slash (or the complete path if no
* slash is contained). To support names containing unsupported characters
@@ -603,25 +618,20 @@ public class Loader {
}
private void uninstallContent(final Session session, final Bundle bundle,
- final Iterator<PathEntry> pathIter) {
+ final String[] uninstallPaths) {
try {
log.debug("Uninstalling initial content from bundle {}",
bundle.getSymbolicName());
- while (pathIter.hasNext()) {
- final PathEntry entry = pathIter.next();
- if (entry.isUninstall()) {
- Node targetNode = getTargetNode(session, entry.getTarget());
- if (targetNode != null)
- uninstallFromPath(bundle, entry.getPath(), entry, targetNode);
- } else {
- log.debug(
- "Ignoring to uninstall content at {}, uninstall directive is not set.",
- entry.getPath());
+ if ( uninstallPaths != null && uninstallPaths.length > 0 ) {
+ for(final String path : uninstallPaths) {
+ if ( session.itemExists(path) ) {
+ session.getItem(path).remove();
+ }
}
+ // persist modifications now
+ session.save();
}
- // persist modifications now
- session.save();
log.debug("Done uninstalling initial content from bundle {}",
bundle.getSymbolicName());
} catch (RepositoryException re) {
@@ -641,98 +651,6 @@ public class Loader {
}
/**
- * Handle content uninstallation for a single path.
- *
- * @param bundle The bundle containing the content.
- * @param path The path
- * @param parent The parent node.
- * @throws RepositoryException
- */
- private void uninstallFromPath(final Bundle bundle,
- final String path,
- final PathEntry configuration,
- final Node parent) throws RepositoryException {
- @SuppressWarnings("unchecked")
- Enumeration<String> entries = bundle.getEntryPaths(path);
- if (entries == null) {
- return;
- }
-
- this.contentCreator.init(configuration, defaultImportProviders);
-
- final Set<URL> ignoreEntry = new HashSet<URL>();
-
- // potential root node import/extension
- Descriptor rootNodeDescriptor = getRootNodeDescriptor(bundle, path);
- if (rootNodeDescriptor != null) {
- ignoreEntry.add(rootNodeDescriptor.rootNodeDescriptor);
- }
-
- while (entries.hasMoreElements()) {
- final String entry = entries.nextElement();
- log.debug("Processing initial content entry {}", entry);
- if (entry.endsWith("/")) {
- // dir, check for node descriptor , else create dir
- String base = entry.substring(0, entry.length() - 1);
- String name = getName(base);
-
- URL nodeDescriptor = null;
- for (String ext : this.contentCreator.getImportProviders().keySet()) {
- nodeDescriptor = bundle.getEntry(base + ext);
- if (nodeDescriptor != null) {
- break;
- }
- }
-
- final Node node;
- boolean delete = false;
- if (nodeDescriptor != null
- && !ignoreEntry.contains(nodeDescriptor)) {
- node = (parent.hasNode(toPlainName(name))
- ? parent.getNode(toPlainName(name))
- : null);
- delete = true;
- } else {
- node = (parent.hasNode(name) ? parent.getNode(name) : null);
- }
-
- if (node != null) {
- // walk down the line
- uninstallFromPath(bundle, entry, configuration, node);
- }
-
- if (delete) {
- deleteNode(parent, toPlainName(name));
- ignoreEntry.add(nodeDescriptor);
- }
-
- } else {
- // file => create file
- URL file = bundle.getEntry(entry);
- if (ignoreEntry.contains(file)) {
- // this is a consumed node descriptor
- continue;
- }
-
- // uninstall if it is a descriptor
- boolean foundProvider = this.contentCreator.getImportProvider(entry) != null;
- if (foundProvider) {
- deleteNode(parent, toPlainName(getName(entry)));
- ignoreEntry.add(file);
- continue;
- }
-
- // otherwise just delete the file
- try {
- deleteFile(parent, file);
- } catch (IOException ioe) {
- log.warn("Cannot delete file node for {}", file, ioe);
- }
- }
- }
- }
-
- /**
* Import the XML file as JCR system or document view import. If the XML
* file is not a valid system or document view export/import file,
* <code>false</code> is returned.
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
similarity index 94%
rename from src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
rename to src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
index 78a7f3e..19d7277 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.contentloader.internal;
+package org.apache.sling.jcr.contentloader.internal.readers;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
@@ -31,12 +31,15 @@ import javax.jcr.RepositoryException;
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.jcr.contentloader.internal.ContentCreator;
+import org.apache.sling.jcr.contentloader.internal.ContentReader;
+import org.apache.sling.jcr.contentloader.internal.ImportProvider;
/**
* The <code>JsonReader</code> TODO
*/
-class JsonReader implements ContentReader {
+public class JsonReader implements ContentReader {
private static final String REFERENCE = "jcr:reference:";
private static final String PATH = "jcr:path:";
@@ -53,7 +56,7 @@ class JsonReader implements ContentReader {
ignoredNames.add("jcr:created");
}
- static final ImportProvider PROVIDER = new ImportProvider() {
+ public static final ImportProvider PROVIDER = new ImportProvider() {
private JsonReader jsonReader;
public ContentReader getReader() {
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReader.java
similarity index 96%
rename from src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java
rename to src/main/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReader.java
index 98dd4a6..af3fa6a 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReader.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.contentloader.internal;
+package org.apache.sling.jcr.contentloader.internal.readers;
import java.io.IOException;
import java.io.InputStream;
@@ -26,6 +26,9 @@ import java.util.List;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
+import org.apache.sling.jcr.contentloader.internal.ContentCreator;
+import org.apache.sling.jcr.contentloader.internal.ContentReader;
+import org.apache.sling.jcr.contentloader.internal.ImportProvider;
import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -86,7 +89,7 @@ public class XmlReader implements ContentReader {
private static final String ELEM_TYPE = "type";
- static final ImportProvider PROVIDER = new ImportProvider() {
+ public static final ImportProvider PROVIDER = new ImportProvider() {
private XmlReader xmlReader;
public ContentReader getReader() throws IOException {
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ZipReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/ZipReader.java
similarity index 86%
rename from src/main/java/org/apache/sling/jcr/contentloader/internal/ZipReader.java
rename to src/main/java/org/apache/sling/jcr/contentloader/internal/readers/ZipReader.java
index fff0c82..4308f4d 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ZipReader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/ZipReader.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.contentloader.internal;
+package org.apache.sling.jcr.contentloader.internal.readers;
import java.io.IOException;
import java.io.InputStream;
@@ -26,6 +26,9 @@ import java.util.zip.ZipInputStream;
import javax.jcr.RepositoryException;
import org.apache.commons.io.input.CloseShieldInputStream;
+import org.apache.sling.jcr.contentloader.internal.ContentCreator;
+import org.apache.sling.jcr.contentloader.internal.ContentReader;
+import org.apache.sling.jcr.contentloader.internal.ImportProvider;
/**
@@ -33,11 +36,11 @@ import org.apache.commons.io.input.CloseShieldInputStream;
*
* @since 2.0.4
*/
-class ZipReader implements ContentReader {
+public class ZipReader implements ContentReader {
private static final String NT_FOLDER = "nt:folder";
- static final ImportProvider ZIP_PROVIDER = new ImportProvider() {
+ public static final ImportProvider ZIP_PROVIDER = new ImportProvider() {
private ZipReader zipReader;
public ContentReader getReader() {
@@ -48,7 +51,7 @@ class ZipReader implements ContentReader {
}
};
- static final ImportProvider JAR_PROVIDER = new ImportProvider() {
+ public static final ImportProvider JAR_PROVIDER = new ImportProvider() {
private ZipReader zipReader;
public ContentReader getReader() {
diff --git a/src/test/java/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java b/src/test/java/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
index 5b3463f..d403145 100644
--- a/src/test/java/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
+++ b/src/test/java/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
@@ -26,6 +26,7 @@ import javax.jcr.RepositoryException;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.jcr.contentloader.internal.readers.JsonReader;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.Sequence;
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.