/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.fmk.call; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import org.apache.commons.jxpath.JXPathContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.exception.SlxException; import org.solmix.api.jaxb.EserviceStyle; import org.solmix.api.jaxb.Tservice; import org.solmix.api.types.Texception; import org.solmix.api.types.Tmodule; import org.solmix.commons.util.DataUtils; import org.solmix.ds.context.Context; import org.solmix.fmk.base.Reflection; import org.solmix.fmk.base.ReflectionArgument; import org.solmix.fmk.util.ServiceUtil; /** * * @author Administrator * @version 110035 2011-4-8 */ public class ServiceObject { private static Logger log = LoggerFactory.getLogger(ServiceObject.class.getName()); Tservice serverObjectConfig; Context context; String contextString; ReflectionArgument factoryOptionalArgs[]; EserviceStyle lookupStyle; Class<?> serverObjectClass; String serverObjectClassName; String serverObjectInterface; String serverObjectFilter; Object serverObjectInstance; Method method; public ServiceObject(Tservice serverObjectConfig, Context context, String contextString) throws SlxException { this(serverObjectConfig, context, null, contextString); } public ServiceObject(Tservice serverObjectConfig, String contextString) throws SlxException { this(serverObjectConfig, null, null, contextString); } public ServiceObject(Tservice srvConfig, Context context, ReflectionArgument factoryOptionalArgs[], String contextString) throws SlxException { this.serverObjectConfig = srvConfig; this.context = context; this.factoryOptionalArgs = factoryOptionalArgs; this.contextString = contextString; lookupStyle = srvConfig.getLookupStyle(); // if ( lookupStyle == null ) // lookupStyle = lookupStyle; switch (lookupStyle) { case NEW: { serverObjectClassName = srvConfig.getClazz(); if (serverObjectClassName == null) throw new SlxException(Tmodule.DATASOURCE, Texception.V_CONDITION_DISSATISFY, (new StringBuilder()).append( "No className specified in serverConfig with ").append("declared").append(" lookupStyle=\"new\" used by ").append( contextString).toString()); try { serverObjectClass = Reflection.classForName(serverObjectClassName); String xpath = serverObjectConfig.getTargetXPath(); if (xpath != null && !xpath.equals("")) try { JXPathContext jxpc = JXPathContext.newContext(serverObjectClass.newInstance()); serverObjectInstance = jxpc.getValue(xpath); serverObjectClass = serverObjectInstance.getClass(); } catch (InstantiationException ie) { throw new SlxException(Tmodule.DATASOURCE, Texception.V_CONDITION_DISSATISFY, (new StringBuilder()).append("Could not create an instance of ").append(serverObjectClassName).append( " whilst attempting to process targetXPath ").append(xpath).append(" used by ").append(contextString).append( " - Exception string: ").append(ie.toString()).toString()); } } catch (Exception e) { throw new SlxException(Tmodule.DATASOURCE, Texception.V_CONDITION_DISSATISFY, (new StringBuilder()).append( "Failed to lookup class by name: ").append(serverObjectClassName).append(" specified in serverConfig used by ").append( contextString).append(" - Exception string: ").append(e.toString()).toString()); } } break; case OSGI: { serverObjectInterface = srvConfig.getInterface(); serverObjectFilter = srvConfig.getFilter(); Object[] objects = ServiceUtil.getOSGIServices(serverObjectInterface, serverObjectFilter); if (DataUtils.isNotNullAndEmpty(objects)) serverObjectInstance = objects[0]; } break; case BEAN: { serverObjectInterface = srvConfig.getInterface(); serverObjectFilter = srvConfig.getFilter(); serverObjectInstance = ServiceUtil.getOsgiJndiService(serverObjectInterface, serverObjectFilter); } break; default: break; } if (serverObjectClass == null) serverObjectClass = serverObjectInstance.getClass(); } public Class<?> getServiceClass() throws Exception { return serverObjectClass; } public Object getServiceInstance() throws Exception { return getServiceInstance(null); } public Object getServiceInstance(Method method) throws Exception { if (serverObjectInstance == null && (method == null || !Modifier.isStatic(method.getModifiers()))) serverObjectInstance = Reflection.newInstance(serverObjectClass); return serverObjectInstance; } public Method getServiceMethod(String methodName) throws Exception { if (method == null) method = findMethod(serverObjectClass, methodName); return method; } public static Method findMethod(Class<?> serverObjectClass, String methodName) throws Exception { Method methods[] = serverObjectClass.getMethods(); List<Method> candidateMethods = new ArrayList<Method>(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (methodName.equals(method.getName())) candidateMethods.add(method); } if (candidateMethods.size() == 0) { log.debug((new StringBuilder()).append("Couldn't find a public method named: ").append(methodName).append(" on class: ").append( serverObjectClass.getName()).toString()); return null; } if (candidateMethods.size() > 1) throw new Exception((new StringBuilder()).append("Class ").append(serverObjectClass.getName()).append(" defines multiple").append( " methods named: ").append(methodName).append(" - overloading is not supported - please disambiguate.").toString()); else return candidateMethods.get(0); } public String getServiceAsString() { if (this.lookupStyle != null) { switch (lookupStyle) { case NEW: return serverObjectClassName; case OSGI: return serverObjectInterface + serverObjectFilter; case BEAN: return serverObjectInterface; default: break; } } return null; } }