001: package org.jacorb.ir;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.lang.reflect.*;
024: import java.util.*;
025:
026: import org.omg.CORBA.ExceptionDefPOATie;
027: import org.omg.CORBA.INTF_REPOS;
028: import org.omg.PortableServer.POA;
029:
030: import org.apache.avalon.framework.logger.Logger;
031:
032: public class OperationDef extends Contained implements
033: org.omg.CORBA.OperationDefOperations {
034: private org.omg.CORBA.TypeCode result = null;
035: private org.omg.CORBA.IDLType result_def = null;
036: private org.omg.CORBA.ExceptionDef[] exceptions = null;
037: private org.omg.CORBA.ParameterDescription[] params = null;
038:
039: private String[] contexts = new String[0];
040: private org.omg.CORBA.OperationMode mode;
041:
042: private Method method;
043:
044: /** the extra information on the operation that is provided in the
045: IRHelper */
046: private String opInfo;
047: private String returnTypeName;
048: private String[] paramTypeNames = new String[0];
049:
050: private boolean defined = false;
051:
052: private Logger logger;
053: private ClassLoader loader;
054: private POA poa;
055:
056: public OperationDef(Method m, Class def_in, Class irHelper,
057: org.omg.CORBA.InterfaceDef i_def, Logger logger,
058: ClassLoader loader, POA poa) {
059: this .logger = logger;
060: this .loader = loader;
061: this .poa = poa;
062:
063: def_kind = org.omg.CORBA.DefinitionKind.dk_Operation;
064: name(m.getName());
065:
066: if (def_in == null) {
067: throw new INTF_REPOS("Class argument null");
068: }
069: if (i_def == null) {
070: throw new INTF_REPOS("Idef argument null");
071: }
072:
073: id(RepositoryID.toRepositoryID(RepositoryID.className(i_def
074: .id(), loader)
075: + "/" + name(), false, loader));
076:
077: version(id().substring(id().lastIndexOf(':')));
078: defined_in = i_def;
079: containing_repository = i_def.containing_repository();
080: String className = def_in.getName();
081: absolute_name = i_def.absolute_name() + "::" + name;
082: method = m;
083:
084: if (this .logger.isDebugEnabled()) {
085: this .logger.debug("New OperationDef, name: " + name + " "
086: + absolute_name);
087: }
088:
089: Hashtable irInfo = null;
090: opInfo = null;
091: try {
092: irInfo = (Hashtable) irHelper.getDeclaredField("irInfo")
093: .get(null);
094: opInfo = (String) irInfo.get(name());
095: } catch (Exception e) {
096: logger.error("Caught Exception", e);
097: }
098:
099: /* parse extra operation information that's in the opInfo string */
100:
101: if (opInfo != null) {
102: if (opInfo.endsWith("-oneway")) {
103: mode = org.omg.CORBA.OperationMode.OP_ONEWAY;
104: }
105:
106: if (opInfo.indexOf("(") > 0)
107: returnTypeName = opInfo.substring(0, opInfo
108: .indexOf("("));
109:
110: StringTokenizer strtok = new StringTokenizer(opInfo
111: .substring(opInfo.indexOf("(") + 1, opInfo
112: .lastIndexOf(")")), ",");
113:
114: paramTypeNames = new String[strtok.countTokens()];
115: for (int i = 0; i < paramTypeNames.length; i++) {
116: String token = strtok.nextToken();
117:
118: paramTypeNames[i] = (!token.equals(",") ? token : null);
119: }
120: }
121:
122: if (mode == null) {
123: mode = org.omg.CORBA.OperationMode.OP_NORMAL;
124: }
125:
126: contexts = new String[0];
127: }
128:
129: void define() {
130: try {
131: result = TypeCodeUtil.getTypeCode(method.getReturnType(),
132: this .loader, null, returnTypeName, this .logger);
133:
134: result_def = org.jacorb.ir.IDLType.create(result,
135: containing_repository, this .logger, this .poa);
136: } catch (Exception e) {
137: logger.error("Caught Exception", e);
138: }
139:
140: params = getParameterDescriptions();
141:
142: Class[] ex_classes = method.getExceptionTypes();
143: Class uexc = null;
144: try {
145: uexc = this .loader.loadClass("org.omg.CORBA.UserException");
146: } catch (ClassNotFoundException e1) {
147: throw new INTF_REPOS(ErrorMsg.IR_Definition_Not_Found,
148: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
149: }
150:
151: Vector v = new Vector();
152: for (int ix = 0; ix < ex_classes.length; ix++) {
153: if (uexc.isAssignableFrom(ex_classes[ix])) {
154: try {
155: ExceptionDef ex = new ExceptionDef(ex_classes[ix],
156: defined_in, containing_repository,
157: this .loader, this .poa, this .logger);
158: org.omg.CORBA.ExceptionDef exRef = org.omg.CORBA.ExceptionDefHelper
159: .narrow(this .poa
160: .servant_to_reference(new ExceptionDefPOATie(
161: ex)));
162:
163: v.addElement(exRef);
164: ex.setReference(exRef);
165: } catch (Exception e) {
166: logger.error("Caught Exception", e);
167: }
168: }
169: }
170:
171: exceptions = new org.omg.CORBA.ExceptionDef[v.size()];
172: v.copyInto(exceptions);
173:
174: defined = true;
175: }
176:
177: org.omg.CORBA.ParameterDescription[] getParameterDescriptions() {
178: org.omg.CORBA.TypeCode tc = null;
179: Class m_params[] = method.getParameterTypes();
180:
181: org.omg.CORBA.ParameterDescription[] params = new org.omg.CORBA.ParameterDescription[m_params.length];
182:
183: if (paramTypeNames.length > 0) {
184: if (paramTypeNames.length != m_params.length) {
185: throw new INTF_REPOS(
186: "Different parameter type numbers! "
187: + paramTypeNames.length + " vs. "
188: + m_params.length + " inforString: "
189: + opInfo);
190: }
191: }
192:
193: for (int i = 0; i < params.length; i++) {
194: String name = "arg_" + i;
195: String paramInfo = null;
196: org.omg.CORBA.ParameterMode mode = null;
197: try {
198: String parameterTypeName = m_params[i].getName();
199:
200: if (paramTypeNames.length != 0)
201: paramInfo = paramTypeNames[i];
202:
203: if (!parameterTypeName.endsWith("Holder")) {
204: mode = org.omg.CORBA.ParameterMode.PARAM_IN;
205: if (paramInfo != null && paramInfo.indexOf(' ') > 0) {
206: parameterTypeName = paramInfo
207: .substring(paramInfo.indexOf(' ') + 1);
208: name = paramInfo.substring(paramInfo
209: .indexOf(':') + 1, paramInfo
210: .indexOf(' '));
211: }
212: } else {
213: if (!(paramInfo != null && (paramInfo.indexOf(' ') > 0))) {
214: throw new INTF_REPOS("No param info for "
215: + parameterTypeName);
216: }
217:
218: if (paramInfo.substring(0,
219: (paramInfo.indexOf(' ') - 1)).startsWith(
220: "inout:"))
221: mode = org.omg.CORBA.ParameterMode.PARAM_INOUT;
222: else
223: mode = org.omg.CORBA.ParameterMode.PARAM_OUT;
224:
225: name = paramInfo.substring(
226: paramInfo.indexOf(':') + 1, paramInfo
227: .indexOf(' '));
228:
229: parameterTypeName = parameterTypeName.substring(0,
230: parameterTypeName.indexOf("Holder"));
231: }
232:
233: if (this .logger.isDebugEnabled()) {
234: this .logger.debug("Operation " + name()
235: + ", param #" + i + "name: " + name
236: + ", paramTypeName " + parameterTypeName
237: + paramInfo);
238: }
239:
240: tc = TypeCodeUtil.getTypeCode(m_params[i], this .loader,
241: null, parameterTypeName, this .logger);
242: } catch (Exception e) {
243: logger.error("Caught Exception", e);
244: throw new INTF_REPOS(ErrorMsg.IR_Definition_Not_Found,
245: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
246: }
247: org.omg.CORBA.IDLType type_def = IDLType.create(tc,
248: containing_repository, this .logger, this .poa);
249: params[i] = new org.omg.CORBA.ParameterDescription(name,
250: tc, type_def, mode);
251: }
252: return params;
253: }
254:
255: public org.omg.CORBA.IDLType result_def() {
256: if (!defined) {
257: throw new INTF_REPOS("OperationDef undefined");
258: }
259: if (result_def == null) {
260: throw new INTF_REPOS("Result def for op " + name()
261: + " null");
262: }
263: return result_def;
264: }
265:
266: public void result_def(org.omg.CORBA.IDLType a) {
267: result_def = a;
268: }
269:
270: public org.omg.CORBA.OperationMode mode() {
271: return mode;
272: }
273:
274: public void mode(org.omg.CORBA.OperationMode a) {
275: mode = a;
276: }
277:
278: public org.omg.CORBA.TypeCode result() {
279: if (!defined) {
280: throw new INTF_REPOS("OperationDeg undefined");
281: }
282:
283: return result;
284: }
285:
286: public org.omg.CORBA.ParameterDescription[] params() {
287: if (!defined)
288: define();
289: return params;
290: }
291:
292: public void params(org.omg.CORBA.ParameterDescription[] a) {
293: params = a;
294: }
295:
296: public java.lang.String[] contexts() {
297: if (!defined)
298: define();
299: return contexts;
300: }
301:
302: public void contexts(java.lang.String[] a) {
303: contexts = a;
304: }
305:
306: public org.omg.CORBA.ExceptionDef[] exceptions() {
307: if (!defined)
308: define();
309: return exceptions;
310: }
311:
312: public void exceptions(org.omg.CORBA.ExceptionDef[] a) {
313: exceptions = a;
314: }
315:
316: public org.omg.CORBA.OperationDescription describe_operation() {
317: if (!defined)
318: define();
319:
320: org.omg.CORBA.ExceptionDescription ex_des[] = new org.omg.CORBA.ExceptionDescription[exceptions.length];
321:
322: for (int i = 0; i < exceptions.length; i++) {
323: org.omg.CORBA.ContainedPackage.Description cd = exceptions[i]
324: .describe();
325:
326: if (cd.kind != org.omg.CORBA.DefinitionKind.dk_Exception) {
327: throw new INTF_REPOS(
328: ErrorMsg.IR_Unexpected_Definition_Kind,
329: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
330: }
331: ex_des[i] = org.omg.CORBA.ExceptionDescriptionHelper
332: .extract(cd.value);
333: }
334: return new org.omg.CORBA.OperationDescription(name, id,
335: org.omg.CORBA.ContainedHelper.narrow(defined_in).id(),
336: version, result, mode, contexts, params, ex_des);
337: }
338:
339: // from IRObject
340:
341: public void destroy() {
342: throw new INTF_REPOS(ErrorMsg.IR_Not_Implemented,
343: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
344: }
345:
346: // from Contained
347:
348: public org.omg.CORBA.ContainedPackage.Description describe() {
349: if (!defined) {
350: throw new INTF_REPOS("OperationDeg undefined");
351: }
352:
353: org.omg.CORBA.Any a = orb.create_any();
354: org.omg.CORBA.OperationDescriptionHelper.insert(a,
355: describe_operation());
356: return new org.omg.CORBA.ContainedPackage.Description(
357: org.omg.CORBA.DefinitionKind.dk_Operation, a);
358: }
359:
360: }
|