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 2012/03/26 21:50:41 UTC
svn commit: r1305516 - in
/sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal:
./ net/
Author: cziegeler
Date: Mon Mar 26 19:50:41 2012
New Revision: 1305516
URL: http://svn.apache.org/viewvc?rev=1305516&view=rev
Log:
SLING-2447 : ClassLoaderWriter should provide class loader for loading written classes/resources
Removed:
sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/FileParts.java
sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/URLFactory.java
Modified:
sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/ClassLoaderWriterImpl.java
sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/RepositoryClassLoader.java
sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLConnection.java
sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLHandler.java
Modified: sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/ClassLoaderWriterImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/ClassLoaderWriterImpl.java?rev=1305516&r1=1305515&r2=1305516&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/ClassLoaderWriterImpl.java (original)
+++ sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/ClassLoaderWriterImpl.java Mon Mar 26 19:50:41 2012
@@ -136,7 +136,7 @@ public class ClassLoaderWriterImpl
/**
* Return a new session.
*/
- public Session getSession() throws RepositoryException {
+ public Session createSession() throws RepositoryException {
// get an administrative session for potentiall impersonation
final Session admin = this.repository.loginAdministrative(null);
@@ -180,7 +180,7 @@ public class ClassLoaderWriterImpl
final String path = cleanPath(name);
Session session = null;
try {
- session = getSession();
+ session = createSession();
if (session.itemExists(path)) {
Item fileItem = session.getItem(path);
fileItem.remove();
@@ -217,7 +217,7 @@ public class ClassLoaderWriterImpl
final String oldPath = cleanPath(oldName);
final String newPath = cleanPath(newName);
- session = this.getSession();
+ session = this.createSession();
session.move(oldPath, newPath);
session.save();
this.repositoryClassLoader.handleEvent(oldName);
@@ -338,7 +338,7 @@ public class ClassLoaderWriterImpl
Session session = null;
try {
// get an own session for writing
- session = repositoryOutputProvider.getSession();
+ session = repositoryOutputProvider.createSession();
final int lastPos = fileName.lastIndexOf('/');
final String path = (lastPos == -1 ? null : fileName.substring(0, lastPos));
final String name = (lastPos == -1 ? fileName : fileName.substring(lastPos + 1));
@@ -425,7 +425,7 @@ public class ClassLoaderWriterImpl
final String path = cleanPath(name) + "/jcr:content/jcr:data";
Session session = null;
try {
- session = this.getSession();
+ session = this.createSession();
if ( session.itemExists(path) ) {
final Property prop = (Property)session.getItem(path);
return prop.getStream();
@@ -448,7 +448,7 @@ public class ClassLoaderWriterImpl
final String path = cleanPath(name) + "/jcr:content/jcr:lastModified";
Session session = null;
try {
- session = this.getSession();
+ session = this.createSession();
if ( session.itemExists(path) ) {
final Property prop = (Property)session.getItem(path);
return prop.getLong();
Modified: sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/RepositoryClassLoader.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/RepositoryClassLoader.java?rev=1305516&r1=1305515&r2=1305516&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/RepositoryClassLoader.java (original)
+++ sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/RepositoryClassLoader.java Mon Mar 26 19:50:41 2012
@@ -34,7 +34,7 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.sling.commons.classloader.DynamicClassLoader;
-import org.apache.sling.jcr.classloader.internal.net.URLFactory;
+import org.apache.sling.jcr.classloader.internal.net.JCRURLHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,11 +83,6 @@ public final class RepositoryClassLoader
private boolean destroyed = false;
/**
- * Session to serve urls.
- */
- private Session urlHandlerSession;
-
- /**
* Creates a <code>RepositoryClassLoader</code> for a given
* repository path.
*
@@ -140,11 +135,6 @@ public final class RepositoryClassLoader
// set destroyal guard
destroyed = true;
- if ( this.urlHandlerSession != null ) {
- this.urlHandlerSession.logout();
- this.urlHandlerSession = null;
- }
-
this.writer = null;
this.repositoryPath = null;
synchronized ( this.usedResources ) {
@@ -202,7 +192,7 @@ public final class RepositoryClassLoader
try {
if ( findClassLoaderResource(path) != null ) {
logger.debug("findResource: Getting resource from {}", path);
- return URLFactory.createURL(this.getUrlHandlerSession(), path);
+ return JCRURLHandler.createURL(this.writer, path);
}
} catch (final Exception e) {
logger.warn("findResource: Cannot getURL for " + name, e);
@@ -211,21 +201,6 @@ public final class RepositoryClassLoader
return null;
}
- private synchronized Session getUrlHandlerSession() {
- if ( this.urlHandlerSession != null && !this.urlHandlerSession.isLive() ) {
- this.urlHandlerSession.logout();
- this.urlHandlerSession = null;
- }
- if ( this.urlHandlerSession == null ) {
- try {
- this.urlHandlerSession = this.writer.getSession();
- } catch ( final RepositoryException re ) {
- logger.warn("Unable to create new session.", re);
- }
- }
- return this.urlHandlerSession;
- }
-
/**
* Returns an Enumeration of URLs representing all of the resources
* on the search path having the specified name.
@@ -324,7 +299,7 @@ public final class RepositoryClassLoader
Session session = null;
byte[] res = null;
try {
- session = this.writer.getSession();
+ session = this.writer.createSession();
if ( session.itemExists(path) ) {
final Node node = (Node)session.getItem(path);
logger.debug("Found resource at {}", path);
Modified: sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLConnection.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLConnection.java?rev=1305516&r1=1305515&r2=1305516&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLConnection.java (original)
+++ sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLConnection.java Mon Mar 26 19:50:41 2012
@@ -16,6 +16,7 @@
*/
package org.apache.sling.jcr.classloader.internal.net;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -26,7 +27,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
@@ -63,17 +63,6 @@ import org.slf4j.LoggerFactory;
* {@link #connect()} fails and access to the content is not possible.
* </ul>
* <p>
- * After having connected the property is available through the
- * {@link #getProperty()} method. Other methods exist to retrieve repository
- * related information defined when creating the URL: {@link #getSession()} to
- * retrieve the session of the URL, {@link #getPath()} to retrieve the path
- * with which the URL was created and {@link #getItem()} to retrieve the item
- * with which the URL was created. The results of calling {@link #getProperty()}
- * and {@link #getItem()} will be the same if the URL directly addressed the
- * property. If the URL addressed the node whose primary item chain ultimately
- * resolved to the property, the {@link #getItem()} will return the node and
- * {@link #getProperty()} will return the resolved property.
- * <p>
* A note on the <code>InputStream</code> available from
* {@link #getInputStream()}: Unlike other implementations - for example
* for <code>file:</code> or <code>http:</code> URLs - which return the same
@@ -119,39 +108,39 @@ public class JCRURLConnection extends UR
* The name of the header containing the content size (value is
* "content-length").
*/
- protected static final String CONTENT_LENGTH = "content-length";
+ private static final String CONTENT_LENGTH = "content-length";
/**
* The name of the header containing the MIME type of the content (value is
* "content-type").
*/
- protected static final String CONTENT_TYPE = "content-type";
+ private static final String CONTENT_TYPE = "content-type";
/**
* The name of the header containing the content encoding (value is
* "content-encoding").
*/
- protected static final String CONTENT_ENCODING = "content-encoding";
+ private static final String CONTENT_ENCODING = "content-encoding";
/**
* The name of the header containing the last modification time stamp of
* the content (value is "last-modified").
*/
- protected static final String LAST_MODIFIED = "last-modified";
+ private static final String LAST_MODIFIED = "last-modified";
/**
* The default content type name for binary properties accessed by this
* connection (value is "application/octet-stream").
* @see #connect()
*/
- protected static final String APPLICATION_OCTET = "application/octet-stream";
+ private static final String APPLICATION_OCTET = "application/octet-stream";
/**
* The default content type name for non-binary properties accessed by this
* connection (value is "text/plain").
* @see #connect()
*/
- protected static final String TEXT_PLAIN = "text/plain";
+ private static final String TEXT_PLAIN = "text/plain";
/**
* The handler associated with the URL of this connection. This handler
@@ -161,31 +150,13 @@ public class JCRURLConnection extends UR
private final JCRURLHandler handler;
/**
- * The {@link FileParts} encapsulating the repository name, workspace name,
- * item path and optional archive entry path contained in the file part
- * of the URL. This field is set on-demand by the {@link #getFileParts()}
- * method.
- *
- * @see #getFileParts()
- */
- private FileParts fileParts;
-
- /**
- * The <code>Item</code> addressed by the path of this connection's URL.
- * This field is set on-demand by the {@link #getItem()} method.
- *
- * @see #getItem()
- */
- private Item item;
-
- /**
* The <code>Property</code> associated with the URLConnection. The field
* is only set after the connection has been successfully opened.
*
* @see #getProperty()
* @see #connect()
*/
- private Property property;
+ private byte[] contents;
/**
* The (guessed) content type of the data. Currently the content type is
@@ -244,52 +215,19 @@ public class JCRURLConnection extends UR
* @param url The URL to base the connection on.
* @param handler The URL handler supporting the given URL.
*/
- JCRURLConnection(URL url, JCRURLHandler handler) {
+ JCRURLConnection(final URL url, final JCRURLHandler handler) {
super(url);
this.handler = handler;
}
/**
- * Returns the current session of URL.
- * <p>
- * Calling this method does not require this connection being connected.
- */
- public Session getSession() {
- return handler.getSession();
- }
-
- /**
* Returns the path to the repository item underlying the URL of this
* connection.
* <p>
* Calling this method does not require this connection being connected.
*/
- public String getPath() {
- return getFileParts().getPath();
- }
-
- /**
- * Returns the repository item underlying the URL of this connection
- * retrieved through the path set on the URL.
- * <p>
- * Calling this method does not require this connection being connected.
- *
- * @throws IOException If the item has to be retrieved from the repository
- * <code>Session</code> of this connection and an error occurrs. The
- * cause of the exception will refer to the exception thrown from the
- * repository. If the path addresses a non-existing item, the cause
- * will be a <code>PathNotFoundException</code>.
- */
- public Item getItem() throws IOException {
- if (item == null) {
- try {
- item = getSession().getItem(getPath());
- } catch (RepositoryException re) {
- throw failure("getItem", re.toString(), re);
- }
- }
-
- return item;
+ private String getPath() {
+ return this.handler.getPath();
}
/**
@@ -304,18 +242,17 @@ public class JCRURLConnection extends UR
*
* @see #connect()
*/
- public Property getProperty() throws IOException {
+ private byte[] getContents() throws IOException {
// connect to set the property value
connect();
- return property;
+ return this.contents;
}
//---------- URLConnection overwrites -------------------------------------
/**
- * Connects to the URL setting the header fields and preparing for the
- * {@link #getProperty()} and {@link #getInputStream()} methods.
+ * Connects to the URL setting the header fields and getting the contents.
* <p>
* The following algorithm is applied:
* <ol>
@@ -353,22 +290,25 @@ public class JCRURLConnection extends UR
* exception.
*/
public synchronized void connect() throws IOException {
- // todo: The ContentBus URL must also contain version information on
if (!connected) {
// Get hold of the data
+ Session session = null;
try {
+ session = this.handler.getClassLoaderWriter().createSession();
+ final Node node = (Node)session.getItem(this.getPath());
// resolve the URLs item to a property
- Property property = Util.getProperty(getItem());
+ final Property property = Util.getProperty(node);
if (property == null) {
throw failure("connect",
"Multivalue property not supported", null);
}
+ final byte[] contents = Util.getBytes(node);
+
// values to set later
String contentType;
String contentEncoding = null; // no defined content encoding
- int contentLength = (int) property.getLength();
long lastModified;
Node parent = property.getParent();
@@ -381,7 +321,7 @@ public class JCRURLConnection extends UR
if (parent.hasProperty("jcr:mimeType")) {
contentType = parent.getProperty("jcr:mimeType").getString();
} else {
- contentType = guessContentTypeFromName(getItem().getName());
+ contentType = guessContentTypeFromName(node.getName());
if (contentType == null) {
contentType = (property.getType() == PropertyType.BINARY)
? APPLICATION_OCTET
@@ -399,17 +339,21 @@ public class JCRURLConnection extends UR
new Integer(contentLength) });
// set the fields
- setProperty(property);
- setContentType(contentType);
- setContentEncoding(contentEncoding);
- setContentLength(contentLength);
- setLastModified(lastModified);
+ this.contents = contents;
+ this.contentType = contentType;
+ this.contentEncoding = contentEncoding;
+ this.contentLength = contents.length;
+ this.lastModified = lastModified;
// mark connection open
connected = true;
- } catch (RepositoryException re) {
+ } catch (final RepositoryException re) {
throw failure("connect", re.toString(), re);
+ } finally {
+ if ( session != null ) {
+ session.logout();
+ }
}
}
}
@@ -434,11 +378,7 @@ public class JCRURLConnection extends UR
* @see #connect()
*/
public InputStream getInputStream() throws IOException {
- try {
- return getProperty().getStream();
- } catch (RepositoryException re) {
- throw failure("getInputStream", re.toString(), re);
- }
+ return new ByteArrayInputStream(this.getContents());
}
/**
@@ -680,62 +620,6 @@ public class JCRURLConnection extends UR
return -1;
}
- //---------- implementation helpers ----------------------------------------
-
- /**
- * Returns the URL handler of the URL of this connection.
- */
- protected JCRURLHandler getHandler() {
- return handler;
- }
-
- /**
- * Returns the {@link FileParts} object which contains the decomposed file
- * part of this connection's URL.
- */
- FileParts getFileParts() {
- if (fileParts == null) {
- fileParts = new FileParts(getURL().getFile());
- }
-
- return fileParts;
- }
-
- /**
- * @param contentEncoding The contentEncoding to set.
- */
- protected void setContentEncoding(String contentEncoding) {
- this.contentEncoding = contentEncoding;
- }
-
- /**
- * @param contentLength The contentLength to set.
- */
- protected void setContentLength(int contentLength) {
- this.contentLength = contentLength;
- }
-
- /**
- * @param contentType The contentType to set.
- */
- protected void setContentType(String contentType) {
- this.contentType = contentType;
- }
-
- /**
- * @param lastModified The lastModified to set.
- */
- protected void setLastModified(long lastModified) {
- this.lastModified = lastModified;
- }
-
- /**
- * @param property The property to set.
- */
- protected void setProperty(Property property) {
- this.property = property;
- }
-
//---------- internal -----------------------------------------------------
/**
@@ -751,7 +635,7 @@ public class JCRURLConnection extends UR
*
* @return The IOException the caller may throw.
*/
- protected IOException failure(String method, String message, Throwable cause) {
+ private IOException failure(String method, String message, Throwable cause) {
log.info(method + ": URL: " + url.toExternalForm() + ", Reason: "
+ message);
Modified: sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLHandler.java?rev=1305516&r1=1305515&r2=1305516&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLHandler.java (original)
+++ sling/trunk/bundles/jcr/classloader/src/main/java/org/apache/sling/jcr/classloader/internal/net/JCRURLHandler.java Mon Mar 26 19:50:41 2012
@@ -16,11 +16,12 @@
*/
package org.apache.sling.jcr.classloader.internal.net;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
-import javax.jcr.Session;
+import org.apache.sling.jcr.classloader.internal.ClassLoaderWriterImpl;
/**
* The <code>JCRURLHandler</code> is the <code>URLStreamHandler</code> for
@@ -29,49 +30,77 @@ import javax.jcr.Session;
* JCR Repository URLs have not been standardized yet and may only be created
* in the context of an existing <code>Session</code>. Therefore this handler
* is not globally available and JCR Repository URLs may only be created through
- * the factory methods in the {@link org.apache.sling.jcr.classloader.internal.net.URLFactory}
- * class.
+ * the factory method.
* <p>
* This class is not intended to be subclassed or instantiated by clients.
*
- * @author Felix Meschberger
- *
* @see org.apache.sling.jcr.classloader.internal.net.JCRURLConnection
- * @see org.apache.sling.jcr.classloader.internal.net.URLFactory
- * @see org.apache.sling.jcr.classloader.internal.net.URLFactory#createURL(Session, String)
*/
-class JCRURLHandler extends URLStreamHandler {
+public class JCRURLHandler extends URLStreamHandler {
+
+ /**
+ * The scheme for JCR Repository URLs (value is "jcr").
+ */
+ private static final String REPOSITORY_SCHEME = "jcr";
+
+ /**
+ * The writer provides access to a new session.
+ *
+ * @see #createSession()
+ */
+ private final ClassLoaderWriterImpl writer;
+
+ /**
+ * The repository path to the underlying item.
+ */
+ private final String path;
/**
- * The session used to create this handler, which is also used to open
- * the connection object.
+ * Creates a new JCR Repository URL for the given session and item path.
+ *
+ * @param writer The writer session providing access to the item.
+ * @param path The absolute path to the item. This must be an absolute
+ * path with a leading slash character. If this is <code>null</code>
+ * the root node path - <code>/</code> - is assumed.
*
- * @see #getSession()
+ * @return The JCR Repository URL
+ *
+ * @throws MalformedURLException If an error occurrs creating the
+ * <code>URL</code> instance.
*/
- private final Session session;
+ public static URL createURL(final ClassLoaderWriterImpl writer, final String path)
+ throws MalformedURLException {
+ return new URL(REPOSITORY_SCHEME, "", -1,
+ path,
+ new JCRURLHandler(writer, path));
+ }
/**
* Creates a new instance of the <code>JCRURLHandler</code> with the
* given session.
*
- * @param session The <code>Session</code> supporting this handler. This
- * must not be <code>null</code>.
+ * @param writer The dynamic class loader writer
*
* @throws NullPointerException if <code>session</code> is <code>null</code>.
*/
- JCRURLHandler(Session session) {
- if (session == null) {
- throw new NullPointerException("session");
+ JCRURLHandler(final ClassLoaderWriterImpl writer, final String path) {
+ if (writer == null) {
+ throw new NullPointerException("writer");
}
- this.session = session;
+ this.writer = writer;
+ this.path = path;
}
/**
* Returns the session supporting this handler.
*/
- Session getSession() {
- return session;
+ ClassLoaderWriterImpl getClassLoaderWriter() {
+ return this.writer;
+ }
+
+ String getPath() {
+ return this.path;
}
//---------- URLStreamHandler abstracts ------------------------------------
@@ -85,63 +114,7 @@ class JCRURLHandler extends URLStreamHan
*
* @see JCRURLConnection
*/
- protected URLConnection openConnection(URL url) {
+ protected URLConnection openConnection(final URL url) {
return new JCRURLConnection(url, this);
}
-
- /**
- * Checks the new <code>authority</code> and <code>path</code> before
- * actually setting the values on the url calling the base class
- * implementation.
- * <p>
- * We check the authority to not have been modified from the original URL,
- * as the authority is dependent on the repository <code>Session</code> on
- * which this handler is based and which was used to create the original
- * URL. Likewise the repository and workspace name parts of the path must
- * not have changed.
- *
- * @param u the URL to modify.
- * @param protocol the protocol name.
- * @param host the remote host value for the URL.
- * @param port the port on the remote machine.
- * @param authority the authority part for the URL.
- * @param userInfo the userInfo part of the URL.
- * @param path the path component of the URL.
- * @param query the query part for the URL.
- * @param ref the reference.
- *
- * @throws IllegalArgumentException if the authority or the repository name
- * or workspace name parts of the path has changed.
- */
- protected void setURL(URL u, String protocol, String host, int port,
- String authority, String userInfo, String path, String query, String ref) {
-
- // check for authority
- if (u.getAuthority() != authority) {
- if (u.getAuthority() == null) {
- if (authority != null) {
- throw new IllegalArgumentException("Authority " +
- authority + " not supported by this handler");
- }
- } else if (!u.getAuthority().equals(authority)) {
- throw new IllegalArgumentException("Authority " +
- authority + " not supported by this handler");
- }
- }
-
- // check for repository and/or workspace modifications
- FileParts newParts = new FileParts(path);
- if (!"_".equals(newParts.getRepository())) {
- throw new IllegalArgumentException("Repository " +
- newParts.getRepository() + " not supported by this handler");
- }
- if (!session.getWorkspace().getName().equals(newParts.getWorkspace())) {
- throw new IllegalArgumentException("Workspace " +
- newParts.getWorkspace() + " not supported by this handler");
- }
-
- // finally set the new values on the URL
- super.setURL(u, protocol, host, port, authority, userInfo, path, query,
- ref);
- }
}