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}