On 11 Feb 2010, at 16:06, Justin Edelson wrote:

> 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?

IMHO remove NamespaceMapper, however I think I saw a commit from Carsten that 
added an NamespaceMapper class into one of the APIs (and versioned to 2.1.0) ?

Ian


> 
> 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