@Override @SuppressWarnings("unchecked") public <T extends ICode> T getCode(final Class<T> type) { synchronized (m_codeTypeMapLock) { if (type == null) { return null; } Class declaringCodeTypeClass = null; if (type.getDeclaringClass() != null) { // code is inner type of code type or another code Class c = type.getDeclaringClass(); while (c != null && !(ICodeType.class.isAssignableFrom(c))) { c = c.getDeclaringClass(); } declaringCodeTypeClass = c; } if (declaringCodeTypeClass == null) { try { declaringCodeTypeClass = type.newInstance().getCodeType().getClass(); } catch (Throwable t) { LOG.error("find code " + type, t); } } ICodeType codeType = getCodeType(declaringCodeTypeClass); final Holder<ICode> codeHolder = new Holder<ICode>(ICode.class); ICodeVisitor v = new ICodeVisitor() { @Override public boolean visit(ICode code, int treeLevel) { if (code.getClass() == type) { codeHolder.setValue(code); return false; } return true; } }; codeType.visit(v); return (T) codeHolder.getValue(); } }
@Override public Object invoke(final Packet packet, final Method method, final Object... aobj) throws InvocationTargetException, IllegalAccessException { final T portType = ScoutInstanceResolver.this.resolve(packet); if (portType == null) { throw new WebServiceException("No port type found"); } Subject subject = null; try { subject = Subject.getSubject(AccessController.getContext()); } catch (Exception e) { LOG.error("Failed to get subject of calling access context", e); } if (subject == null) { throw new WebServiceException( "Webservice request was NOT dispatched due to security reasons: request must run on behalf of a subject context."); } IServerSession session = getSession(m_context.getMessageContext()); if (session == null) { LOG.warn( "Webservice request is not run in a session context as no server session is configured."); return method.invoke(portType, aobj); } try { final ObjectHolder resultHolder = new ObjectHolder(); final Holder<InvocationTargetException> invocationTargetExceptionHolder = new Holder<InvocationTargetException>(InvocationTargetException.class); final Holder<IllegalAccessException> illegalAccessExceptionHolder = new Holder<IllegalAccessException>(IllegalAccessException.class); final Holder<RuntimeException> runtimeExceptionHolder = new Holder<RuntimeException>(RuntimeException.class); // run server job final IServerJobFactory jobFactory = SERVICES.getService(IServerJobService.class).createJobFactory(session, subject); ServerJob serverJob = jobFactory.create( "Tx", new ITransactionRunnable() { @Override public IStatus run(IProgressMonitor monitor) throws ProcessingException { try { resultHolder.setValue(method.invoke(portType, aobj)); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); ThreadContext.getTransaction().addFailure(cause); // rollback transaction if (cause instanceof RuntimeException) { LOG.warn( "Webservice processing exception occured. Please handle faults by respective checked SOAP faults.", cause); invocationTargetExceptionHolder.setValue( new InvocationTargetException( new WebServiceException("Internal Server Error"))); } else { // business exception (SOAP faults are checked exceptions) LOG.info("Webservice processing exception occured.", cause); invocationTargetExceptionHolder.setValue(e); } } catch (IllegalAccessException e) { ThreadContext.getTransaction().addFailure(e); // rollback transaction LOG.error( "Illegal access exception occured while dispatching webservice request. This might be caused because of Java security settings.", e); illegalAccessExceptionHolder.setValue(e); } catch (RuntimeException e) { ThreadContext.getTransaction().addFailure(e); // rollback transaction LOG.error( "Unexpected error occured while dispatching webservice request.", e); runtimeExceptionHolder.setValue(e); } return Status.OK_STATUS; } }); serverJob.setSystem(true); serverJob.runNow(new NullProgressMonitor()); if (invocationTargetExceptionHolder.getValue() != null) { throw invocationTargetExceptionHolder.getValue(); } if (illegalAccessExceptionHolder.getValue() != null) { throw illegalAccessExceptionHolder.getValue(); } if (runtimeExceptionHolder.getValue() != null) { throw runtimeExceptionHolder.getValue(); } return resultHolder.getValue(); } finally { postInvoke(packet, portType); } }