001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.q2.qbean; 020 021import org.jdom2.Element; 022import org.jpos.core.ConfigurationException; 023import org.jpos.q2.QBeanSupport; 024import org.jpos.q2.QFactory; 025import org.jpos.util.NameRegistrar; 026 027import java.util.*; 028 029/** 030 * QBean that instantiates and registers arbitrary beans declared in its 031 * persist element, exposing them through {@link #getBean(String)} and the 032 * JMX {@link QBeanFactoryMBean} interface. 033 */ 034@SuppressWarnings("unchecked") 035public class QBeanFactory extends QBeanSupport implements QBeanFactoryMBean { 036 /** Default constructor; no instance state to initialise. */ 037 public QBeanFactory() {} 038 039 private static Map beanMap = new WeakHashMap(); 040 private Map privateList; // list of beans in the config file 041 042 public void initService() throws Exception { 043 Element e = getPersist(); 044 privateList = new HashMap(); 045 List beans = e.getChildren("bean"); 046 for (Object bean1 : beans) { 047 Element bean = (Element) bean1; 048 String id = bean.getAttributeValue("id"); 049 privateList.put(id, bean); 050 } 051 052 } 053 054 public void start() { 055 super.start(); 056 NameRegistrar.register("QBeanFactory." + getName(), this); 057 } 058 059 public void stop() { 060 super.stop(); 061 NameRegistrar.unregister("QBeanFactory." + getName()); 062 } 063 // Support methods for bean life cycle 064 public void startService() { 065 Iterator keys = privateList.keySet().iterator(); 066 while (keys.hasNext()) { 067 Element bean = (Element) privateList.get(keys.next()); 068 String id = bean.getAttributeValue("id"); 069 String lazy = bean.getAttributeValue("lazy"); 070 // Load the bean only when lazy="false". default value true 071 if (lazy != null && lazy.equalsIgnoreCase("false")) { 072 getBean(id); 073 } 074 } 075 } 076 077 public void stopService() { 078 Iterator keys = privateList.keySet().iterator(); 079 while (keys.hasNext()) { 080 Element bean = (Element) privateList.get(keys.next()); 081 String id = bean.getAttributeValue("id");// id and key are same 082 Object beanInstance=beanMap.remove(id); 083 String stopMethod = bean.getAttributeValue("stop-method"); 084 if(beanInstance!=null && stopMethod!=null){ 085 try{ 086 QFactory.invoke(beanInstance, stopMethod, null); 087 }catch(Exception e){ 088 log.warn(e); 089 } 090 } 091 } 092 } 093 094 public Object getBean(String id) { 095 096 // Hack to support a global ref bean across multiple 097 // deployment files. We may need to support lazy loading here but now 098 // not supported 099 Element bean = (Element) privateList.get(id); 100 if (bean == null) { 101 return beanMap.get(id); 102 } 103 // Need to create a new instance when singleton="false" 104 // It is true by default 105 String singleton = bean.getAttributeValue("singleton"); 106 try{ 107 if(singleton != null && singleton.equals("false")){// create new instance every time 108 return newBean(bean,false); 109 }else{ 110 return newBean(bean,true); 111 } 112 }catch(Exception e){ 113 log.fatal(e); 114 return null; 115 } 116 117 } 118 private Object newBean(Element bean,boolean useCache) throws ConfigurationException{ 119 String id = bean.getAttributeValue("id"); 120 121 if(useCache && beanMap.containsKey(id)){ 122 return beanMap.get(id); 123 } 124 125 String className = bean.getAttributeValue("class"); 126 Object beanInstance = getFactory().newInstance(className); 127 List propertyList = bean.getChildren("property"); 128 for (Object aPropertyList : propertyList) { 129 Element propertyElement = (Element) aPropertyList; 130 String pName = propertyElement.getAttributeValue("name"); 131 String pValue = propertyElement.getAttributeValue("value"); 132 String pRef = propertyElement.getAttributeValue("ref"); 133 String methodName = "set" 134 + Character.toUpperCase(pName.charAt(0)) 135 + pName.substring(1); 136 if (pValue == null) { 137 QFactory.invoke(beanInstance, methodName, getBean(pRef)); 138 } else { 139 QFactory.invoke(beanInstance, methodName, pValue); 140 } 141 } 142 String startMethod = bean.getAttributeValue("start-method"); 143 if(startMethod!=null){ 144 QFactory.invoke(beanInstance, startMethod, null); 145 } 146 if(useCache)//indication for a singleton 147 beanMap.put(id, beanInstance); 148 // Return the bean instance 149 return beanInstance; 150 } 151 152}