001/*
002  GRANITE DATA SERVICES
003  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005  This file is part of Granite Data Services.
006
007  Granite Data Services is free software; you can redistribute it and/or modify
008  it under the terms of the GNU Library General Public License as published by
009  the Free Software Foundation; either version 2 of the License, or (at your
010  option) any later version.
011
012  Granite Data Services is distributed in the hope that it will be useful, but
013  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015  for more details.
016
017  You should have received a copy of the GNU Library General Public License
018  along with this library; if not, see <http://www.gnu.org/licenses/>.
019*/
020
021package org.granite.spring;
022
023import java.io.IOException;
024import java.util.Map;
025import java.util.Map.Entry;
026
027import javax.servlet.ServletContext;
028
029import org.granite.config.AbstractFrameworkGraniteConfig;
030import org.granite.logging.Logger;
031import org.granite.messaging.service.ExceptionConverter;
032import org.granite.messaging.service.security.SecurityService;
033import org.granite.util.TypeUtil;
034import org.springframework.beans.factory.InitializingBean;
035import org.springframework.beans.factory.annotation.Autowired;
036import org.springframework.context.ApplicationContext;
037import org.springframework.context.ApplicationContextAware;
038import org.springframework.web.context.ServletContextAware;
039import org.xml.sax.SAXException;
040
041
042public class SpringGraniteConfig extends AbstractFrameworkGraniteConfig implements InitializingBean, ServletContextAware, ApplicationContextAware {
043        
044        private static final Logger log = Logger.getLogger(SpringGraniteConfig.class);
045
046        @Autowired(required=false)
047    private ServletContext servletContext = null;
048    private ApplicationContext applicationContext = null;
049
050    
051        // Determine Spring Security version
052    public static boolean isSpringSecurity3Present() {
053        try {
054                SpringGraniteConfig.class.getClassLoader().loadClass("org.springframework.security.access.AccessDeniedException");
055                return true;
056        }
057        catch (ClassNotFoundException e) {
058        }
059        return false;
060    }
061    public static boolean isSpringSecurity2Present() {
062        try {
063                SpringGraniteConfig.class.getClassLoader().loadClass("org.springframework.security.context.SecurityContext");
064                return true;
065        }
066        catch (ClassNotFoundException e) {
067        }
068        return false;
069    }
070    
071    public void afterPropertiesSet() throws IOException, SAXException {
072        init(servletContext, "org/granite/spring/granite-config-spring.xml");
073        
074        Map<String, ExceptionConverter> exceptionConvertersMap = applicationContext.getBeansOfType(ExceptionConverter.class);
075        for (ExceptionConverter exceptionConverter : exceptionConvertersMap.values())
076            getGraniteConfig().registerExceptionConverter(exceptionConverter, true);
077        
078        if (getGraniteConfig().getSecurityService() == null) {
079                Map<String, ?> servicesMap = applicationContext.getBeansOfType(SecurityService.class);
080                if (servicesMap.size() == 1) {
081                        Entry<String, ?> se = servicesMap.entrySet().iterator().next();
082                        log.info("Found security service %s in Spring context", se.getKey());
083                        getGraniteConfig().setSecurityService((SecurityService)se.getValue());
084                }
085                else {
086                        if (servicesMap.size() > 1)
087                                log.warn("Multiple security services found in Spring context, will use default config");
088                        
089                        // Autodetect and configure Spring Security service
090                        // Load dynamically to avoid runtime dependency on SS
091                        try {
092                                if (isSpringSecurity3Present())
093                                        getGraniteConfig().setSecurityService(TypeUtil.newInstance("org.granite.spring.security.SpringSecurity3Service", SecurityService.class));
094                                else if (isSpringSecurity2Present())
095                                        getGraniteConfig().setSecurityService(TypeUtil.newInstance("org.granite.messaging.service.security.SpringSecurityService", SecurityService.class));
096                        }
097                        catch (Exception e) {
098                                throw new IOException("Could not configure Spring Security service");
099                        }
100                }
101        }
102    }
103    
104    public void setServletContext(ServletContext servletContext) {
105        this.servletContext = servletContext;
106    }
107    
108    public void setApplicationContext(ApplicationContext applicationContext) {
109        this.applicationContext = applicationContext;
110    }
111}