package org.cagrid.mms.service.impl.cadsr; import gov.nih.nci.system.applicationservice.ApplicationException; import gov.nih.nci.system.applicationservice.ApplicationService; import gov.nih.nci.system.client.proxy.ApplicationServiceProxy; import java.io.ByteArrayInputStream; import java.util.Map; import org.acegisecurity.AcegiSecurityException; import org.acegisecurity.Authentication; import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.rcp.RemoteAuthenticationException; import org.aopalliance.aop.Advice; import org.springframework.aop.Advisor; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.InputStreamResource; public class ApplicationServiceProvider { private static String DEFAULT_SERVICE = "ServiceInfo"; public static ApplicationService getApplicationService(ApplicationContext ctx) throws Exception { return getApplicationService(ctx,DEFAULT_SERVICE,null,null,null); } public static ApplicationService getApplicationService(ApplicationContext ctx,String username, String password) throws Exception { if(username == null || password == null || username.trim().length() == 0 || password.trim().length() == 0) throw new Exception("Cannot authenticate user"); return getApplicationService(ctx,DEFAULT_SERVICE,null,username,password); } public static ApplicationService getApplicationService(ApplicationContext ctx,String service) throws Exception { return getApplicationService(ctx,service, null,null,null); } public static ApplicationService getApplicationService(ApplicationContext ctx,String service, String username, String password) throws Exception { if(username == null || password == null || username.trim().length() == 0 || password.trim().length() == 0) throw new Exception("Cannot authenticate user"); return getApplicationService(ctx,service,null,username,password); } public static ApplicationService getApplicationServiceFromUrl(ApplicationContext ctx,String url) throws Exception { return getApplicationService(ctx,DEFAULT_SERVICE,url,null,null); } public static ApplicationService getApplicationServiceFromUrl(ApplicationContext ctx,String url,String username, String password) throws Exception { if(username == null || password == null || username.trim().length() == 0 || password.trim().length() == 0) throw new Exception("Cannot authenticate user"); return getApplicationService(ctx,DEFAULT_SERVICE,url,username,password); } public static ApplicationService getApplicationServiceFromUrl(ApplicationContext ctx,String url, String service) throws Exception { return getApplicationService(ctx,service, url,null,null); } public static ApplicationService getApplicationServiceFromUrl(ApplicationContext ctx,String url, String service, String username, String password) throws Exception { if(username == null || password == null || username.trim().length() == 0 || password.trim().length() == 0) throw new Exception("Cannot authenticate user"); return getApplicationService(ctx,service,url,username,password); } @SuppressWarnings("unchecked") public static ApplicationService getApplicationService(ApplicationContext ctx, String service, String url, String username, String password) throws Exception { Boolean secured = username!=null && password!=null; ApplicationContext context = getApplicationContext(ctx, service, url,secured); ApplicationService as = null; AuthenticationProvider ap = null; Map<String,Object> serviceInfoMap = (Map<String, Object>) ctx.getBean(service); if(serviceInfoMap == null) { as = (ApplicationService) context.getBean("applicationService"); ap = (AuthenticationProvider)context.getBean("authenticationProvider"); } else { if(url == null) url =""; String serviceName = (String)serviceInfoMap.get("APPLICATION_SERVICE_BEAN"); as = (ApplicationService) context.getBean(serviceName); ap = (AuthenticationProvider)serviceInfoMap.get("AUTHENTICATION_SERVICE_BEAN"); } if(secured) { Authentication auth = new UsernamePasswordAuthenticationToken(username,password); try { auth = ap.authenticate(auth); setApplicationService(as, auth); } catch(Exception e) { String message=""; if(e instanceof RemoteAuthenticationException || e instanceof AcegiSecurityException) message = "Error authenticating user:"; else message = "Unknown error in authenticating user:"; throw new ApplicationException(message,e); } } else { setApplicationService(as, null); } return as; } private static void setApplicationService(ApplicationService as, Authentication auth) { if(as instanceof org.springframework.aop.framework.Advised) { org.springframework.aop.framework.Advised proxy = (org.springframework.aop.framework.Advised)as; for(Advisor advisor: proxy.getAdvisors()) { Advice advice = advisor.getAdvice(); if(advice instanceof ApplicationServiceProxy) { ApplicationServiceProxy asp = (ApplicationServiceProxy)advice; asp.setApplicationService(as); asp.setAuthentication(auth); } } } } @SuppressWarnings("unchecked") private static ApplicationContext getApplicationContext(ApplicationContext ctx, String service, String url, Boolean secured) throws Exception { if(service == null || service.trim().length() == 0) throw new Exception("Name of the service can not be empty"); Map<String,Object> serviceInfoMap = (Map<String, Object>) ctx.getBean(service); if(serviceInfoMap == null) throw new Exception("Change the configuration file!!!"); //Initialized instances found in the configuration String asName = (String)serviceInfoMap.get("APPLICATION_SERVICE_BEAN"); ApplicationService as = (ApplicationService)ctx.getBean(asName); AuthenticationProvider ap = (AuthenticationProvider)serviceInfoMap.get("AUTHENTICATION_SERVICE_BEAN"); //Returning initialized instance if((!secured && as!=null && url == null)||(secured && as!=null && ap!=null && url == null)) //Empty URL, return the service. This helps in improving performance return ctx; String serviceInfo = (String)serviceInfoMap.get("APPLICATION_SERVICE_CONFIG");; if(url == null) url = (String)serviceInfoMap.get("APPLICATION_SERVICE_URL"); //URL_KEY must be present if the user is trying to use the url to reach the service if(serviceInfo==null ||(url == null && serviceInfo.indexOf("URL_KEY")>0) || (url!=null && serviceInfo.indexOf("URL_KEY")<0)) throw new Exception("Change the configuration file!!!"); //Resetting the URL as URL_KEY is absent in the configuration if(serviceInfo.indexOf("URL_KEY") <0 || url == null) url=""; serviceInfo = serviceInfo.replace("URL_KEY", url); //Prepare in memory configuration from the information retrieved of the configuration file String xmlFileString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\" \"http://www.springframework.org/dtd/spring-beans.dtd\"><beans>"+serviceInfo+"</beans>"; GenericApplicationContext context = new GenericApplicationContext(); context.setClassLoader(ApplicationServiceProvider.class.getClassLoader()); XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context); xmlReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE); InputStreamResource inputStreamResource = new InputStreamResource(new ByteArrayInputStream(xmlFileString.getBytes())); xmlReader.loadBeanDefinitions(inputStreamResource); context.refresh(); as = (ApplicationService) context.getBean("applicationService"); ap = (AuthenticationProvider)context.getBean("authenticationProvider"); //Make sure the configuration has the required objects present if(as==null || (secured && ap==null)) throw new Exception("Change the configuration file!!!"); return context; } }