This, combined with the use of the JCR 2 bundle, is causing some test
failures. It seems to be because AccessControlUtil.getAccessManager()
attempts to call the getAccessManager() method specified by the
javax.jcr.Session interface which isn't implemented by SessionImpl.

Possible fixes are:
* Upgrade jackrabbit.server to JR 2.
* Remove NamespaceMapper modifications to jcr.base and roll back to old
jcr.api bundle in launchpad.

WDYT?

Justin


On 2/11/10 8:17 AM, [email protected] wrote:
> Author: cziegeler
> Date: Thu Feb 11 13:17:47 2010
> New Revision: 908956
> 
> URL: http://svn.apache.org/viewvc?rev=908956&view=rev
> Log:
> SLING-1366 : Use dynamic proxy to handle session#impersonate call.
> 
> Added:
>     
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
>    (with props)
> Modified:
>     
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
> 
> Modified: 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
> URL: 
> http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java?rev=908956&r1=908955&r2=908956&view=diff
> ==============================================================================
> --- 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
>  (original)
> +++ 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
>  Thu Feb 11 13:17:47 2010
> @@ -118,7 +118,11 @@
>  
>      private char[] adminPass;
>  
> -    private Loader loader;
> +    /** Namespace handler. */
> +    private Loader namespaceHandler;
> +
> +    /** Session proxy handler. */
> +    private SessionProxyHandler sessionProxyHandler;
>  
>      // the poll interval used while the repository is not active
>      private long pollTimeInActiveSeconds;
> @@ -231,6 +235,11 @@
>  
>              defineNamespacePrefixes(session);
>  
> +            // to support namespace prefixes if session.impersonate is called
> +            // we have to use a proxy
> +            if ( this.sessionProxyHandler != null ) {
> +                return this.sessionProxyHandler.createProxy(session);
> +            }
>              return session;
>  
>          } catch (NoSuchWorkspaceException nswe) {
> @@ -390,7 +399,8 @@
>       */
>      protected void setupRepository(Repository repository) {
>          BundleContext bundleContext = componentContext.getBundleContext();
> -        this.loader = new Loader(this, bundleContext.getBundles());
> +        this.namespaceHandler = new Loader(this, bundleContext.getBundles());
> +        this.sessionProxyHandler = new SessionProxyHandler(this);
>      }
>  
>      /**
> @@ -496,10 +506,11 @@
>       * @param repository
>       */
>      protected void tearDown(Repository repository) {
> -        if (this.loader != null) {
> -            this.loader.dispose();
> -            this.loader = null;
> +        if (this.namespaceHandler != null) {
> +            this.namespaceHandler.dispose();
> +            this.namespaceHandler = null;
>          }
> +        this.sessionProxyHandler = null;
>      }
>  
>      /**
> @@ -525,7 +536,7 @@
>       */
>      public void bundleChanged(BundleEvent event) {
>          // Take care: This is synchronous - take care to not block the 
> system !!
> -        Loader theLoader = this.loader;
> +        Loader theLoader = this.namespaceHandler;
>          if (theLoader != null) {
>              switch (event.getType()) {
>                  case BundleEvent.INSTALLED:
> @@ -693,10 +704,10 @@
>          return false;
>      }
>  
> -    private void defineNamespacePrefixes(final Session session) throws 
> RepositoryException {
> -        if (this.loader != null) {
> +    void defineNamespacePrefixes(final Session session) throws 
> RepositoryException {
> +        if (this.namespaceHandler != null) {
>              // apply namespace mapping
> -            this.loader.defineNamespacePrefixes(session);
> +            this.namespaceHandler.defineNamespacePrefixes(session);
>          }
>  
>          // call post processors
> 
> Added: 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
> URL: 
> http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java?rev=908956&view=auto
> ==============================================================================
> --- 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
>  (added)
> +++ 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
>  Thu Feb 11 13:17:47 2010
> @@ -0,0 +1,142 @@
> +/*
> + * 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.InvocationTargetException;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Proxy;
> +import java.util.HashSet;
> +import java.util.Set;
> +
> +import javax.jcr.Credentials;
> +import javax.jcr.Session;
> +
> +/**
> + * The session proxy handler creates session proxies to handle
> + * the namespace mapping support if impersonate is called on
> + * the session.
> + */
> +public class SessionProxyHandler  {
> +
> +    /** The array of proxied interfaces. */
> +    private Class<?>[] interfaces;
> +
> +    /** The repository */
> +    private final AbstractSlingRepository repository;
> +
> +    public SessionProxyHandler(final AbstractSlingRepository repo) {
> +        this.repository = repo;
> +    }
> +
> +    /** Calculate the interfaces.
> +     * This is done only once - we simply assume that the same repository is
> +     * emitting session from the same class.
> +     */
> +    private Class<?>[] getInterfaces(final Class<?> sessionClass) {
> +        if ( interfaces == null ) {
> +            synchronized ( SessionProxyHandler.class ) {
> +                if ( interfaces == null ) {
> +                    final HashSet<Class<?>> workInterfaces = new 
> HashSet<Class<?>>();
> +
> +                    // Get *all* interfaces
> +                    guessWorkInterfaces( sessionClass, workInterfaces );
> +
> +                    this.interfaces = workInterfaces.toArray( new 
> Class[workInterfaces.size()] );
> +
> +                }
> +            }
> +        }
> +        return interfaces;
> +    }
> +
> +    /**
> +     * Create a proxy for the session.
> +     */
> +    public Session createProxy(final Session session) {
> +        final Class<?> sessionClass = session.getClass();
> +        return (Session)Proxy.newProxyInstance(sessionClass.getClassLoader(),
> +                getInterfaces(sessionClass),
> +                new SessionProxy(session, this.repository));
> +
> +    }
> +
> +
> +    public static final class SessionProxy implements InvocationHandler {
> +        private final Session delegatee;
> +        private final AbstractSlingRepository repository;
> +
> +        public SessionProxy(final Session delegatee, final 
> AbstractSlingRepository repo) {
> +            this.delegatee = delegatee;
> +            this.repository = repo;
> +        }
> +
> +        /**
> +         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, 
> java.lang.reflect.Method, java.lang.Object[])
> +         */
> +        public Object invoke(Object proxy, Method method, Object[] args)
> +        throws Throwable {
> +            if ( method.getName().equals("impersonate") && args != null && 
> args.length == 1) {
> +                final Session session = 
> this.delegatee.impersonate((Credentials)args[0]);
> +                this.repository.defineNamespacePrefixes(session);
> +                return new SessionProxy(session, this.repository);
> +            }
> +            try {
> +                return method.invoke(this.delegatee, args);
> +            } catch (InvocationTargetException ite) {
> +                throw ite.getTargetException();
> +            }
> +        }
> +    }
> +
> +    /**
> +     * Get a list of interfaces to proxy by scanning through
> +     * all interfaces a class implements.
> +     *
> +     * @param clazz           the class
> +     * @param workInterfaces  the set of current work interfaces
> +     */
> +    private void guessWorkInterfaces( final Class<?> clazz,
> +                                      final Set<Class<?>> workInterfaces ) {
> +        if ( null != clazz ) {
> +            addInterfaces( clazz.getInterfaces(), workInterfaces );
> +
> +            guessWorkInterfaces( clazz.getSuperclass(), workInterfaces );
> +        }
> +    }
> +
> +    /**
> +     * Get a list of interfaces to proxy by scanning through
> +     * all interfaces a class implements.
> +     *
> +     * @param classInterfaces the array of interfaces
> +     * @param workInterfaces  the set of current work interfaces
> +     */
> +    private void addInterfaces( final Class<?>[] classInterfaces,
> +                                final Set<Class<?>> workInterfaces ) {
> +        for ( int i = 0; i < classInterfaces.length; i++ ) {
> +            // to avoid problems we simply ignore all pre jsr 283 interfaces 
> - once we
> +            // moved to jcr 2.0 completly we can remove this check
> +            if ( 
> !classInterfaces[i].getName().startsWith("org.apache.jackrabbit.api.jsr283")) 
> {
> +                workInterfaces.add( classInterfaces[i] );
> +            }
> +            addInterfaces(classInterfaces[i].getInterfaces(), 
> workInterfaces);
> +        }
> +    }
> +}
> 
> Propchange: 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
> ------------------------------------------------------------------------------
>     svn:keywords = author date id revision rev url
> 
> Propchange: 
> sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> 

Reply via email to