package org.jacorb.ir; /* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.lang.reflect.Method; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; import org.slf4j.Logger; import org.omg.CORBA.ExceptionDefPOATie; import org.omg.CORBA.INTF_REPOS; import org.omg.PortableServer.POA; public class OperationDef extends Contained implements org.omg.CORBA.OperationDefOperations { private org.omg.CORBA.TypeCode result = null; private org.omg.CORBA.IDLType result_def = null; private org.omg.CORBA.ExceptionDef[] exceptions = null; private org.omg.CORBA.ParameterDescription[] params = null; private String[] contexts = new String[0]; private org.omg.CORBA.OperationMode mode; private Method method; /** the extra information on the operation that is provided in the IRHelper */ private String opInfo; private String returnTypeName; private String[] paramTypeNames = new String[0]; private boolean defined = false; private Logger logger; private ClassLoader loader; private POA poa; public OperationDef( Method m, Class def_in, Class irHelper, org.omg.CORBA.InterfaceDef i_def, Logger logger, ClassLoader loader, POA poa) { this.logger = logger; this.loader = loader; this.poa = poa; def_kind = org.omg.CORBA.DefinitionKind.dk_Operation; name( m.getName()); if (def_in == null) { throw new INTF_REPOS ("Class argument null"); } if (i_def == null) { throw new INTF_REPOS ("Idef argument null" ); } id( RepositoryID.toRepositoryID( RepositoryID.className( i_def.id(), loader) + "/" + name(), false, loader)); version(id().substring( id().lastIndexOf(':'))); defined_in = i_def; containing_repository = i_def.containing_repository(); String className = def_in.getName(); absolute_name = i_def.absolute_name() + "::" + name; method = m; if (this.logger.isDebugEnabled()) { this.logger.debug("New OperationDef, name: " + name + " " + absolute_name); } Hashtable irInfo = null; opInfo = null; try { irInfo = (Hashtable)irHelper.getDeclaredField("irInfo").get(null); opInfo = (String)irInfo.get( name() ); } catch( Exception e ) { logger.error("Caught Exception", e); } /* parse extra operation information that's in the opInfo string */ if( opInfo != null ) { if( opInfo.endsWith("-oneway")) { mode = org.omg.CORBA.OperationMode.OP_ONEWAY; } if( opInfo.indexOf("(") > 0 ) returnTypeName = opInfo.substring(0,opInfo.indexOf("(")); StringTokenizer strtok = new StringTokenizer( opInfo.substring( opInfo.indexOf("(") + 1, opInfo.lastIndexOf(")")), ","); paramTypeNames = new String[strtok.countTokens()]; for( int i = 0; i < paramTypeNames.length; i++ ) { String token = strtok.nextToken(); paramTypeNames[i] = ( !token.equals(",") ? token : null ); } } if( mode == null ) { mode = org.omg.CORBA.OperationMode.OP_NORMAL; } contexts = new String[0]; } void define() { try { result = TypeCodeUtil.getTypeCode( method.getReturnType(), this.loader, null, returnTypeName, this.logger); result_def = IDLType.create( result, containing_repository, this.logger, this.poa); } catch( Exception e ) { logger.error("Caught Exception", e); } params = getParameterDescriptions(); Class [] ex_classes = method.getExceptionTypes(); Class uexc = null; try { uexc = this.loader.loadClass("org.omg.CORBA.UserException"); } catch ( ClassNotFoundException e1) { throw new INTF_REPOS(ErrorMsg.IR_Definition_Not_Found, org.omg.CORBA.CompletionStatus.COMPLETED_NO); } Vector v = new Vector(); for( int ix = 0; ix < ex_classes.length; ix++ ) { if( uexc.isAssignableFrom(ex_classes[ix])) { try { ExceptionDef ex = new ExceptionDef( ex_classes[ ix ], defined_in, containing_repository, this.loader, this.poa, this.logger); org.omg.CORBA.ExceptionDef exRef = org.omg.CORBA.ExceptionDefHelper.narrow( this.poa.servant_to_reference( new ExceptionDefPOATie ( ex ) ) ); v.addElement( exRef ); ex.setReference( exRef ); } catch( Exception e ) { logger.error("Caught Exception", e); } } } exceptions = new org.omg.CORBA.ExceptionDef[ v.size() ]; v.copyInto( exceptions ); defined = true; } org.omg.CORBA.ParameterDescription[] getParameterDescriptions() { org.omg.CORBA.TypeCode tc = null; Class m_params[] = method.getParameterTypes(); org.omg.CORBA.ParameterDescription[] params = new org.omg.CORBA.ParameterDescription[m_params.length]; if( paramTypeNames.length > 0 ) { if (paramTypeNames.length != m_params.length) { throw new INTF_REPOS ("Different parameter type numbers! " + paramTypeNames.length + " vs. " + m_params.length + " inforString: " + opInfo); } } for( int i = 0; i < params.length; i++) { String name = "arg_" + i; String paramInfo = null; org.omg.CORBA.ParameterMode mode = null; try { String parameterTypeName = m_params[i].getName(); if( paramTypeNames.length != 0 ) paramInfo = paramTypeNames[i]; if( ! parameterTypeName.endsWith("Holder") ) { mode = org.omg.CORBA.ParameterMode.PARAM_IN; if( paramInfo != null && paramInfo.indexOf(' ') > 0 ) { parameterTypeName = paramInfo.substring( paramInfo.indexOf(' ')+1); name = paramInfo.substring( paramInfo.indexOf(':')+1, paramInfo.indexOf(' ')); } } else { if ( ! (paramInfo != null && (paramInfo.indexOf(' ') > 0))) { throw new INTF_REPOS ("No param info for " + parameterTypeName); } if( paramInfo.substring(0, (paramInfo.indexOf(' ')-1)).startsWith("inout:")) mode = org.omg.CORBA.ParameterMode.PARAM_INOUT; else mode = org.omg.CORBA.ParameterMode.PARAM_OUT; name = paramInfo.substring( paramInfo.indexOf(':')+1, paramInfo.indexOf(' ')); parameterTypeName = parameterTypeName.substring(0, parameterTypeName.indexOf("Holder")); } if (this.logger.isDebugEnabled()) { this.logger.debug("Operation " + name() + ", param #"+ i + "name: " + name + ", paramTypeName " + parameterTypeName + paramInfo); } tc = TypeCodeUtil.getTypeCode( m_params[i], this.loader, null, parameterTypeName, this.logger); } catch ( Exception e ) { logger.error("Caught Exception", e); throw new INTF_REPOS( ErrorMsg.IR_Definition_Not_Found, org.omg.CORBA.CompletionStatus.COMPLETED_NO); } org.omg.CORBA.IDLType type_def = IDLType.create( tc, containing_repository, this.logger, this.poa ); params[i] = new org.omg.CORBA.ParameterDescription( name, tc, type_def, mode); } return params; } public org.omg.CORBA.IDLType result_def() { if ( ! defined) { throw new INTF_REPOS ("OperationDef undefined"); } if (result_def == null) { throw new INTF_REPOS ("Result def for op " + name () + " null"); } return result_def; } public void result_def(org.omg.CORBA.IDLType a) { result_def = a; } public org.omg.CORBA.OperationMode mode() { return mode; } public void mode( org.omg.CORBA.OperationMode a) { mode = a; } public org.omg.CORBA.TypeCode result() { if ( ! defined) { throw new INTF_REPOS ("OperationDeg undefined"); } return result; } public org.omg.CORBA.ParameterDescription[] params() { if( !defined ) define(); return params; } public void params(org.omg.CORBA.ParameterDescription[] a) { params = a; } public java.lang.String[] contexts() { if( !defined ) define(); return contexts; } public void contexts(java.lang.String[] a) { contexts = a; } public org.omg.CORBA.ExceptionDef[] exceptions() { if( !defined ) define(); return exceptions; } public void exceptions(org.omg.CORBA.ExceptionDef[] a) { exceptions = a; } public org.omg.CORBA.OperationDescription describe_operation() { if( !defined ) define(); org.omg.CORBA.ExceptionDescription ex_des[] = new org.omg.CORBA.ExceptionDescription[exceptions.length]; for( int i = 0; i < exceptions.length; i++ ) { org.omg.CORBA.ContainedPackage.Description cd = exceptions[i].describe(); if( cd.kind != org.omg.CORBA.DefinitionKind.dk_Exception ) { throw new INTF_REPOS( ErrorMsg.IR_Unexpected_Definition_Kind, org.omg.CORBA.CompletionStatus.COMPLETED_NO); } ex_des[i] = org.omg.CORBA.ExceptionDescriptionHelper.extract( cd.value ); } return new org.omg.CORBA.OperationDescription(name, id, org.omg.CORBA.ContainedHelper.narrow(defined_in).id(), version, result, mode, contexts, params, ex_des); } // from IRObject public void destroy() { throw new INTF_REPOS( ErrorMsg.IR_Not_Implemented, org.omg.CORBA.CompletionStatus.COMPLETED_NO); } // from Contained public org.omg.CORBA.ContainedPackage.Description describe() { if ( ! defined) { throw new INTF_REPOS ("OperationDeg undefined"); } org.omg.CORBA.Any a = orb.create_any(); org.omg.CORBA.OperationDescriptionHelper.insert( a, describe_operation() ); return new org.omg.CORBA.ContainedPackage.Description( org.omg.CORBA.DefinitionKind.dk_Operation, a); } }