You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2012/01/27 20:07:39 UTC
svn commit: r1236837 - in /jackrabbit/branches/2.4: ./ jackrabbit-jcr-server/
jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/
jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/jcr/
jackrabbit-jcr-server/src/main/java/or...
Author: jukka
Date: Fri Jan 27 19:07:38 2012
New Revision: 1236837
URL: http://svn.apache.org/viewvc?rev=1236837&view=rev
Log:
2.4: Merged revisions 1236819, 1236820 and 1236821 (JCR-3222)
Added:
jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/package-info.java
- copied unchanged from r1236819, jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/package-info.java
Modified:
jackrabbit/branches/2.4/ (props changed)
jackrabbit/branches/2.4/jackrabbit-jcr-server/pom.xml
jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/SessionProviderImpl.java
jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/jcr/JCRWebdavServer.java
jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/DavexServletService.java
jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
Propchange: jackrabbit/branches/2.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 27 19:07:38 2012
@@ -1,3 +1,3 @@
/jackrabbit/branches/JCR-2272:1173165-1176545
/jackrabbit/sandbox/JCR-2415-lucene-3.0:1060860-1064038
-/jackrabbit/trunk:1221447,1221579,1221593,1221789,1221818,1225179,1225191,1225196,1225207,1225525,1225528,1226452,1226472,1226515,1226750,1226863,1227171,1227240,1227590,1227593,1227615,1228058,1228149,1228155,1228160,1230507,1230681,1230688,1231204,1232035,1232100,1232404,1232831,1232920,1232922,1233069,1233344,1233446,1233468,1233471,1234807,1235192,1235375,1235423,1236775
+/jackrabbit/trunk:1221447,1221579,1221593,1221789,1221818,1225179,1225191,1225196,1225207,1225525,1225528,1226452,1226472,1226515,1226750,1226863,1227171,1227240,1227590,1227593,1227615,1228058,1228149,1228155,1228160,1230507,1230681,1230688,1231204,1232035,1232100,1232404,1232831,1232920,1232922,1233069,1233344,1233446,1233468,1233471,1234807,1235192,1235375,1235423,1236775,1236819-1236821
Modified: jackrabbit/branches/2.4/jackrabbit-jcr-server/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-server/pom.xml?rev=1236837&r1=1236836&r2=1236837&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-server/pom.xml (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-server/pom.xml Fri Jan 27 19:07:38 2012
@@ -71,13 +71,8 @@
<configuration>
<instructions>
<Export-Package>
- !*
+ org.apache.jackrabbit.server
</Export-Package>
- <Private-Package>
- org.apache.jackrabbit.server.*,
- org.apache.jackrabbit.webdav.jcr.*,
- org.apache.jackrabbit.webdav.simple
- </Private-Package>
</instructions>
</configuration>
</plugin>
@@ -208,7 +203,12 @@
<version>1.6.0</version>
<scope>provided</scope>
</dependency>
-
+ <dependency>
+ <groupId>biz.aQute</groupId>
+ <artifactId>bndlib</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Modified: jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/SessionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/SessionProviderImpl.java?rev=1236837&r1=1236836&r2=1236837&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/SessionProviderImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/SessionProviderImpl.java Fri Jan 27 19:07:38 2012
@@ -16,9 +16,9 @@
*/
package org.apache.jackrabbit.server;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Locale;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import javax.jcr.Credentials;
import javax.jcr.LoginException;
@@ -28,24 +28,31 @@ import javax.jcr.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
-import org.apache.jackrabbit.commons.webdav.JcrRemotingConstants;
-import org.apache.jackrabbit.spi.commons.SessionExtensions;
-import org.apache.jackrabbit.util.Text;
-import org.apache.jackrabbit.webdav.util.LinkHeaderFieldParser;
-
/**
- * This Class implements a default session provider uses a credentials provider.
+ * This class implements a default session provider based on a given
+ * {@link CredentialsProvider credentials provider}. Additionally,
+ * since Jackrabbit 2.4, if another session provider is available as
+ * the "org.apache.jackrabbit.server.SessionProvider" request attribute,
+ * then that provider is asked first for a session before the default
+ * credential-based login mechanism is used.
*/
public class SessionProviderImpl implements SessionProvider {
- public static final String ATTRIBUTE_SESSION_ID = SessionProviderImpl.class + "#sessionid()";
-
/**
* the credentials provider
*/
private CredentialsProvider cp;
/**
+ * Map of sessions acquired from custom session providers looked up
+ * from request attributes. We need to keep track of such providers
+ * so we can route the {@link #releaseSession(Session)} call to the
+ * correct provider.
+ */
+ private final Map<Session, SessionProvider> externalSessions =
+ Collections.synchronizedMap(new HashMap<Session, SessionProvider>());
+
+ /**
* Creates a new SessionProvider
*
* @param cp
@@ -60,25 +67,28 @@ public class SessionProviderImpl impleme
public Session getSession(HttpServletRequest request,
Repository repository, String workspace) throws LoginException,
RepositoryException, ServletException {
- Credentials creds = cp.getCredentials(request);
- Session s;
- if (creds == null) {
- s = repository.login(workspace);
- } else {
- s = repository.login(creds, workspace);
+ Session s = null;
+
+ // JCR-3222: Check if a custom session provider is available as a
+ // request attribute. If one is available, ask it first for a session.
+ Object object = request.getAttribute(SessionProvider.class.getName());
+ if (object instanceof SessionProvider) {
+ SessionProvider provider = (SessionProvider) object;
+ s = provider.getSession(request, repository, workspace);
+ if (s != null) {
+ externalSessions.put(s, provider);
+ }
}
- // extract information from Link header fields
- LinkHeaderFieldParser lhfp = new LinkHeaderFieldParser(
- request.getHeaders("Link"));
- String userData = getJcrUserData(lhfp);
- s.getWorkspace().getObservationManager().setUserData(userData);
-
- String sessionId = getSessionIdentifier(lhfp);
- if (s instanceof SessionExtensions) {
- SessionExtensions xs = (SessionExtensions) s;
- xs.setAttribute(ATTRIBUTE_SESSION_ID, sessionId);
+ if (s == null) {
+ Credentials creds = cp.getCredentials(request);
+ if (creds == null) {
+ s = repository.login(workspace);
+ } else {
+ s = repository.login(creds, workspace);
+ }
}
+
return s;
}
@@ -86,49 +96,14 @@ public class SessionProviderImpl impleme
* {@inheritDoc }
*/
public void releaseSession(Session session) {
- session.logout();
- }
-
- // find first link relation for JCR User Data
- private String getJcrUserData(LinkHeaderFieldParser lhfp) {
- String jcrUserData = null;
- String target = lhfp
- .getFirstTargetForRelation(JcrRemotingConstants.RELATION_USER_DATA);
- if (target != null) {
- jcrUserData = getJcrUserData(target);
+ // JCR-3222: If the session was acquired from a custom session
+ // provider, we need to ask that provider to release the session.
+ SessionProvider provider = externalSessions.remove(session);
+ if (provider != null) {
+ provider.releaseSession(session);
+ } else {
+ session.logout();
}
-
- return jcrUserData;
- }
-
- // find first link relation for remote session identifier
- private String getSessionIdentifier(LinkHeaderFieldParser lhfp) {
- return lhfp
- .getFirstTargetForRelation(JcrRemotingConstants.RELATION_REMOTE_SESSION_ID);
}
- // extracts User Data string from RFC 2397 "data" URI
- // only supports the simple case of "data:,..." for now
- private String getJcrUserData(String target) {
- try {
- URI datauri = new URI(target);
-
- String scheme = datauri.getScheme();
-
- // Poor Man's data: URI parsing
- if (scheme != null
- && "data".equals(scheme.toLowerCase(Locale.ENGLISH))) {
-
- String sspart = datauri.getRawSchemeSpecificPart();
-
- if (sspart.startsWith(",")) {
- return Text.unescape(sspart.substring(1));
- }
- }
- } catch (URISyntaxException ex) {
- // not a URI, skip
- }
-
- return null;
- }
}
Modified: jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/jcr/JCRWebdavServer.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/jcr/JCRWebdavServer.java?rev=1236837&r1=1236836&r2=1236837&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/jcr/JCRWebdavServer.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/jcr/JCRWebdavServer.java Fri Jan 27 19:07:38 2012
@@ -16,7 +16,10 @@
*/
package org.apache.jackrabbit.server.jcr;
+import org.apache.jackrabbit.commons.webdav.JcrRemotingConstants;
import org.apache.jackrabbit.server.SessionProvider;
+import org.apache.jackrabbit.spi.commons.SessionExtensions;
+import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavMethods;
import org.apache.jackrabbit.webdav.DavSession;
@@ -25,6 +28,7 @@ import org.apache.jackrabbit.webdav.Webd
import org.apache.jackrabbit.webdav.header.IfHeader;
import org.apache.jackrabbit.webdav.jcr.JcrDavException;
import org.apache.jackrabbit.webdav.jcr.JcrDavSession;
+import org.apache.jackrabbit.webdav.util.LinkHeaderFieldParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,8 +36,12 @@ import javax.jcr.LoginException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
+
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@@ -325,7 +333,17 @@ public class JCRWebdavServer implements
if (DavMethods.DAV_MKWORKSPACE != DavMethods.getMethodCode(request.getMethod())) {
workspaceName = request.getRequestLocator().getWorkspaceName();
}
- return sessionProvider.getSession(request, repository, workspaceName);
+
+ Session session = sessionProvider.getSession(
+ request, repository, workspaceName);
+
+ // extract information from Link header fields
+ LinkHeaderFieldParser lhfp =
+ new LinkHeaderFieldParser(request.getHeaders("Link"));
+ setJcrUserData(session, lhfp);
+ setSessionIdentifier(session, lhfp);
+
+ return session;
} catch (LoginException e) {
// LoginException results in UNAUTHORIZED,
throw new JcrDavException(e);
@@ -337,6 +355,53 @@ public class JCRWebdavServer implements
}
}
+ /**
+ * Find first link relation for JCR user data and set it as
+ * the user data of the observation manager of the given session.
+ */
+ private void setJcrUserData(
+ Session session, LinkHeaderFieldParser lhfp)
+ throws RepositoryException {
+ String data = null;
+
+ // extract User Data string from RFC 2397 "data" URI
+ // only supports the simple case of "data:,..." for now
+ String target = lhfp.getFirstTargetForRelation(
+ JcrRemotingConstants.RELATION_USER_DATA);
+ if (target != null) {
+ try {
+ URI uri = new URI(target);
+ // Poor Man's data: URI parsing
+ if ("data".equalsIgnoreCase(uri.getScheme())) {
+ String sspart = uri.getRawSchemeSpecificPart();
+ if (sspart.startsWith(",")) {
+ data = Text.unescape(sspart.substring(1));
+ }
+ }
+ } catch (URISyntaxException ex) {
+ // not a URI, skip
+ }
+ }
+
+ try {
+ session.getWorkspace().getObservationManager().setUserData(data);
+ } catch (UnsupportedRepositoryOperationException ignore) {
+ }
+ }
+
+ /**
+ * Find first link relation for remote session identifier and set
+ * it as an attribute of the given session.
+ */
+ private void setSessionIdentifier(
+ Session session, LinkHeaderFieldParser lhfp) {
+ if (session instanceof SessionExtensions) {
+ String name = JcrRemotingConstants.RELATION_REMOTE_SESSION_ID;
+ String id = lhfp.getFirstTargetForRelation(name);
+ ((SessionExtensions) session).setAttribute(name, id);
+ }
+ }
+
private String getUserID(DavSession session) {
try {
Session s = DavSessionImpl.getRepositorySession(session);
Modified: jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/DavexServletService.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/DavexServletService.java?rev=1236837&r1=1236836&r2=1236837&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/DavexServletService.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/DavexServletService.java Fri Jan 27 19:07:38 2012
@@ -18,17 +18,29 @@
*/
package org.apache.jackrabbit.server.remoting.davex;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
+import javax.jcr.LoginException;
import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
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.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.server.SessionProvider;
import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
import org.apache.jackrabbit.webdav.util.CSRFUtil;
@@ -38,8 +50,15 @@ import org.apache.jackrabbit.webdav.util
@Property(name = "service.description", value = "Apache Jackrabbit JcrRemoting Servlet"),
@Property(name = JcrRemotingServlet.INIT_PARAM_AUTHENTICATE_HEADER, value = AbstractWebdavServlet.DEFAULT_AUTHENTICATE_HEADER),
@Property(name = JcrRemotingServlet.INIT_PARAM_CSRF_PROTECTION, value = CSRFUtil.DISABLED),
- @Property(name = JcrRemotingServlet.INIT_PARAM_MISSING_AUTH_MAPPING, value = "") })
-public class DavexServletService extends JcrRemotingServlet {
+ @Property(name = JcrRemotingServlet.INIT_PARAM_MISSING_AUTH_MAPPING, value = ""),
+ @Property(name = "contextId", value = "") })
+@Reference(
+ name = "providers", referenceInterface = SessionProvider.class,
+ policy = ReferencePolicy.DYNAMIC,
+ cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
+ bind = "addSessionProvider", unbind = "removeSessionProvider")
+public class DavexServletService extends JcrRemotingServlet
+ implements SessionProvider {
/** Serial version UID */
private static final long serialVersionUID = -901601294536148635L;
@@ -54,6 +73,22 @@ public class DavexServletService extends
private String alias;
+ /**
+ * Currently available custom session providers. They're used
+ * first before the default provider gets consulted. The associated
+ * set of sessions is used to forcibly release all sessions acquired
+ * from a provider when that provider is being removed.
+ */
+ private final Map<SessionProvider, Set<Session>> providers =
+ new LinkedHashMap<SessionProvider, Set<Session>>();
+
+ /**
+ * Currently active sessions. Used to link a session to the correct
+ * provider in the {@link #releaseSession(Session)} method.
+ */
+ private final Map<Session, SessionProvider> sessions =
+ new HashMap<Session, SessionProvider>();
+
@Override
protected Repository getRepository() {
return repository;
@@ -78,4 +113,78 @@ public class DavexServletService extends
}
}
+ @Override
+ protected SessionProvider getSessionProvider() {
+ return this;
+ }
+
+ /**
+ * Adds a custom session provider service.
+ *
+ * @param provider session provider
+ */
+ public synchronized void addSessionProvider(SessionProvider provider) {
+ providers.put(provider, new HashSet<Session>());
+ }
+
+ /**
+ * Removes a custom session provider service. All active sessions
+ * acquired from that provider are forcibly released.
+ *
+ * @param provider session provider
+ */
+ public synchronized void removeSessionProvider(SessionProvider provider) {
+ Set<Session> sessions = providers.remove(provider);
+ if (sessions != null) {
+ for (Session session : sessions) {
+ releaseSession(session);
+ }
+ }
+ }
+
+ //-----------------------------------------------------< SessionProvider >
+
+ /**
+ * Asks each available session provider in order for a session and
+ * returns the first session given. The default provider is used
+ * if no custom provider service is available or can provide a requested
+ * session.
+ */
+ public synchronized Session getSession(
+ HttpServletRequest request, Repository repository, String workspace)
+ throws LoginException, ServletException, RepositoryException {
+ SessionProvider provider = null;
+ Session session = null;
+
+ for (Map.Entry<SessionProvider, Set<Session>> entry : providers.entrySet()) {
+ provider = entry.getKey();
+ session = provider.getSession(request, repository, workspace);
+ if (session != null) {
+ entry.getValue().add(session);
+ break;
+ }
+ }
+
+ if (session == null) {
+ provider = super.getSessionProvider();
+ session = provider.getSession(request, repository, workspace);
+ }
+
+ if (session != null) {
+ sessions.put(session, provider);
+ }
+
+ return session;
+ }
+
+ /**
+ * Releases the given session using the provider from which it was acquired.
+ */
+ public synchronized void releaseSession(Session session) {
+ SessionProvider provider = sessions.remove(session);
+ if (provider != null) {
+ provider.releaseSession(session);
+ }
+ }
+
}
Modified: jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java?rev=1236837&r1=1236836&r2=1236837&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java Fri Jan 27 19:07:38 2012
@@ -17,7 +17,7 @@
package org.apache.jackrabbit.webdav.jcr.observation;
import org.apache.jackrabbit.commons.webdav.EventUtil;
-import org.apache.jackrabbit.server.SessionProviderImpl;
+import org.apache.jackrabbit.commons.webdav.JcrRemotingConstants;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.commons.AdditionalEventInfo;
import org.apache.jackrabbit.spi.commons.SessionExtensions;
@@ -462,17 +462,18 @@ public class SubscriptionImpl implements
if (!localFlagSet) {
// obtain remote session identifier
localFlagSet = true;
- String forSessionId = (String) session
- .getAttribute(SessionProviderImpl.ATTRIBUTE_SESSION_ID);
+ String name = JcrRemotingConstants.RELATION_REMOTE_SESSION_ID;
+ Object forSessionId = session.getAttribute(name);
// calculate "local" flags
if (forSessionId != null
&& event instanceof AdditionalEventInfo) {
+ AdditionalEventInfo aei = (AdditionalEventInfo) event;
try {
- String eventforSessionId = (String) ((AdditionalEventInfo) event)
- .getSessionAttribute(SessionProviderImpl.ATTRIBUTE_SESSION_ID);
- boolean isLocal = forSessionId
- .equals(eventforSessionId);
- DomUtil.setAttribute(bundle, XML_EVENT_LOCAL, null, Boolean.toString(isLocal));
+ boolean isLocal = forSessionId.equals(
+ aei.getSessionAttribute(name));
+ DomUtil.setAttribute(
+ bundle, XML_EVENT_LOCAL, null,
+ Boolean.toString(isLocal));
} catch (UnsupportedRepositoryOperationException ex) {
// optional feature
}