You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2007/09/20 11:07:54 UTC
svn commit: r577648 - in /incubator/sling/trunk: content/
content/src/main/java/org/apache/sling/content/jcr/
content/src/main/java/org/apache/sling/content/jcr/internal/loader/
jackrabbit-api/ jackrabbit-api/src/main/java/org/apache/sling/jcr/ jackrab...
Author: cziegeler
Date: Thu Sep 20 02:07:53 2007
New Revision: 577648
URL: http://svn.apache.org/viewvc?rev=577648&view=rev
Log:
Move node type mgmg to jackrabbit api to solve problems mentioned in SLING-12
Added:
incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java (with props)
incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/
incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java (with props)
Removed:
incubator/sling/trunk/content/src/main/java/org/apache/sling/content/jcr/NodeTypeLoader.java
Modified:
incubator/sling/trunk/content/pom.xml
incubator/sling/trunk/content/src/main/java/org/apache/sling/content/jcr/internal/loader/Loader.java
incubator/sling/trunk/jackrabbit-api/pom.xml
incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/AbstractSlingRepository.java
Modified: incubator/sling/trunk/content/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/content/pom.xml?rev=577648&r1=577647&r2=577648&view=diff
==============================================================================
--- incubator/sling/trunk/content/pom.xml (original)
+++ incubator/sling/trunk/content/pom.xml Thu Sep 20 02:07:53 2007
@@ -33,11 +33,11 @@
<packaging>bundle</packaging>
<name>
- Sling - Content Loading, Mapping and Nodetype Management
+ Sling - Content Loading and Mapping Management
</name>
<description>
- This bundle provides three kinds of Repository Content related
- functionality: Node type registration, initial content
+ This bundle provides two kinds of Repository Content related
+ functionality: Initial content
installation and JCR Mapping.
</description>
Modified: incubator/sling/trunk/content/src/main/java/org/apache/sling/content/jcr/internal/loader/Loader.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/content/src/main/java/org/apache/sling/content/jcr/internal/loader/Loader.java?rev=577648&r1=577647&r2=577648&view=diff
==============================================================================
--- incubator/sling/trunk/content/src/main/java/org/apache/sling/content/jcr/internal/loader/Loader.java (original)
+++ incubator/sling/trunk/content/src/main/java/org/apache/sling/content/jcr/internal/loader/Loader.java Thu Sep 20 02:07:53 2007
@@ -40,10 +40,7 @@
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import org.apache.jackrabbit.ocm.mapper.model.ClassDescriptor;
-import org.apache.sling.content.jcr.NodeTypeLoader;
import org.apache.sling.content.jcr.internal.JcrContentHelper;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
@@ -56,7 +53,6 @@
public class Loader {
public static final String CONTENT_HEADER = "Sling-Initial-Content";
- public static final String NODETYPES_BUNDLE_HEADER = "Sling-Nodetypes";
public static final String EXT_XML = ".xml";
public static final String EXT_JSON = ".json";
@@ -110,10 +106,8 @@
private boolean registerBundleInternal (Bundle bundle) {
try {
- if (this.registerNodeTypes(bundle)) {
- this.installContent(bundle);
- return true;
- }
+ this.installContent(bundle);
+ return true;
} catch (RepositoryException re) {
log.error("Cannot load initial content for bundle {}: {}",
bundle.getSymbolicName(), re);
@@ -126,93 +120,7 @@
this.uninstallContent(bundle);
}
- public void checkNodeType(ClassDescriptor classDescriptor) throws RepositoryException {
- Session session = this.getSession();
- try {
- String nodeType = classDescriptor.getJcrType();
- if (nodeType == null || nodeType.length() == 0) {
- return;
- }
-
- try {
- session.getWorkspace().getNodeTypeManager().getNodeType(nodeType);
- return;
- } catch (NoSuchNodeTypeException nsnte) {
- // have to register
- log.debug("Node Type {} is not registered yet", nodeType);
- }
-
- // TODO: create and later register it
- log.error("Nodetype {} is missing, but Session cannot be used to register", nodeType);
- return;
-
- } finally {
- this.ungetSession(session);
- }
- }
-
- public void registerNodeTypes(List<?> nodeTypes) throws RepositoryException {
- // TODO
- }
-
//---------- internal -----------------------------------------------------
-
- private boolean registerNodeTypes(Bundle bundle) throws RepositoryException {
- // TODO: define header referring to mapper files
- String typesHeader = (String) bundle.getHeaders().get(NODETYPES_BUNDLE_HEADER);
- if (typesHeader == null) {
- // no components in the bundle, return with success
- log.debug("registerNodeTypes: Bundle {} has no nodetypes",
- bundle.getSymbolicName());
- return true;
- }
-
- boolean success = true;
- Session session = this.getSession();
- try {
- StringTokenizer tokener = new StringTokenizer(typesHeader, ",");
- while (tokener.hasMoreTokens()) {
- String nodeTypeFile = tokener.nextToken().trim();
-
- URL mappingURL = bundle.getEntry(nodeTypeFile);
- if (mappingURL == null) {
- log.warn("Mapping {} not found in bundle {}", nodeTypeFile, bundle.getSymbolicName());
- continue;
- }
-
- InputStream ins = null;
- try {
- // laod the descriptors
- ins = mappingURL.openStream();
- NodeTypeLoader.registerNodeType(session, ins);
- } catch (IOException ioe) {
- success = false;
-// log.error("Cannot read node types " + nodeTypeFile
-// + " from bundle " + bundle.getSymbolicName(), ioe);
- log.warn("Cannot read node types {} from bundle {}: {}",
- new Object[]{ nodeTypeFile, bundle.getSymbolicName(), ioe });
- } catch (Exception e) {
- success = false;
-// log.error("Error loading node types " + nodeTypeFile
-// + " from bundle " + bundle.getSymbolicName(), e);
- log.error("Error loading node types {} from bundle {}: {}",
- new Object[]{ nodeTypeFile, bundle.getSymbolicName(), e });
- } finally {
- if (ins != null) {
- try {
- ins.close();
- } catch (IOException ioe) {
- // ignore
- }
- }
- }
- }
- } finally {
- this.ungetSession(session);
- }
-
- return success;
- }
private void installContent(Bundle bundle) throws RepositoryException {
String root = (String) bundle.getHeaders().get(CONTENT_HEADER);
Modified: incubator/sling/trunk/jackrabbit-api/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jackrabbit-api/pom.xml?rev=577648&r1=577647&r2=577648&view=diff
==============================================================================
--- incubator/sling/trunk/jackrabbit-api/pom.xml (original)
+++ incubator/sling/trunk/jackrabbit-api/pom.xml Thu Sep 20 02:07:53 2007
@@ -71,7 +71,8 @@
org.apache.jackrabbit.*;version=1.3.1
</Export-Package>
<Private-Package>
- org.apache.sling.jcr.internal
+ org.apache.sling.jcr.internal,
+ org.apache.sling.jcr.internal.loader
</Private-Package>
</instructions>
</configuration>
@@ -100,6 +101,11 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-io</artifactId>
</dependency>
<!-- OSGi Libraries -->
Modified: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/AbstractSlingRepository.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/AbstractSlingRepository.java?rev=577648&r1=577647&r2=577648&view=diff
==============================================================================
--- incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/AbstractSlingRepository.java (original)
+++ incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/AbstractSlingRepository.java Thu Sep 20 02:07:53 2007
@@ -31,6 +31,10 @@
import org.apache.jackrabbit.api.JackrabbitWorkspace;
import org.apache.sling.jcr.internal.SessionPoolManager;
+import org.apache.sling.jcr.internal.loader.Loader;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.log.LogService;
@@ -56,7 +60,8 @@
* scr.property value="256" type="Integer" name="pool.maxActiveWait"
* </pre>
*/
-public abstract class AbstractSlingRepository implements SlingRepository {
+public abstract class AbstractSlingRepository
+ implements SlingRepository, SynchronousBundleListener {
public static final String PROPERTY_DEFAULT_WORKSPACE = "defaultWorkspace";
@@ -111,6 +116,8 @@
private SessionPoolManager poolManager;
+ private Loader loader;
+
protected AbstractSlingRepository() {
}
@@ -290,6 +297,20 @@
DEFAULT_ADMIN_USER);
this.adminPass = this.getProperty(properties, PROPERTY_ADMIN_PASS,
DEFAULT_ADMIN_PASS).toCharArray();
+
+ this.loader = new Loader(this);
+
+ componentContext.getBundleContext().addBundleListener(this);
+
+ // TODO: Consider running this in the background !!
+ Bundle[] bundles = componentContext.getBundleContext().getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+ // load content for bundles which are neither INSTALLED nor
+ // UNINSTALLED
+ this.loader.registerBundle(bundles[i]);
+ }
+ }
}
/**
@@ -302,8 +323,35 @@
this.poolManager.dispose();
this.poolManager = null;
}
+ if ( this.loader != null ) {
+ this.loader.dispose();
+ this.loader = null;
+ }
this.componentContext = null;
+ }
+
+ /**
+ * Loads and unloads any components provided by the bundle whose state
+ * changed. If the bundle has been started, the components are loaded. If
+ * the bundle is about to stop, the components are unloaded.
+ *
+ * @param event The <code>BundleEvent</code> representing the bundle state
+ * change.
+ */
+ public void bundleChanged(BundleEvent event) {
+ // TODO: This is synchronous - take care to not block the system !!
+ switch (event.getType()) {
+ case BundleEvent.INSTALLED:
+ // register content and types when the bundle content is
+ // available
+ this.loader.registerBundle(event.getBundle());
+ break;
+
+ case BundleEvent.UNINSTALLED:
+ this.loader.unregisterBundle(event.getBundle());
+ break;
+ }
}
// ---------- internal -----------------------------------------------------
Added: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java?rev=577648&view=auto
==============================================================================
--- incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java (added)
+++ incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java Thu Sep 20 02:07:53 2007
@@ -0,0 +1,141 @@
+/*
+ * 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.jcr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeTypeManager;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>NodeTypeSupport</code> contains utility methods to register node
+ * types from a <a href="http://jackrabbit.apache.org/doc/nodetype/cnd.html">CND
+ * nodetype definition</a> file given as an URL or InputStream with the
+ * repository.
+ */
+public class NodeTypeLoader {
+
+ /** default log */
+ private static final Logger log = LoggerFactory.getLogger(NodeTypeLoader.class);
+
+ /**
+ * Registers node types from the CND file accessible by the <code>URL</code>
+ * with the node type manager available from the given <code>session</code>.
+ * <p>
+ * The <code>NodeTypeManager</code> returned by the <code>session</code>'s
+ * workspace is expected to be of type
+ * <code>org.apache.jackrabbit.api.JackrabbitNodeTypeManager</code> for
+ * the node type registration to succeed.
+ * <p>
+ * This method is not synchronized. It is up to the calling method to
+ * prevent paralell execution.
+ *
+ * @param session The <code>Session</code> providing the node type manager
+ * through which the node type is to be registered.
+ * @param URL The URL from which to read the CND file
+ * @return <code>true</code> if registration of all node types succeeded.
+ */
+ public static boolean registerNodeType(Session session, URL source) {
+
+ // Access the node type definition file, "fail" if not available
+ if (source == null) {
+ log.info("No node type definition source available");
+ return false;
+ }
+
+ InputStream ins = null;
+ try {
+ ins = source.openStream();
+ return registerNodeType(session, ins);
+ } catch (IOException ioe) {
+ log.error("Cannot register node types from " + source, ioe);
+ } catch (RepositoryException re) {
+ log.error("Cannot register node types from " + source, re);
+ } finally {
+ IOUtils.closeQuietly(ins);
+ }
+
+ // fall back to failure, reason has been logged
+ return false;
+ }
+
+ /**
+ * Registers node types from the CND file read from the <code>source</code>
+ * with the node type manager available from the given <code>session</code>.
+ * <p>
+ * The <code>NodeTypeManager</code> returned by the <code>session</code>'s
+ * workspace is expected to be of type
+ * <code>org.apache.jackrabbit.api.JackrabbitNodeTypeManager</code> for
+ * the node type registration to succeed.
+ * <p>
+ * This method is not synchronized. It is up to the calling method to
+ * prevent paralell execution.
+ *
+ * @param session The <code>Session</code> providing the node type manager
+ * through which the node type is to be registered.
+ * @param source The <code>InputStream</code> from which the CND file is
+ * read.
+ * @return <code>true</code> if registration of all node types succeeded.
+ */
+ public static boolean registerNodeType(Session session, InputStream source)
+ throws IOException, RepositoryException {
+
+ Workspace workspace = session.getWorkspace();
+ NodeTypeManager ntm = workspace.getNodeTypeManager();
+ if (ntm instanceof JackrabbitNodeTypeManager) {
+ log.debug("Using Jackrabbit to import node types");
+ JackrabbitNodeTypeManager jntm = (JackrabbitNodeTypeManager) ntm;
+ try {
+ jntm.registerNodeTypes(source,
+ JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
+ return true;
+ } catch (RepositoryException re) {
+ Throwable t = re.getCause();
+ if (t != null
+ && t.getClass().getName().endsWith(
+ ".InvalidNodeTypeDefException")) {
+ // hacky wacky: interpret message to check whether it is for
+ // duplicate node type -> very bad, that this is the only
+ // way to check !!!
+ if (re.getCause().getMessage().indexOf("already exists") >= 0) {
+ // alright, node types are already registered, ignore
+ // this
+ log.debug("Node types already registered...");
+ return true;
+ }
+ }
+
+ // get here to rethrow the RepositoryException
+ throw re;
+ }
+ }
+
+ log.warn("Repository is not Jackrabbit based, cannot import node types");
+ return false;
+ }
+}
Propchange: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/NodeTypeLoader.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java?rev=577648&view=auto
==============================================================================
--- incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java (added)
+++ incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java Thu Sep 20 02:07:53 2007
@@ -0,0 +1,171 @@
+/*
+ * 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.jcr.internal.loader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.jcr.AbstractSlingRepository;
+import org.apache.sling.jcr.NodeTypeLoader;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * The <code>Loader</code> TODO
+ */
+public class Loader {
+
+ public static final String NODETYPES_BUNDLE_HEADER = "Sling-Nodetypes";
+
+ /** default log */
+ private static final Logger log = LoggerFactory.getLogger(Loader.class);
+
+ private AbstractSlingRepository slingRepository;
+
+ // bundles whose registration failed and should be retried
+ private List<Bundle> delayedBundles;
+
+ public Loader(AbstractSlingRepository repository) {
+ this.slingRepository = repository;
+ this.delayedBundles = new LinkedList<Bundle>();
+ }
+
+ public void dispose() {
+ if (this.delayedBundles != null) {
+ this.delayedBundles.clear();
+ this.delayedBundles = null;
+ }
+ this.slingRepository = null;
+ }
+
+ public void registerBundle(Bundle bundle) {
+ if (this.registerBundleInternal(bundle)) {
+ // handle delayed bundles, might help now
+ int currentSize = -1;
+ for (int i=this.delayedBundles.size(); i > 0 && currentSize != this.delayedBundles.size() && !this.delayedBundles.isEmpty(); i--) {
+ for (Iterator<Bundle> di=this.delayedBundles.iterator(); di.hasNext(); ) {
+ Bundle delayed = di.next();
+ if (this.registerBundleInternal(delayed)) {
+ di.remove();
+ }
+ }
+ currentSize = this.delayedBundles.size();
+ }
+ } else {
+ // add to delayed bundles
+ this.delayedBundles.add(bundle);
+ }
+ }
+
+ public void unregisterBundle(Bundle bundle) {
+ if ( this.delayedBundles.contains(bundle) ) {
+ this.delayedBundles.remove(bundle);
+ }
+ }
+
+ private boolean registerBundleInternal (Bundle bundle) {
+ try {
+ if (this.registerNodeTypes(bundle)) {
+ return true;
+ }
+ } catch (RepositoryException re) {
+ log.error("Cannot register node types for bundle {}: {}",
+ bundle.getSymbolicName(), re);
+ }
+
+ return false;
+ }
+
+ private boolean registerNodeTypes(Bundle bundle) throws RepositoryException {
+ // TODO: define header referring to mapper files
+ String typesHeader = (String) bundle.getHeaders().get(NODETYPES_BUNDLE_HEADER);
+ if (typesHeader == null) {
+ // no components in the bundle, return with success
+ log.debug("registerNodeTypes: Bundle {} has no nodetypes",
+ bundle.getSymbolicName());
+ return true;
+ }
+
+ boolean success = true;
+ Session session = this.getSession();
+ try {
+ StringTokenizer tokener = new StringTokenizer(typesHeader, ",");
+ while (tokener.hasMoreTokens()) {
+ String nodeTypeFile = tokener.nextToken().trim();
+
+ URL mappingURL = bundle.getEntry(nodeTypeFile);
+ if (mappingURL == null) {
+ log.warn("Mapping {} not found in bundle {}", nodeTypeFile, bundle.getSymbolicName());
+ continue;
+ }
+
+ InputStream ins = null;
+ try {
+ // laod the descriptors
+ ins = mappingURL.openStream();
+ NodeTypeLoader.registerNodeType(session, ins);
+ } catch (IOException ioe) {
+ success = false;
+// log.error("Cannot read node types " + nodeTypeFile
+// + " from bundle " + bundle.getSymbolicName(), ioe);
+ log.warn("Cannot read node types {} from bundle {}: {}",
+ new Object[]{ nodeTypeFile, bundle.getSymbolicName(), ioe });
+ } catch (Exception e) {
+ success = false;
+// log.error("Error loading node types " + nodeTypeFile
+// + " from bundle " + bundle.getSymbolicName(), e);
+ log.error("Error loading node types {} from bundle {}: {}",
+ new Object[]{ nodeTypeFile, bundle.getSymbolicName(), e });
+ } finally {
+ if (ins != null) {
+ try {
+ ins.close();
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+ }
+ }
+ } finally {
+ this.ungetSession(session);
+ }
+
+ return success;
+ }
+
+ private Session getSession() throws RepositoryException {
+ return this.slingRepository.loginAdministrative(null);
+ }
+
+ private void ungetSession(Session session) {
+ if (session != null) {
+ session.logout();
+ }
+ }
+}
Propchange: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/jackrabbit-api/src/main/java/org/apache/sling/jcr/internal/loader/Loader.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url