/*
  GRANITE DATA SERVICES
  Copyright (C) 2007-2008 ADEQUATE SYSTEMS SARL

  This file is part of Granite Data Services.

  Granite Data Services is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 3 of the License, or (at your
  option) any later version.

  Granite Data Services is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

package org.granite.grails.integration;

import java.util.Map;

import javax.servlet.ServletContext;

import org.codehaus.groovy.grails.plugins.GrailsPluginManager;
import org.granite.context.GraniteContext;
import org.granite.logging.Logger;
import org.granite.messaging.service.security.AbstractSecurityContext;
import org.granite.messaging.service.security.AbstractSecurityService;
import org.granite.messaging.service.security.SecurityServiceException;
import org.granite.messaging.webapp.HttpGraniteContext;
import org.granite.util.ClassUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * @author William Draï
 */
public class GrailsSecurityService extends AbstractSecurityService {
    
	private static final Logger log = Logger.getLogger(GrailsSecurityService.class);
	
	private Map<String, String> conf;
	private AbstractSecurityService delegate;
	
	public GrailsSecurityService() {
	}

	public void configure(Map<String, String> params) {
		this.conf = params;
	}
	
    private AbstractSecurityService getDelegate() {
        GraniteContext context = GraniteContext.getCurrentInstance();
        ServletContext sc = ((HttpGraniteContext)context).getServletContext();
        ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
        
        GrailsPluginManager manager = (GrailsPluginManager)springContext.getBean("pluginManager");
        if (manager.hasGrailsPlugin("acegi")) {
        	// Determine Spring Security version
        	boolean spring3 = false;
        	try {
        		getClass().getClassLoader().loadClass("org.springframework.security.access.AccessDeniedException");
        		spring3 = true;
        	}
        	catch (ClassNotFoundException e) {
        		// Assume Spring 2
        	}
        	
        	try {
        		delegate = (AbstractSecurityService)ClassUtil.newInstance(spring3
        				? "org.granite.spring.security.SpringSecurity3Service"
        				: "org.granite.messaging.service.security.SpringSecurityService"
        		);
        		delegate.configure(conf);
        	}
        	catch (Exception e) {
        		log.error("Could not instantiate Spring Security service", e);
        	}
        }
        else
        	delegate = null;
        
        return delegate;
    }
    
	public Object authorize(AbstractSecurityContext context) throws Exception {
		AbstractSecurityService delegate = getDelegate();
		if (delegate != null)
			return delegate.authorize(context);
		
		return context.invoke();
	}

	public void login(Object credentials) throws SecurityServiceException {
		AbstractSecurityService delegate = getDelegate();
		if (delegate != null)
			delegate.login(credentials);
	}

	public void logout() throws SecurityServiceException {
		AbstractSecurityService delegate = getDelegate();
		if (delegate != null)
			delegate.logout();
	}
}

@@ -2381,301 +2381,59 @@
 gi%22)
-) %7B%0D%0A        %09// Determine Spring Security version%0D%0A        %09boolean spring3 = false;%0D%0A        %09try %7B%0D%0A        %09%09getClass().getClassLoader().loadClass(%22org.springframework.security.access.AccessDeniedException%22);%0D%0A        %09%09spring3 = true;%0D%0A        %09%7D%0D%0A        %09catch (ClassNotFoundException e
+ %7C%7C manager.hasGrailsPlugin(%22spring-security-core%22)
 ) %7B%0D
@@ -2446,17 +2446,19 @@
    %09
-%09
 // 
-Assum
+Determin
 e Sp
@@ -2466,32 +2466,24 @@
 ing 
-2%0D%0A        %09%7D%0D%0A        %09
+Security version
 %0D%0A  
@@ -2568,15 +2568,55 @@
 nce(
-spring3
+manager.hasGrailsPlugin(%22spring-security-core%22)
 %0D%0A  

Support for spring-security-core plugin