On 2/11/10 1:33 PM, Ian Boston wrote:
> 
> 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) ?
> 
Right. jcr.api now exports version 2.1.0 of org.apache.sling.jcr.api.
Changes to this module need not be rolled back because, with or without
the inclusion of NamespaceMapper in the API, the jcr.api bundle can't be
used without either a wrapped JCR 1 API bundle or the JCR 2 API bundle.

Justin

> 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