001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.config; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.core.api.config.ConfigurationException; 020import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; 021import org.kuali.rice.core.framework.util.ApplicationThreadLocal; 022import org.springframework.beans.factory.FactoryBean; 023import org.springframework.beans.factory.InitializingBean; 024 025import javax.xml.namespace.QName; 026 027/** 028 * Exports services in the {@link org.kuali.rice.core.api.resourceloader.GlobalResourceLoader} as beans available to Spring. 029 * 030 * @author Kuali Rice Team (rice.collab@kuali.org) 031 * 032 */ 033public class GlobalResourceLoaderServiceFactoryBean implements FactoryBean<Object>, InitializingBean { 034 035 private String serviceNamespace; 036 private String serviceName; 037 private boolean singleton; 038 private boolean mustExist; 039 040 // used to prevent a stack overflow when trying to get the service 041 private ThreadLocal<Boolean> isFetchingService = new ApplicationThreadLocal<Boolean>() { 042 @Override 043 protected Boolean initialValue() { 044 return false; 045 } 046 }; 047 048 public GlobalResourceLoaderServiceFactoryBean() { 049 this.mustExist = true; 050 } 051 052 public Object getObject() throws Exception { 053 if (isFetchingService.get()) return null; // we already have been invoked, don't recurse, just return null. 054 isFetchingService.set(true); 055 try { 056 Object service = null; 057 if (StringUtils.isBlank(getServiceNamespace())) { 058 service = GlobalResourceLoader.getService(this.getServiceName()); 059 } else { 060 service = GlobalResourceLoader.getService(new QName(getServiceNamespace(), getServiceName())); 061 } 062 if (mustExist && service == null) { 063 throw new IllegalStateException("Service must exist and no service could be located with serviceNamespace='" + getServiceNamespace() + "' and name='" + this.getServiceName() + "'"); 064 } 065 return service; 066 } finally { 067 isFetchingService.remove(); 068 } 069 } 070 071 public Class<?> getObjectType() { 072 return Object.class; 073 } 074 075 public boolean isSingleton() { 076 return singleton; 077 } 078 079 public String getServiceNamespace() { 080 return serviceNamespace; 081 } 082 083 public void setServiceNamespace(String serviceNamespace) { 084 this.serviceNamespace = serviceNamespace; 085 } 086 087 public String getServiceName() { 088 return serviceName; 089 } 090 091 public void setServiceName(String serviceName) { 092 this.serviceName = serviceName; 093 } 094 095 public void setSingleton(boolean singleton) { 096 this.singleton = singleton; 097 } 098 099 public boolean isMustExist() { 100 return mustExist; 101 } 102 103 public void setMustExist(boolean mustExist) { 104 this.mustExist = mustExist; 105 } 106 107 108 public void afterPropertiesSet() throws Exception { 109 if (StringUtils.isBlank(this.getServiceName())) { 110 throw new ConfigurationException("No serviceName given."); 111 } 112 } 113 114}