/** * Copyright 2008 biaoping.yin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.frameworkset.spi.remote.hession; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.servlet.ServletException; import org.apache.log4j.Logger; import org.frameworkset.spi.BaseApplicationContext; import org.frameworkset.spi.assemble.Pro; import com.caucho.hessian.io.SerializerFactory; import com.caucho.services.server.GenericService; /** * <p> HessianHanderContainer.java</p> * <p> Description: </p> * <p> bboss workgroup </p> * <p> Copyright (c) 2009 </p> * * @Date 2013-2-21 下午5:25:30 * @author biaoping.yin * @version 1.0 */ public class HessianHanderContainer { private Map<String,AbstractHessionHandler> hessionHandlers; private BaseApplicationContext context; private static final Logger log = Logger.getLogger(HessianHanderContainer.class); private Map<String,Pro> hessionPortServices = new HashMap<String,Pro>(); public HessianHanderContainer(BaseApplicationContext context) { hessionHandlers = new HashMap<String,AbstractHessionHandler>(); this.context = context; initHessionPortServices(); } public AbstractHessionHandler getHessionHandler(String service) throws Exception { AbstractHessionHandler handler = this.hessionHandlers.get(service); if(handler != null) return handler; synchronized(hessionHandlers) { handler = this.hessionHandlers.get(service); if(handler != null) return handler; handler = parserHessionHandler(service) ; this.hessionHandlers.put(service, handler); } if(handler == null) throw new java.lang.IllegalArgumentException("Service["+service+"] not found in "+this.context.getConfigfile()); return handler; } private void initHessionPortServices() { if(context != null) { Set<String> beanNames = context.getPropertyKeys(); if(beanNames == null || beanNames.size() == 0) return ; // Take any bean name that we can determine URLs for. Iterator<String> beanNamesItr = beanNames.iterator(); Pro pro = null; while(beanNamesItr.hasNext()) { String beanName = beanNamesItr.next(); try { pro = context.getProBean(beanName); if(pro == null) continue; String servicePort = pro.getStringExtendAttribute("hessian:servicePort"); if(servicePort != null) this.hessionPortServices.put(servicePort, pro); } catch(Exception e) { // if (logger.) { log.debug("Detect Hession servicePort Handler from '" + beanName + "' failed: " + e.getMessage(),e); } } } } } private Pro _searchWithHessionPort(String service) { // if(context != null) // { // // Set<String> beanNames = context.getPropertyKeys(); // if(beanNames == null || beanNames.size() == 0) // return null; // // Take any bean name that we can determine URLs for. // Iterator<String> beanNamesItr = beanNames.iterator(); // Pro pro = null; // while(beanNamesItr.hasNext()) { // String beanName = beanNamesItr.next(); // try // { // pro = context.getProBean(beanName); // if(pro == null) // continue; // String servicePort = pro.getStringExtendAttribute("hessian:servicePort"); // } // catch(Exception e) // { //// if (logger.) // { // logger.error("Detect Handler bean name '" + beanName + "' failed: " + e.getMessage(),e); // } // } // // } // } return hessionPortServices.get(service); } /** * hessian:api * hessian:serializable xml|bin * hessian:debug default false used by serializable="bin". * hessian:sendCollectionType used by serializable="bin". default true Set whether to send the Java collection type for each serialized collection. * hessian:serializerFactory used by serializable="bin".default com.caucho.hessian.io.SerializerFactory * hessian:servicePort 指定服务的唯一标识,一般无需指定hessian:servicePort属性,hessian服务的标识直接为组件的名称name或者id,但是如果在mvc控制器模式下的组件名称不是很友好可以 * 使用hessian:servicePort来指定一个简单的hessian服务名称 * @param service * @return * @throws Exception */ private AbstractHessionHandler parserHessionHandler(String service) throws Exception { Pro pro = this.context.getProBean(service); if(pro == null)//检索hessian:servicePort值为service的组件元数据 { pro = _searchWithHessionPort(service); if(pro == null) throw new Exception("Parser Hession Handler failed:hession service["+service+"] not found in hessian container[ "+context.getConfigfile()+"]"); service = pro.getName(); } String api = pro.getStringExtendAttribute("hessian:api"); String serialtype = pro.getStringExtendAttribute("hessian:serializable"); if(serialtype == null || "".equals(serialtype)) serialtype = "bin"; Object _service = context.getBeanObject(service); Class serviceapi = null; AbstractHessionHandler handler = null; if(api == null || "".equals(api)) { Class serviceClass = _service.getClass(); serviceapi = this.findRemoteAPI(serviceClass); } else { serviceapi = Class.forName(api); } if(serialtype.equals("bin")) { HessionHandler handler_ = new HessionHandler(); handler_.setService(_service); handler_.setServiceInterface(serviceapi); boolean debug = pro.getBooleanExtendAttribute("hessian:debug",false); handler_.setDebug(debug); boolean sendCollectionType = pro.getBooleanExtendAttribute("hessian:sendCollectionType",true); handler_.setSendCollectionType(sendCollectionType); String serializerFactory = pro.getStringExtendAttribute("hessian:serializerFactory"); if(serializerFactory == null || "".equals(serializerFactory)) { } else { SerializerFactory _serializerFactory = (SerializerFactory)Class.forName(serializerFactory).newInstance(); handler_.setSerializerFactory(_serializerFactory); } handler = handler_; } else if(serialtype.equals("xml")) { handler = new BurlapHandler(); handler.setService(_service); handler.setServiceInterface(serviceapi); } handler.afterPropertiesSet(); return handler; } private Class findRemoteAPI(Class implClass) { if (implClass == null || implClass.equals(GenericService.class)) return null; Class []interfaces = implClass.getInterfaces(); if (interfaces.length == 1) return interfaces[0]; return findRemoteAPI(implClass.getSuperclass()); } }