incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmesc...@apache.org
Subject svn commit: r1499293 - in /sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base: ./ src/main/java/org/apache/sling/jcr/base/
Date Wed, 03 Jul 2013 09:36:43 GMT
Author: fmeschbe
Date: Wed Jul  3 09:36:42 2013
New Revision: 1499293

URL: http://svn.apache.org/r1499293
Log:
Implement support for service based ResourceResolver and Session access

- Use a proxy handler instead of a proxy to be able to implement
  all interfaces exposed by the Repository service.
- Expose the jcr.base API at a version which matches the current
  value.
- Implement the loginService method
- Register the service as a service factory to make sure each
  bundle gets its own instance to be able to know the calling
  bundle. This requires to make the registerService method final
  and provide a new method to provide the actual service
  registration interfaces. Extensions of the AbstractSlingRepository
  base class may need to be fixed.

Added:
    sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxyHandler.java
Removed:
    sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxy.java
Modified:
    sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/pom.xml
    sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/pom.xml?rev=1499293&r1=1499292&r2=1499293&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/pom.xml (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/pom.xml Wed Jul  3 09:36:42
2013
@@ -58,7 +58,7 @@
                             sling,jcr,jackrabbit
                         </Bundle-Category>
                         <Export-Package>
-                            org.apache.sling.jcr.base;version=1.0,
+                            org.apache.sling.jcr.base;version=2.2,
                             org.apache.sling.jcr.base.util;version=2.1.0
                         </Export-Package>
                         <Private-Package>

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java?rev=1499293&r1=1499292&r2=1499293&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
(original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
Wed Jul  3 09:36:42 2013
@@ -38,7 +38,6 @@ import org.apache.sling.jcr.base.util.Re
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.log.LogService;
@@ -249,6 +248,33 @@ public abstract class AbstractSlingRepos
     }
 
     /**
+     * Actual implementation of the {@link #loginService(String, String)}
+     * method taking into account the bundle calling this method.
+     *
+     * @param usingBundle
+     * @param serviceInfo
+     * @param workspace
+     * @return
+     * @throws LoginException
+     * @throws RepositoryException
+     */
+    final Session loginService(final Bundle usingBundle, final String serviceInfo, final
String workspace)
+            throws LoginException, RepositoryException {
+        final String userName = this.serviceUserMapper.getUserForService(usingBundle, serviceInfo);
+        final SimpleCredentials creds = new SimpleCredentials(userName, new char[0]);
+
+        Session admin = null;
+        try {
+            admin = this.loginAdministrative(workspace);
+            return admin.impersonate(creds);
+        } finally {
+            if (admin != null) {
+                admin.logout();
+            }
+        }
+    }
+
+    /**
      * @param anonUser the user name of the anon user.
      * @return a Credentials implementation that represents the anon user.
      */
@@ -440,38 +466,59 @@ public abstract class AbstractSlingRepos
     }
 
     /**
-     * Registers this component as an OSGi service with type
-     * <code>javax.jcr.Repository</code> and
-     * <code>org.apache.sling.jcr.api.SlingRepository</code> using the
-     * component properties as service registration properties.
+     * Registers this component as an OSGi service with the types provided by
+     * the {@link #getServiceRegistrationInterfaces()} method and properties
+     * provided by the {@link #getServiceRegistrationProperties()} method.
      * <p>
-     * This method may be overwritten to register the component with different
-     * types.
+     * This method is final and cannot be overwritten because the mechanism of
+     * service registration using a service factory is required to fully
+     * implement the {@link #loginService(String, String)} method.
      *
-     * @return The OSGi <code>ServiceRegistration</code> object representing
-     *         the registered service.
+     * @return The OSGi <code>ServiceRegistration</code> object representing
the
+     *         registered service.
      */
     protected final ServiceRegistration registerService() {
-        Dictionary<String, Object> props = getServiceRegistrationProperties();
-        String[] interfaces = getServiceRegistrationInterfaces();
+        final Dictionary<String, Object> props = getServiceRegistrationProperties();
+        final String[] interfaces = getServiceRegistrationInterfaces();
 
         return componentContext.getBundleContext().registerService(interfaces, new ServiceFactory()
{
             public Object getService(Bundle bundle, ServiceRegistration registration) {
-                return new SlingRepositoryProxy(AbstractSlingRepository.this, bundle, AbstractSlingRepository.this.serviceUserMapper);
+                return SlingRepositoryProxyHandler.createProxy(interfaces, AbstractSlingRepository.this,
bundle);
             }
 
             public void ungetService(Bundle bundle, ServiceRegistration registration, Object
service) {
                 // nothing to do (GC does the work for us)
             }
-        }, // was: this
-        props);
+        }, props);
     }
 
+    /**
+     * Return the service registration properties to be used to register the
+     * repository service in {@link #registerService()}.
+     * <p>
+     * This method may be overwritten to return additional service registration
+     * properties. But it is strongly recommended to always include the
+     * properties returned from this method.
+     *
+     * @return The service registration properties to be used to register the
+     *         repository service in {@link #registerService()}
+     */
     @SuppressWarnings("unchecked")
     protected Dictionary<String, Object> getServiceRegistrationProperties() {
         return componentContext.getProperties();
     }
 
+    /**
+     * Returns the service types to be used to register the repository service
+     * in {@link #registerService()}. All interfaces returned must be accessible
+     * to the class loader of the class of this instance.
+     * <p>
+     * This method may be overwritten to return additional types but the types
+     * returned from this base implementation must always be included.
+     *
+     * @return The service types to be used to register the repository service
+     *         in {@link #registerService()}
+     */
     protected String[] getServiceRegistrationInterfaces() {
         return new String[] {
             SlingRepository.class.getName(), Repository.class.getName()

Added: sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxyHandler.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxyHandler.java?rev=1499293&view=auto
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxyHandler.java
(added)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxyHandler.java
Wed Jul  3 09:36:42 2013
@@ -0,0 +1,116 @@
+/*
+ * 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.base;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.framework.Bundle;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>SlingRepositoryProxyHandler</code> class implements a proxy for
all
+ * service interfaces under which the {@link AbstractSlingRepository}
+ * implementation is registered.
+ * <p>
+ * All calls a directly handed through to the object except for the
+ * {@code loginService} call which is routed through
+ * {@code AbstractSlingRepository.loginService(Bundle, String, String)} method
+ * to influence logging in by the calling bundle.
+ */
+class SlingRepositoryProxyHandler implements InvocationHandler {
+
+    // The name of the method to re-route
+    private static final String LOGIN_SERVICE_NAME = "loginService";
+
+    // The signature of the loginService method to re-route
+    private static final Class<?>[] LOGIN_SERVICE_SIG = {
+        String.class, String.class
+    };
+
+    // The actual longService method object used for re-routing
+    private static final Method LOGIN_SERVICE;
+
+    // The delegatee object to which all calls are routed
+    private final AbstractSlingRepository delegatee;
+
+    // The bundle using this proxy service instance
+    private final Bundle usingBundle;
+
+    static {
+        Method tmplsm = null;
+        try {
+            tmplsm = SlingRepository.class.getMethod(LOGIN_SERVICE_NAME, LOGIN_SERVICE_SIG);
+        } catch (Exception e) { // SecurityException e, NoSuchMethodException
+            LoggerFactory.getLogger(SlingRepositoryProxyHandler.class).error(
+                "[init]: Cannot get " + LOGIN_SERVICE_NAME + " method from SlingRepository
interface", e);
+        }
+        LOGIN_SERVICE = tmplsm;
+    }
+
+    /**
+     * Creates a new proxy instance for the given {@code delegatee} object. The
+     * proxy is handled by a new instance of this
+     * {@code SlingRepositoryProxyHandler} handler.
+     *
+     * @param interfaceNames The list of interfaces to implement and expose in
+     *            the proxy
+     * @param delegatee The object to which to route all method calls
+     * @param usingBundle The bundle making use of the proxy
+     * @return The proxy to be used by client code or {@code null} if not all
+     *         service interfaces can be loaded by the class loader of the
+     *         {@code delegatee} object.
+     */
+    static Object createProxy(final String[] interfaceNames, final AbstractSlingRepository
delegatee,
+            final Bundle usingBundle) {
+
+        // get the interface classes to create the proxy
+        final ClassLoader cl = delegatee.getClass().getClassLoader();
+        final Class<?>[] interfaces = new Class<?>[interfaceNames.length];
+        for (int i = 0; i < interfaces.length; i++) {
+            try {
+                interfaces[i] = cl.loadClass(interfaceNames[i]);
+            } catch (ClassNotFoundException e) {
+                LoggerFactory.getLogger(SlingRepositoryProxyHandler.class).error(
+                    "createProxy: Cannot load interface class " + interfaceNames[i], e);
+                return null;
+            }
+        }
+
+        // create the proxy
+        final InvocationHandler handler = new SlingRepositoryProxyHandler(delegatee, usingBundle);
+        return Proxy.newProxyInstance(cl, interfaces, handler);
+    }
+
+    private SlingRepositoryProxyHandler(final AbstractSlingRepository delegatee, final Bundle
usingBundle) {
+        this.delegatee = delegatee;
+        this.usingBundle = usingBundle;
+    }
+
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (method == SlingRepositoryProxyHandler.LOGIN_SERVICE) {
+            return this.delegatee.loginService(this.usingBundle, (String) args[0], (String)
args[1]);
+        }
+
+        // otherwise forward to the AbstractSlingRepository implementation
+        return method.invoke(this.delegatee, args);
+    }
+}



Mime
View raw message