Spring extension

1 message Options
Embed this post
Permalink
Rémi Dewitte-2

Spring extension

Reply Threaded More More options
Print post
Permalink
Hello Rhett et al.,

I have started using Spring with Rest and I have found that SpringBean(Router|Finder) nearly matched my needs. I still wanted to use the type-safe Router#attach(String, Class) method.

Here the two classes I have written, if you think it is useful...

Cheers,
Rémi

[SpringBeanTypeFinder.java]

package net.gide.spring;

import java.util.logging.Level;

import org.restlet.Context;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.Finder;
import org.restlet.resource.ServerResource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;

/**
 * It is very closed to the original Restlet's Finder except that is search for
 * the bean by type inside the BeanFactory.
 *
 * It is type-safe. The bean factory must include only one definition for that
 * bean and have the prototype scope.
 *
 * Very easy to use with annotation auto-discovery on resources classes :
 * <code>@Component @Scope("prototype")</code>
 *
 * @see BeanFactoryUtils#beanNamesForType(ListableBeanFactory, Class)
 * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory,
 *      Class)
 */
public class SpringBeanTypeFinder extends Finder {

        /** The parent bean factory. */
        private volatile ListableBeanFactory beanFactory;

        /**
         * Look for the bean type in beanFactory's ancestors ?
         *
         * @see BeanFactoryUtils#beanNamesForType(ListableBeanFactory, Class)
         * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory,
         *      Class)
         */
        private volatile boolean includeAncestors = false;

        /**
         * Constructor.
         *
         * @param context
         *            The Restlet context
         * @param beanFactory
         *            The Spring bean factory.
         * @param targetClass
         *            The bean type.
         */
        public SpringBeanTypeFinder(Context context,
                        ListableBeanFactory beanFactory, Class<?> targetClass) {
                super(context, targetClass);
                setBeanFactory(beanFactory);
        }

        /**
         * Constructor.
         *
         * @param beanFactory
         *            The Spring bean factory.
         * @param targetClass
         *            The bean type.
         */
        public SpringBeanTypeFinder(ListableBeanFactory beanFactory,
                        Class<?> targetClass) {
                this(null, beanFactory, targetClass);
        }

        /**
         * Search for a bean of type in the beanFactory.
         *
         * @see BeanFactoryUtils#beanNamesForType(ListableBeanFactory, Class)
         * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory,
         *      Class)
         */
        @Override
        public ServerResource create(Class<? extends ServerResource> targetClass,
                        Request request, Response response) {
                Object result = null;
                try {
                        if (includeAncestors) {
                                result = BeanFactoryUtils.beanOfTypeIncludingAncestors(
                                                beanFactory, targetClass);
                        } else {
                                result = BeanFactoryUtils.beanOfType(beanFactory, targetClass);
                        }
                } catch (BeansException e) {
                        getLogger().log(Level.WARNING,
                                        e.getLocalizedMessage() + ". Using default constructor.");
                        result = super.create(targetClass, request, response);
                }
                return (ServerResource) result;
        }

        public ListableBeanFactory getBeanFactory() {
                return this.beanFactory;
        }

        public void setBeanFactory(ListableBeanFactory beanFactory)
                        throws BeansException {
                this.beanFactory = beanFactory;
        }

        public boolean isIncludeAncestors() {
                return includeAncestors;
        }

        public void setIncludeAncestors(boolean includeAncestors) {
                this.includeAncestors = includeAncestors;
        }

}


[SpringBeanTypeRouter.java]

package net.gide.spring;

import org.restlet.Context;
import org.restlet.resource.Finder;
import org.restlet.routing.Router;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;

/**
 * It is very closed to the original Restlet's Router except that
 * {@link SpringBeanTypeFinder} are created.
 */
public class SpringBeanTypeRouter extends Router {

        /**
         * The bean factory that will be used
         */
        private volatile ListableBeanFactory beanFactory;
       
        /**
         * Look for the bean type in beanFactory's ancestors ?
         *
         * @see BeanFactoryUtils#beanNamesForType(ListableBeanFactory, Class)
         * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory,
         *      Class)
         */
        private volatile boolean includeAncestors = false;

        public SpringBeanTypeRouter(ListableBeanFactory beanFactory) {
                super(null);
                this.beanFactory = beanFactory;
        }

        public SpringBeanTypeRouter(Context context, ListableBeanFactory beanFactory) {
                super(context);
                this.beanFactory = beanFactory;
        }

        @Override
        public Finder createFinder(Class<?> targetClass) {
                SpringBeanTypeFinder result = new SpringBeanTypeFinder(getContext(), beanFactory, targetClass);
                result.setIncludeAncestors(includeAncestors);
                return result;
        }

        public ListableBeanFactory getBeanFactory() {
                return beanFactory;
        }

        public void setBeanFactory(ListableBeanFactory beanFactory) {
                this.beanFactory = beanFactory;
        }

        public boolean isIncludeAncestors() {
                return includeAncestors;
        }

        public void setIncludeAncestors(boolean includeAncestors) {
                this.includeAncestors = includeAncestors;
        }

}