diff options
Diffstat (limited to '')
-rw-r--r-- | sca-java-2.x/tags/2.0-Beta1-RC2/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaRequest.java | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-Beta1-RC2/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaRequest.java b/sca-java-2.x/tags/2.0-Beta1-RC2/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaRequest.java new file mode 100644 index 0000000000..e7d0b8b91b --- /dev/null +++ b/sca-java-2.x/tags/2.0-Beta1-RC2/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaRequest.java @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.tuscany.sca.binding.corba.provider.reference; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.binding.corba.provider.exceptions.CorbaException; +import org.apache.tuscany.sca.binding.corba.provider.exceptions.RequestConfigurationException; +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTree; +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeCreator; +import org.apache.tuscany.sca.binding.corba.provider.types.util.TypeHelpersProxy; +import org.apache.tuscany.sca.binding.corba.provider.types.util.Utils; +import org.apache.tuscany.sca.binding.corba.provider.util.MethodFinder; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Object; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ Represents single CORBA request + */ +public class DynaCorbaRequest { + + private TypeTree returnTree; + private Map<String, TypeTree> exceptions = new HashMap<String, TypeTree>(); + private InputStream inputStream; + private ObjectImpl remoteObject; + private String operation; + private List<java.lang.Object> arguments = new ArrayList<java.lang.Object>(); + private List<TypeTree> argumentsTypes = new ArrayList<TypeTree>(); + private Class<?> referenceClass; + private Map<Method, String> operationsMap; + + /** + * Creates request. + * + * @param ObjectremoteObject remote object reference + * @param operation operation to invoke + * @param scaBindingRules apply SCA default binding mapping rules + */ + public DynaCorbaRequest(Object remoteObject, String operation) { + this.remoteObject = (ObjectImpl)remoteObject; + this.operation = operation; + } + + /** + * Sets class which will be backed by this reference request + * @param referenceClass + */ + public void setReferenceClass(Class<?> referenceClass) { + this.referenceClass = referenceClass; + } + + /** + * Sets method to operation names mapping + * @param operationsMap + */ + public void setOperationsMap(Map<Method, String> operationsMap) { + this.operationsMap = operationsMap; + } + + /** + * Adds operation argument - stores arguments and caches its TypeTree. Annotations will be set to null by default. + * + * @param argument + */ + public void addArgument(java.lang.Object argument) throws RequestConfigurationException { + addArgument(argument, null); + } + + /** + * Adds operation argument - stores arguments and caches its TypeTree + * + * @param argument + */ + public void addArgument(java.lang.Object argument, Annotation[] notes) throws RequestConfigurationException { + TypeTree tree = TypeTreeCreator.createTypeTree(argument.getClass(), notes); + argumentsTypes.add(tree); + arguments.add(argument); + } + + /** + * Passing stored arguments to CORBA communication output stream + * + * @param outputStream + * @throws RequestConfigurationException + */ + private void passArguments(OutputStream outputStream) throws RequestConfigurationException { + for (int i = 0; i < arguments.size(); i++) { + TypeTree tree = argumentsTypes.get(i); + TypeHelpersProxy.write(tree.getRootNode(), outputStream, arguments.get(i)); + } + } + + /** + * Sets return type for operation. Annotations will be set to null by default. + * + * @param forClass + */ + public void setOutputType(Class<?> forClass) throws RequestConfigurationException { + setOutputType(forClass, null); + } + + /** + * Sets return type for operation + * + * @param forClass + */ + public void setOutputType(Class<?> forClass, Annotation[] notes) throws RequestConfigurationException { + returnTree = TypeTreeCreator.createTypeTree(forClass, notes); + } + + /** + * Configures possible exceptions + * + * @param forClass + */ + public void addExceptionType(Class<?> forClass) throws RequestConfigurationException { + TypeTree tree = TypeTreeCreator.createTypeTree(forClass, null); + String exceptionId = Utils.getTypeId(forClass); + exceptions.put(exceptionId, tree); + } + + /** + * Handles application excpeition. + * + * @param ae occured exception + * @throws Exception + */ + private void handleApplicationException(ApplicationException ae) throws Exception { + try { + if (exceptions.size() == 0) { + RequestConfigurationException exception = + new RequestConfigurationException( + "ApplicationException occured, but no exception type was specified.", + ae.getId()); + throw exception; + } + InputStream is = ae.getInputStream(); + String exceptionId = is.read_string(); + TypeTree tree = exceptions.get(exceptionId); + if (tree == null) { + RequestConfigurationException exception = + new RequestConfigurationException( + "ApplicationException occured, but no such exception was defined", + ae.getId()); + throw exception; + } else { + Exception ex = (Exception)TypeHelpersProxy.read(tree.getRootNode(), is); + throw ex; + } + } catch (Exception e) { + throw e; + } + } + + /** + * Handles exceptions generated by CORBA API + * + * @param se + */ + private void handleSystemException(SystemException se) throws Exception { + if (se instanceof BAD_OPERATION) { + throw new CorbaException("Bad operation name: " + operation, se); + } else if (se instanceof BAD_PARAM) { + throw new CorbaException("Bad parameter", se); + } else { + // TODO: handle more system exception types + throw new CorbaException(se.getMessage(), se); + } + } + + /** + * Gets operation name which is includes mapping rules + * @return + */ + private String getFinalOperationName() { + String result = operation; + if (referenceClass != null) { + Class<?>[] argumentTypes = new Class<?>[arguments.size()]; + for (int i = 0; i < arguments.size(); i++) { + argumentTypes[i] = arguments.get(i).getClass(); + } + Method method = MethodFinder.findMethod(referenceClass, operation, argumentTypes); + String newOperation = (String)operationsMap.get(method); + if (newOperation != null) { + result = newOperation; + } + } + return result; + } + + /** + * Invokes previously configured request + * + * @return + */ + public DynaCorbaResponse invoke() throws Exception { + DynaCorbaResponse response = new DynaCorbaResponse(); + String finalOperationName = getFinalOperationName(); + OutputStream outputStream = ((ObjectImpl)remoteObject)._request(finalOperationName, true); + passArguments(outputStream); + try { + inputStream = remoteObject._invoke(outputStream); + if (inputStream != null && returnTree != null) { + response.setContent(TypeHelpersProxy.read(returnTree.getRootNode(), inputStream)); + } + } catch (ApplicationException ae) { + handleApplicationException(ae); + } catch (SystemException se) { + handleSystemException(se); + } catch (Exception e) { + throw e; + } finally { + release(); + } + return response; + } + + /** + * Releases request resources + */ + private void release() { + remoteObject._releaseReply(inputStream); + } + +} |