diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2010-10-18 02:24:55 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2010-10-18 02:24:55 +0000 |
commit | 4f9328953ea16c7a42eb1910f1e809bf1c537d3b (patch) | |
tree | 2f989a5045456d2057540563a483465a1d490dc0 /sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany | |
parent | 41c3e83fe3990eff86b40f775c5d02c5177ae005 (diff) |
Copy 2.0-M5.1-RC2 tag as 2.0-M5.1 official release tag
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1023626 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany')
44 files changed, 3719 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaBindingProviderFactory.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaBindingProviderFactory.java new file mode 100644 index 0000000000..bf0cc34195 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaBindingProviderFactory.java @@ -0,0 +1,61 @@ +/* + * 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; + +import org.apache.tuscany.sca.binding.corba.CorbaBinding; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.host.corba.ExtensibleCorbaHost; +import org.apache.tuscany.sca.provider.BindingProviderFactory; +import org.apache.tuscany.sca.provider.ReferenceBindingProvider; +import org.apache.tuscany.sca.provider.ServiceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; + +/** + * @version $Rev$ $Date$ + */ +public class CorbaBindingProviderFactory implements BindingProviderFactory<CorbaBinding> { + private ExtensibleCorbaHost host; + + public CorbaBindingProviderFactory(ExtensionPointRegistry registry) { + host = ExtensibleCorbaHost.getInstance(registry); + } + /** + * @see org.apache.tuscany.sca.provider.BindingProviderFactory#createReferenceBindingProvider(org.apache.tuscany.sca.runtime.RuntimeComponent, org.apache.tuscany.sca.runtime.RuntimeComponentReference, org.apache.tuscany.sca.assembly.Binding) + */ + public ReferenceBindingProvider createReferenceBindingProvider(RuntimeEndpointReference epr) { + return new CorbaReferenceBindingProvider(epr, host); + } + + /** + * @see org.apache.tuscany.sca.provider.BindingProviderFactory#createServiceBindingProvider(org.apache.tuscany.sca.runtime.RuntimeComponent, org.apache.tuscany.sca.runtime.RuntimeComponentService, org.apache.tuscany.sca.assembly.Binding) + */ + public ServiceBindingProvider createServiceBindingProvider(RuntimeEndpoint ep) { + return new CorbaServiceBindingProvider(ep, host); + } + + /** + * @see org.apache.tuscany.sca.provider.ProviderFactory#getModelType() + */ + public Class<CorbaBinding> getModelType() { + return CorbaBinding.class; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaInvoker.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaInvoker.java new file mode 100644 index 0000000000..0ad3b2240e --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaInvoker.java @@ -0,0 +1,89 @@ +/* + * 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; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Map; + +import org.apache.tuscany.sca.binding.corba.provider.exceptions.RequestConfigurationException; +import org.apache.tuscany.sca.binding.corba.provider.reference.DynaCorbaRequest; +import org.apache.tuscany.sca.binding.corba.provider.reference.DynaCorbaResponse; +import org.apache.tuscany.sca.binding.corba.provider.util.OperationMapper; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.omg.CORBA.Object; +import org.oasisopen.sca.ServiceRuntimeException; + +/** + * @version $Rev$ $Date$ + */ +public class CorbaInvoker implements Invoker { + + private Object remoteObject; + private Class<?> referenceClass; + private Map<Method, String> operationsMap; + private Map<Operation, Method> operationMethodMapping; + + public CorbaInvoker(RuntimeComponentReference reference, Object remoteObject, Class<?> referenceClass, Map<Method, String> operationsMap) { + this.remoteObject = remoteObject; + this.referenceClass = referenceClass; + this.operationsMap = operationsMap; + this.operationMethodMapping = OperationMapper.mapOperationToMethod(reference.getInterfaceContract().getInterface().getOperations(), referenceClass); + } + + /** + * @see org.apache.tuscany.sca.invocation.Invoker#invoke(org.apache.tuscany.sca.invocation.Message) + */ + public Message invoke(Message msg) { + try { + DynaCorbaRequest request = new DynaCorbaRequest(remoteObject, msg.getOperation().getName()); + request.setReferenceClass(referenceClass); + request.setOperationsMap(operationsMap); + if (msg.getOperation().getOutputType() != null) { + Annotation[] notes = operationMethodMapping.get(msg.getOperation()).getAnnotations(); + request.setOutputType(msg.getOperation().getOutputType().getPhysical(), notes); + } + java.lang.Object[] args = msg.getBody(); + if (args != null) { + Annotation[][] notes = operationMethodMapping.get(msg.getOperation()).getParameterAnnotations(); + for (int i = 0; i < args.length; i++) { + request.addArgument(args[i], notes[i]); + } + } + if (msg.getOperation().getFaultTypes() != null) { + for (DataType<?> type : msg.getOperation().getFaultTypes()) { + request.addExceptionType(type.getPhysical()); + } + } + DynaCorbaResponse response = request.invoke(); + msg.setBody(response.getContent()); + } catch (RequestConfigurationException e) { + throw new ServiceRuntimeException(e); + } catch (Exception e) { + msg.setFaultBody(e); + } + return msg; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaReferenceBindingProvider.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaReferenceBindingProvider.java new file mode 100644 index 0000000000..19ab58cc74 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaReferenceBindingProvider.java @@ -0,0 +1,101 @@ +/* + * 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; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.binding.corba.CorbaBinding; +import org.apache.tuscany.sca.binding.corba.provider.util.OperationMapper; +import org.apache.tuscany.sca.host.corba.CorbaHost; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.provider.ReferenceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; +import org.omg.CORBA.Object; + +/** + * @version $Rev$ $Date$ + */ +public class CorbaReferenceBindingProvider implements ReferenceBindingProvider { + + private static final Logger logger = Logger.getLogger(CorbaReferenceBindingProvider.class.getName()); + private CorbaBinding binding; + private CorbaHost host; + private RuntimeComponentReference reference; + private Object remoteObject; + private Class<?> referenceClass; + private Map<Method, String> operationsMap = null; + + public CorbaReferenceBindingProvider(RuntimeEndpointReference epr, CorbaHost host) { + this.binding = (CorbaBinding) epr.getBinding(); + this.host = host; + this.reference = (RuntimeComponentReference) epr.getReference(); + this.referenceClass = ((JavaInterface)reference.getInterfaceContract().getInterface()).getJavaClass(); + operationsMap = OperationMapper.mapMethodToOperationName(referenceClass); + } + + /** + * @see org.apache.tuscany.sca.provider.ReferenceBindingProvider#createInvoker(org.apache.tuscany.sca.interfacedef.Operation) + */ + public Invoker createInvoker(Operation operation) { + try { + if (remoteObject == null) { + remoteObject = host.lookup(binding.getCorbaname()); + } + return new CorbaInvoker(reference, remoteObject, referenceClass, operationsMap); + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during creating CORBA invoker", e); + } + return null; + } + + /** + * @see org.apache.tuscany.sca.provider.ReferenceBindingProvider#getBindingInterfaceContract() + */ + public InterfaceContract getBindingInterfaceContract() { + return reference.getInterfaceContract(); + } + + /** + * @see org.apache.tuscany.sca.provider.ReferenceBindingProvider#start() + */ + public void start() { + } + + /** + * @see org.apache.tuscany.sca.provider.ReferenceBindingProvider#stop() + */ + public void stop() { + } + + /** + * @see org.apache.tuscany.sca.provider.ReferenceBindingProvider#supportsOneWayInvocation() + */ + public boolean supportsOneWayInvocation() { + return false; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaServiceBindingProvider.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaServiceBindingProvider.java new file mode 100644 index 0000000000..0aa2e7394a --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/CorbaServiceBindingProvider.java @@ -0,0 +1,94 @@ +/* + * 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; + +import org.apache.tuscany.sca.binding.corba.CorbaBinding; +import org.apache.tuscany.sca.binding.corba.provider.service.ComponentInvocationProxy; +import org.apache.tuscany.sca.binding.corba.provider.service.DynaCorbaServant; +import org.apache.tuscany.sca.binding.corba.provider.service.InvocationProxy; +import org.apache.tuscany.sca.binding.corba.provider.types.util.Utils; +import org.apache.tuscany.sca.host.corba.CorbaHost; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.provider.ServiceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.oasisopen.sca.ServiceRuntimeException; + +/** + * @version $Rev$ $Date$ + */ +public class CorbaServiceBindingProvider implements ServiceBindingProvider { + + private RuntimeEndpoint endpoint; + private CorbaBinding binding; + private CorbaHost host; + // private RuntimeComponentService service; + private DynaCorbaServant servant; + + public CorbaServiceBindingProvider(RuntimeEndpoint ep, CorbaHost host) { + this.endpoint = ep; + // this.service = (RuntimeComponentService) ep.getService(); + this.binding = (CorbaBinding) ep.getBinding(); + this.host = host; + } + + /** + * @see org.apache.tuscany.sca.provider.ServiceBindingProvider#getBindingInterfaceContract() + */ + public InterfaceContract getBindingInterfaceContract() { + return endpoint.getBindingInterfaceContract(); + } + + /** + * @see org.apache.tuscany.sca.provider.ServiceBindingProvider#start() + */ + public void start() { + try { + Class<?> javaClass = ((JavaInterface)endpoint.getComponentTypeServiceInterfaceContract().getInterface()).getJavaClass(); + InvocationProxy proxy = new ComponentInvocationProxy(endpoint, javaClass); + servant = new DynaCorbaServant(proxy, Utils.getTypeId(javaClass)); + servant.setIds(new String[] {binding.getId()}); + host.registerServant(binding.getCorbaname(), servant); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + /** + * @see org.apache.tuscany.sca.provider.ServiceBindingProvider#stop() + */ + public void stop() { + try { + host.unregisterServant(binding.getCorbaname()); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + /** + * @see org.apache.tuscany.sca.provider.ServiceBindingProvider#supportsOneWayInvocation() + */ + public boolean supportsOneWayInvocation() { + return false; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/exceptions/CorbaException.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/exceptions/CorbaException.java new file mode 100644 index 0000000000..b3569e43b9 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/exceptions/CorbaException.java @@ -0,0 +1,34 @@ +/* + * 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.exceptions; + +/** + * @version $Rev$ $Date$ + * Represents CORBA SystemException + */ +public class CorbaException extends Exception { + + private static final long serialVersionUID = 1L; + + public CorbaException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/exceptions/RequestConfigurationException.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/exceptions/RequestConfigurationException.java new file mode 100644 index 0000000000..a554f56035 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/exceptions/RequestConfigurationException.java @@ -0,0 +1,43 @@ +/* + * 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.exceptions; + +/** + * @version $Rev$ $Date$ + */ +public class RequestConfigurationException extends Exception { + + private static final long serialVersionUID = 1L; + private String objectId; + + public RequestConfigurationException(String message, String objectId) { + super(message + ", object id was: " + objectId); + this.objectId = objectId; + } + + public RequestConfigurationException(String message) { + super(message); + } + + public String getType() { + return objectId; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaArray.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaArray.java new file mode 100644 index 0000000000..823db1e748 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaArray.java @@ -0,0 +1,34 @@ +/* + * 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.meta; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @version $Rev$ $Date$ + * Declares CORBA arrays lengths + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface CorbaArray { + + int[] value(); + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaUnionElement.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaUnionElement.java new file mode 100644 index 0000000000..feb6627e25 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaUnionElement.java @@ -0,0 +1,37 @@ +/* + * 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.meta; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @version $Rev$ $Date$ Declares CORBA union object + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface CorbaUnionElement { + + // number of option in switch clause + int optionNumber() default -1; + + // type of element + CorbaUnionElementType type(); + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaUnionElementType.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaUnionElementType.java new file mode 100644 index 0000000000..1e7a0087e0 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/meta/CorbaUnionElementType.java @@ -0,0 +1,28 @@ +/* + * 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.meta; + +/** + * @version $Rev$ $Date$ + * Types for union element + */ +public enum CorbaUnionElementType { + discriminator, defaultOption, option; +}
\ No newline at end of file diff --git a/sca-java-2.x/tags/2.0-M5.1/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-M5.1/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-M5.1/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); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaResponse.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaResponse.java new file mode 100644 index 0000000000..6a01c70a38 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/DynaCorbaResponse.java @@ -0,0 +1,39 @@ +/* + * 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; + +/** + * @version $Rev$ $Date$ + * Holder for content returned from DynaCorbaRequest + * + */ +public class DynaCorbaResponse { + + private Object content; + + public Object getContent() { + return content; + } + + public void setContent(Object content) { + this.content = content; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/InterfaceInstanceCreator.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/InterfaceInstanceCreator.java new file mode 100644 index 0000000000..2828e09cc7 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/InterfaceInstanceCreator.java @@ -0,0 +1,70 @@ +/* + * 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.reflect.Method; + +import net.sf.cglib.proxy.Callback; +import net.sf.cglib.proxy.CallbackFilter; +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.NoOp; + +import org.omg.CORBA.Object; + +/** + * @version $Rev$ $Date$ + */ +public class InterfaceInstanceCreator { + + private static final CallbackFilter FILTER = new CallbackFilter() { + public int accept(Method method) { + return 1; + } + }; + + /** + * Dynamically creates instance of user defined interface. Instance is + * enhanced by RemoteMethodInterceptor + * + * @param reference + * CORBA reference + * @param forClass + * user defined interface + * @return dynamic implementation instance + */ + public static java.lang.Object createInstance(Object reference, Class<?> forClass) { + java.lang.Object result = null; + try { + Enhancer enhancer = new Enhancer(); + enhancer.setInterfaces(new Class[] {forClass}); + enhancer.setCallbackFilter(FILTER); + enhancer.setCallbackTypes(new Class[] {NoOp.class, MethodInterceptor.class}); + Class<?> newClass = enhancer.createClass(); + Enhancer.registerStaticCallbacks(newClass, new Callback[] {NoOp.INSTANCE, + new InterfaceMethodInterceptor(reference, forClass)}); + result = newClass.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/InterfaceMethodInterceptor.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/InterfaceMethodInterceptor.java new file mode 100644 index 0000000000..c5c98ab27c --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/reference/InterfaceMethodInterceptor.java @@ -0,0 +1,65 @@ +/* + * 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.reflect.Method; + +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; + +import org.omg.CORBA.Object; + +/** + * @version $Rev$ $Date$ + * Interceptor for CORBA reference methods + */ +public class InterfaceMethodInterceptor implements MethodInterceptor { + + private Object reference; + private Class<?> javaClass; + + public InterfaceMethodInterceptor(Object reference, Class<?> javaClass) { + this.reference = reference; + this.javaClass = javaClass; + } + + /** + * Create and execute DynaCorbaRequest instance, basing on intercepted + * method arguments, return types, exceptions + */ + public java.lang.Object intercept(java.lang.Object object, + Method method, + java.lang.Object[] arguments, + MethodProxy arg3) throws Throwable { + DynaCorbaRequest request = new DynaCorbaRequest(reference, method.getName()); + request.setReferenceClass(javaClass); + for (int i = 0; i < arguments.length; i++) { + request.addArgument(arguments[i]); + } + request.setOutputType(method.getReturnType()); + Class<?>[] exceptions = method.getExceptionTypes(); + for (int i = 0; i < exceptions.length; i++) { + request.addExceptionType(exceptions[i]); + } + DynaCorbaResponse response = request.invoke(); + return response.getContent(); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/ComponentInvocationProxy.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/ComponentInvocationProxy.java new file mode 100644 index 0000000000..5babc25b07 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/ComponentInvocationProxy.java @@ -0,0 +1,122 @@ +/* + * 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.service; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +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.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.util.OperationMapper; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.runtime.Invocable; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; + +/** + * @version $Rev$ $Date$ + * Invocation proxy for SCA components + */ +public class ComponentInvocationProxy implements InvocationProxy { + + private Invocable wire; + private Map<Method, Operation> methodOperationMapping; + private Map<Operation, Method> operationMethodMapping; + private Map<String, Method> operationsMap; + private Map<Operation, OperationTypes> operationsCache = new HashMap<Operation, OperationTypes>(); + + public ComponentInvocationProxy(RuntimeEndpoint wire, Class javaClass) + throws RequestConfigurationException { + this.wire = wire; + Interface interfaze = wire.getComponentTypeServiceInterfaceContract().getInterface(); + operationsMap = OperationMapper.mapOperationNameToMethod(javaClass); + operationMethodMapping = OperationMapper.mapOperationToMethod(interfaze.getOperations(), javaClass); + methodOperationMapping = OperationMapper.mapMethodToOperation(interfaze.getOperations(), javaClass); + cacheOperationTypes(interfaze.getOperations()); + } + + /** + * Caches TypeTree for every operation in backed component + * + * @param operations + * @throws RequestConfigurationException + */ + private void cacheOperationTypes(List<Operation> operations) throws RequestConfigurationException { + for (Operation operation : operations) { + try { + OperationTypes operationTypes = new OperationTypes(); + List<TypeTree> inputInstances = new ArrayList<TypeTree>(); + // cache output type tree + if (operation.getOutputType() != null && operation.getOutputType().getPhysical() != null + && !operation.getOutputType().getPhysical().equals(void.class)) { + Annotation[] notes = operationMethodMapping.get(operation).getAnnotations(); + TypeTree outputType = + TypeTreeCreator.createTypeTree(operation.getOutputType().getPhysical(), notes); + operationTypes.setOutputType(outputType); + } + // cache input types trees + if (operation.getInputType() != null) { + Method method = operationMethodMapping.get(operation); + Annotation[][] notes = method.getParameterAnnotations(); + int i = 0; + for (DataType<List<DataType<?>>> type : operation.getInputType().getLogical()) { + Class<?> forClass = type.getPhysical(); + TypeTree inputType = TypeTreeCreator.createTypeTree(forClass, notes[i]); + inputInstances.add(inputType); + i++; + } + + } + operationTypes.setInputType(inputInstances); + operationsCache.put(operation, operationTypes); + } catch (RequestConfigurationException e) { + throw e; + } + } + } + + private Operation getOperation4Name(String operationName) { + Method method = operationsMap.get(operationName); + return methodOperationMapping.get(method); + } + + public OperationTypes getOperationTypes(String operationName) { + return operationsCache.get(getOperation4Name(operationName)); + } + + public Object invoke(String operationName, List<Object> arguments) throws InvocationException { + Object result = null; + try { + result = wire.invoke(getOperation4Name(operationName), arguments.toArray()); + } catch (InvocationTargetException e) { + InvocationException exception = new InvocationException(e.getCause()); + throw exception; + } + return result; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/DynaCorbaServant.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/DynaCorbaServant.java new file mode 100644 index 0000000000..d8524eaee9 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/DynaCorbaServant.java @@ -0,0 +1,137 @@ +/* + * 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.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +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.omg.CORBA.MARSHAL; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; + +/** + * @version $Rev$ $Date$ + * General servant which provides target component implementation via CORBA + */ +public class DynaCorbaServant extends ObjectImpl implements InvokeHandler { + + private static final Logger logger = Logger.getLogger(DynaCorbaServant.class.getName()); + + private String[] ids; + private InvocationProxy invocationProxy; + private String typeId; + + /** + * Creates servant object + * @param invocationProxy + * @param typeId + * @throws RequestConfigurationException + */ + public DynaCorbaServant(InvocationProxy invocationProxy, String typeId) throws RequestConfigurationException { + this.invocationProxy = invocationProxy; + this.typeId = typeId; + setDefaultIds(); + } + + /** + * Sets CORBA object ID + * @param ids + */ + public void setIds(String[] ids) { + for (int i = 0; i < ids.length; i++) { + if (ids[i] == null || ids[i].length() == 0) { + // if invalid id was passed then set to default + setDefaultIds(); + return; + } + } + this.ids = ids; + } + + public OutputStream _invoke(String operationName, InputStream in, ResponseHandler rh) { + OperationTypes types = invocationProxy.getOperationTypes(operationName); + if (types == null) { + // operation wasn't found + throw new org.omg.CORBA.BAD_OPERATION(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); + } else { + List<Object> inputInstances = new ArrayList<Object>(); + try { + // retrieving in arguments + for (TypeTree tree : types.getInputType()) { + Object o = TypeHelpersProxy.read(tree.getRootNode(), in); + inputInstances.add(o); + } + } catch (MARSHAL e) { + // parameter passed by user was not compatible with Java to + // Corba mapping + throw new org.omg.CORBA.BAD_PARAM(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); + } + try { + // invocation and sending result + Object result = invocationProxy.invoke(operationName, inputInstances); + OutputStream out = rh.createReply(); + if (types.getOutputType() != null) { + TypeTree tree = types.getOutputType(); + TypeHelpersProxy.write(tree.getRootNode(), out, result); + } + return out; + } catch (InvocationException ie) { + // handling user exception + try { + OutputStream out = rh.createExceptionReply(); + Class<?> exceptionClass = ie.getTargetException().getClass(); + TypeTree tree = TypeTreeCreator.createTypeTree(exceptionClass, null); + String exceptionId = Utils.getTypeId(exceptionClass); + out.write_string(exceptionId); + TypeHelpersProxy.write(tree.getRootNode(), out, ie.getTargetException()); + return out; + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during handling invocation exception", e); + } + } catch (Exception e) { + logger.log(Level.WARNING, "Unexpected exception during sending CORBA result to client", e); + } + } + return null; + } + + @Override + public String[] _ids() { + return ids; + } + + /** + * Sets servant ID to default, based on Java class name + */ + private void setDefaultIds() { + this.ids = new String[] {typeId}; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/InvocationException.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/InvocationException.java new file mode 100644 index 0000000000..57e2fae9f4 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/InvocationException.java @@ -0,0 +1,43 @@ +/* + * 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.service; + +/** + * @version $Rev$ $Date$ + * Wrapper for exception thrown during target invocation + */ +public class InvocationException extends Exception { + + private static final long serialVersionUID = 1L; + private Throwable targetException; + + public InvocationException(Throwable targetException) { + this.targetException = targetException; + } + + public Throwable getTargetException() { + return targetException; + } + + public void setTargetException(Throwable target) { + this.targetException = target; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/InvocationProxy.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/InvocationProxy.java new file mode 100644 index 0000000000..2e2066802a --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/InvocationProxy.java @@ -0,0 +1,46 @@ +/* + * 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.service; + +import java.util.List; + +/** + * @version $Rev$ $Date$ + * Target proxy interface for service bindings + */ +public interface InvocationProxy { + + /** + * Gets operations types for target + * @param operationName + * @return + */ + public OperationTypes getOperationTypes(String operationName); + + /** + * Invokes target operation + * @param operationName + * @param arguments + * @return + * @throws InvocationException + */ + public Object invoke(String operationName, List<Object> arguments) throws InvocationException; + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/OperationTypes.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/OperationTypes.java new file mode 100644 index 0000000000..766048ac64 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/service/OperationTypes.java @@ -0,0 +1,51 @@ +/* + * 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.service; + +import java.util.List; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTree; + +/** + * @version $Rev$ $Date$ + * Holder for Java type trees for one method + */ +public class OperationTypes { + + private TypeTree outputType; + private List<TypeTree> inputType; + + public TypeTree getOutputType() { + return outputType; + } + + public void setOutputType(TypeTree outputType) { + this.outputType = outputType; + } + + public List<TypeTree> getInputType() { + return inputType; + } + + public void setInputType(List<TypeTree> inputType) { + this.inputType = inputType; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/AnnotationAttributes.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/AnnotationAttributes.java new file mode 100644 index 0000000000..ab7371bbe8 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/AnnotationAttributes.java @@ -0,0 +1,46 @@ +/* + * 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.types; + +/** + * Holds information retrieved from objects annotations + */ +public class AnnotationAttributes { + + private boolean corbaArray; + private int[] corbaArrayLength; + + public boolean isCorbaArray() { + return corbaArray; + } + + public void setCorbaArray(boolean isCorbaArray) { + this.corbaArray = isCorbaArray; + } + + public int[] getCorbaArrayLength() { + return corbaArrayLength; + } + + public void setCorbaArrayLength(int[] corbaArrayLength) { + this.corbaArrayLength = corbaArrayLength; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/NodeType.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/NodeType.java new file mode 100644 index 0000000000..706a44406b --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/NodeType.java @@ -0,0 +1,28 @@ +/* + * 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.types; + +/** + * @version $Rev$ $Date$ + * Types of CORBA objects. + */ +public enum NodeType { + primitive, struct, union, array, sequence, reference, idl_enum, exception +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTree.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTree.java new file mode 100644 index 0000000000..d4207ab735 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTree.java @@ -0,0 +1,50 @@ +/* + * 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.types; + +/** + * @version $Rev$ $Date$ + * Helper tree for Java object hierarchy. It's closer to CORBA types + * structure than plain Java hierarchy - it helps reading and writing + * complex structures. + */ +public class TypeTree { + + private TypeTreeNode rootNode; + + /** + * Returns root node. + * + * @return root of type tree + */ + public TypeTreeNode getRootNode() { + return rootNode; + } + + /** + * Sets root of the type tree. + * + * @param rootNode root node. + */ + public void setRootNode(TypeTreeNode rootNode) { + this.rootNode = rootNode; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTreeCreator.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTreeCreator.java new file mode 100644 index 0000000000..1ba4002303 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTreeCreator.java @@ -0,0 +1,497 @@ +/* + * 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.types; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.sca.binding.corba.provider.exceptions.RequestConfigurationException; +import org.apache.tuscany.sca.binding.corba.provider.meta.CorbaArray; +import org.apache.tuscany.sca.binding.corba.provider.meta.CorbaUnionElement; +import org.apache.tuscany.sca.binding.corba.provider.meta.CorbaUnionElementType; + +/** + * @version $Rev$ $Date$ + * Creator of types tree. + */ +public class TypeTreeCreator { + + /** + * Helps to determine if type is a primitive. + */ + private static List<Class<?>> primitives = new ArrayList<Class<?>>(); + + static { + primitives.add(boolean.class); + primitives.add(byte.class); + primitives.add(short.class); + primitives.add(int.class); + primitives.add(long.class); + primitives.add(double.class); + primitives.add(float.class); + primitives.add(char.class); + primitives.add(String.class); + primitives.add(Boolean.class); + primitives.add(Byte.class); + primitives.add(Short.class); + primitives.add(Integer.class); + primitives.add(Long.class); + primitives.add(Double.class); + primitives.add(Float.class); + primitives.add(Character.class); + } + + /** + * Creates class for given string argument. + * + * @param name name of type + * @return type + */ + private static Class<?> createClassFromString(String name) { + Class<?> result = null; + try { + if (name.length() == 1) { + // primitives + switch (name.charAt(0)) { + case 'Z': + result = boolean.class; + break; + case 'C': + result = char.class; + break; + case 'B': + result = byte.class; + break; + case 'S': + result = short.class; + break; + case 'I': + result = int.class; + break; + case 'J': + result = long.class; + break; + case 'F': + result = float.class; + break; + case 'D': + result = double.class; + break; + } + } else { + // class + name = name.substring(1, name.length() - 1); + result = Class.forName(name); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + /** + * Reduces dimension of array. + * + * @param forClass array class + * @return reduced array + */ + private static Class<?> reduceArrayDimension(Class<?> forClass) { + String name = forClass.getName(); + try { + String reduced = name.substring(1, name.length()); + if (reduced.startsWith("[")) { + // reduced class is still an array + return Class.forName(reduced); + } else { + // reduced class may be primitive or class + return createClassFromString(reduced); + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Return given array without first element + * + * @param array + * @return + */ + private static int[] removeFirstElement(int[] array) { + int[] result = new int[array.length - 1]; + System.arraycopy(array, 1, result, 0, result.length); + return result; + } + + /** + * Converts objects annotations to structure which will be used by this + * class + * + * @param notes + * @return + */ + private static AnnotationAttributes createAnnotationAttributes(Annotation[] notes) { + AnnotationAttributes attrs = new AnnotationAttributes(); + for (int i = 0; notes != null && i < notes.length; i++) { + if (notes[i].annotationType().equals(CorbaArray.class)) { + attrs.setCorbaArray(true); + attrs.setCorbaArrayLength(((CorbaArray)notes[i]).value()); + } + } + return attrs; + } + + /** + * Creates tree for given type. + * + * @param forClass + * @return type tree + */ + public static TypeTree createTypeTree(Class<?> forClass, Annotation[] notes) throws RequestConfigurationException { + TypeTree tree = new TypeTree(); + TypeTreeNode rootNode = null; + AnnotationAttributes attrs = createAnnotationAttributes(notes); + rootNode = inspectClassHierarchy(forClass, attrs, tree); + tree.setRootNode(rootNode); + return tree; + + } + + /** + * Recurrent method which builds type tree. + * + * @param forClass + * @param tree + * @return + */ + private static TypeTreeNode inspectClassHierarchy(Class<?> forClass, AnnotationAttributes attributes, TypeTree tree) + throws RequestConfigurationException { + + TypeTreeNode node = null; + node = createTypeNode(forClass, attributes); + + NodeType nodeType = node.getNodeType(); + TypeTreeNode[] children = null; + + if (nodeType.equals(NodeType.primitive)) { + // stop condition for recurrent method + } else if (nodeType.equals(NodeType.array)) { + Class<?> reduced = reduceArrayDimension(node.getJavaClass()); + children = new TypeTreeNode[1]; + int[] newLengths = removeFirstElement(attributes.getCorbaArrayLength()); + attributes.setCorbaArrayLength(newLengths); + children[0] = inspectClassHierarchy(reduced, attributes, tree); + } else if (nodeType.equals(NodeType.sequence)) { + // reducing sequence dimension + Class<?> reduced = reduceArrayDimension(node.getJavaClass()); + children = new TypeTreeNode[1]; + children[0] = inspectClassHierarchy(reduced, attributes, tree); + // System.arraycopy(src, srcPos, dest, destPos, length) + } else if (nodeType.equals(NodeType.struct) || nodeType.equals(NodeType.exception)) { + // inspect types for every structure member + Field[] fields = node.getJavaClass().getFields(); + children = new TypeTreeNode[fields.length]; + for (int i = 0; i < fields.length; i++) { + Class<?> field = fields[i].getType(); + AnnotationAttributes fAttrs = createAnnotationAttributes(fields[i].getAnnotations()); + TypeTreeNode child = inspectClassHierarchy(field, fAttrs, tree); + child.setName(fields[i].getName()); + children[i] = child; + } + } else if (nodeType.equals(NodeType.idl_enum)) { + + } else if (nodeType.equals(NodeType.union)) { + // inspect types for every structure member + Field[] fields = node.getJavaClass().getDeclaredFields(); + children = new TypeTreeNode[fields.length]; + for (int i = 0; i < fields.length; i++) { + Class<?> field = fields[i].getType(); + AnnotationAttributes fAttrs = createAnnotationAttributes(fields[i].getAnnotations()); + TypeTreeNode child = inspectClassHierarchy(field, fAttrs, tree); + child.setName(fields[i].getName()); + children[i] = child; + } + } else if (nodeType.equals(NodeType.reference)) { + // TODO: CORBA references + } + + node.setChildren(children); + return node; + } + + /** + * Creating and configuring TypeTreeNode for given class. + * + * @param forClass class + * @return node + * @throws RequestConfigurationException + */ + private static TypeTreeNode createTypeNode(Class<?> forClass, AnnotationAttributes attributes) + throws RequestConfigurationException { + TypeTreeNode node = new TypeTreeNode(); + if (forClass.isArray() && !attributes.isCorbaArray()) { + node.setNodeType(NodeType.sequence); + node.setJavaClass(forClass); + } else if (forClass.isArray() && attributes.isCorbaArray()) { + node.setNodeType(NodeType.array); + node.setJavaClass(forClass); + try { + // set the actual array size for further use by ArrayTypeHelper + node.setAttributes(attributes.getCorbaArrayLength()[0]); + } catch (ArrayIndexOutOfBoundsException e) { + RequestConfigurationException exc = + new RequestConfigurationException("Annotated array size doesn't match declared arrays size"); + throw exc; + } + } else if (primitives.contains(forClass)) { + node.setNodeType(NodeType.primitive); + node.setJavaClass(forClass); + node.setChildren(null); + } else if (forClass.isInterface()) { + node.setNodeType(NodeType.reference); + node.setJavaClass(forClass); + node.setChildren(null); + } else if (isStructType(forClass)) { + node.setNodeType(NodeType.struct); + node.setJavaClass(forClass); + } else if (isEnumType(forClass)) { + node.setNodeType(NodeType.idl_enum); + node.setJavaClass(forClass); + } else if (isUserException(forClass)) { + node.setNodeType(NodeType.exception); + node.setJavaClass(forClass); + } else if (isUnionType(forClass)) { + node.setNodeType(NodeType.union); + node.setJavaClass(forClass); + node.setAttributes(getUnionAttributes(forClass)); + } else { + RequestConfigurationException e = + new RequestConfigurationException("User defined type which cannot be handled: " + forClass + .getCanonicalName()); + throw e; + } + return node; + } + + /** + * Tells whether given class is structure + * + * @param forClass + * @return + */ + private static boolean isStructType(Class<?> forClass) { + int classMods = forClass.getModifiers(); + if (!Modifier.isFinal(classMods)) { + return false; + } + boolean areCtorsValid = false; + Class<?>[] fieldsTypes = null; + Constructor<?>[] ctors = forClass.getConstructors(); + /* + * Do we have 2 ctors and one of them is null ctor? + */ + if (ctors.length != 2) { + return false; + } + for (int i = 0; i < ctors.length; i++) { + Class<?>[] params = ctors[i].getParameterTypes(); + if (params.length == 0) { + areCtorsValid = true; + } else { + fieldsTypes = params; + } + } + if (!areCtorsValid) { + return false; + } + /* + * Are constructor args declared as class fields? + */ + Field[] fields = forClass.getFields(); + Set<Class<?>> fieldsSet = new HashSet<Class<?>>(Arrays.asList(fieldsTypes)); + for (int i = 0; i < fields.length && !fieldsSet.isEmpty(); i++) { + int mods = fields[i].getModifiers(); + if (Modifier.isPublic(mods) && !Modifier.isStatic(mods) && !Modifier.isFinal(mods)) { + fieldsSet.remove(fields[i].getType()); + } + + } + return fieldsSet.isEmpty(); + } + + /** + * Tells whether given class is enum + * + * @param forClass + * @return + */ + private static boolean isEnumType(Class<?> forClass) { + boolean isValueMethod = false; + boolean isFromIntMethod = false; + /* + * enum type should have value and from_int methods + */ + try { + Method valueMet = forClass.getMethod("value", new Class[] {}); + int modValueMet = valueMet.getModifiers(); + if (valueMet.getReturnType().equals(int.class) && Modifier.isPublic(modValueMet)) { + isValueMethod = true; + } + Method fromIntMet = forClass.getMethod("from_int", new Class[] {int.class}); + int modFromIntMet = fromIntMet.getModifiers(); + if ((fromIntMet.getReturnType().equals(forClass) && Modifier.isPublic(modFromIntMet) && Modifier + .isStatic(modFromIntMet))) { + isFromIntMethod = true; + } + } catch (NoSuchMethodException e) { + } + if (!isFromIntMethod || !isValueMethod) { + return false; + } + /* + * enum type should also contain minimum one pair of fields: EnumType + * field and int _field + */ + int enumCount = 0; + Field[] fields = forClass.getFields(); + for (int i = 0; i < fields.length; i++) { + if (fields[i].getType().equals(forClass)) { + int modifiers = fields[i].getModifiers(); + if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && Modifier.isFinal(modifiers)) { + try { + Field field = forClass.getField("_" + fields[i].getName()); + if (field.getType().equals(int.class)) { + enumCount++; + } + } catch (NoSuchFieldException e) { + } + + } + } + } + return enumCount > 0; + } + + /** + * Tells whether given class is CORBA user exception + * + * @param forClass + * @return + */ + private static boolean isUserException(Class<?> forClass) { + do { + if (forClass.equals(Exception.class)) { + return true; + } else { + forClass = forClass.getSuperclass(); + } + } while (forClass != null && !forClass.equals(Object.class)); + return false; + } + + /** + * Tells whether given class is CORBA union. This method validates usage of + * unions annotations. + * + * @param forClass + * @return + * @throws RequestConfigurationException + */ + private static boolean isUnionType(Class<?> forClass) throws RequestConfigurationException { + int classMods = forClass.getModifiers(); + if (!Modifier.isFinal(classMods)) { + return false; + } + boolean atLeastOneOption = false; + boolean discriminatorPresent = false; + for (int i = 0; i < forClass.getDeclaredFields().length; i++) { + CorbaUnionElement note = forClass.getDeclaredFields()[i].getAnnotation(CorbaUnionElement.class); + if (note != null) { + int fieldMod = forClass.getDeclaredFields()[i].getModifiers(); + if (Modifier.isPrivate(fieldMod) && !Modifier.isFinal(fieldMod) && !Modifier.isStatic(fieldMod)) { + if (note.type().equals(CorbaUnionElementType.discriminator)) { + if (discriminatorPresent) { + throw new RequestConfigurationException( + "More than one discriminators declared on: " + forClass); + } + discriminatorPresent = true; + } else { + atLeastOneOption = true; + } + } else { + throw new RequestConfigurationException( + "Annotated union field should be private, not final and no static on class: " + forClass); + } + } + } + if (atLeastOneOption && !discriminatorPresent) { + throw new RequestConfigurationException("No discriminator annotation found on: " + forClass); + } else if (!atLeastOneOption && discriminatorPresent) { + throw new RequestConfigurationException("No union option found on: " + forClass); + } else if (discriminatorPresent && atLeastOneOption) { + return true; + } else { + return false; + } + } + + /** + * Gets union attributes - discriminator field name, option fields etc. This + * method relies that previously scanned class is valid (method isUnionType) + * + * @param forClass + * @return + * @throws RequestConfigurationException + */ + private static UnionAttributes getUnionAttributes(Class<?> forClass) throws RequestConfigurationException { + UnionAttributes attributes = new UnionAttributes(); + for (int i = 0; i < forClass.getDeclaredFields().length; i++) { + CorbaUnionElement note = forClass.getDeclaredFields()[i].getAnnotation(CorbaUnionElement.class); + if (note != null) { + if (note.type().equals(CorbaUnionElementType.discriminator)) { + attributes.setDiscriminatorName(forClass.getDeclaredFields()[i].getName()); + } else if (note.type().equals(CorbaUnionElementType.defaultOption)) { + attributes.setDefaultOptionName(forClass.getDeclaredFields()[i].getName()); + } else if (note.type().equals(CorbaUnionElementType.option)) { + if (attributes.getOptionsMapping().containsKey(note.optionNumber())) { + throw new RequestConfigurationException("In " + forClass + + ": field \"" + + forClass.getDeclaredFields()[i].getName() + + "\" uses already used option id: " + + note.optionNumber()); + } else { + attributes.getOptionsMapping().put(note.optionNumber(), + forClass.getDeclaredFields()[i].getName()); + } + } + } + } + return attributes; + } +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTreeNode.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTreeNode.java new file mode 100644 index 0000000000..009eac3377 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/TypeTreeNode.java @@ -0,0 +1,75 @@ +/* + * 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.types; + +/** + * @version $Rev$ $Date$ + * Represents single tree node. + * + */ +public class TypeTreeNode { + + private NodeType nodeType; + private TypeTreeNode[] children; + private Class<?> javaClass; + private String name; + private Object attributes; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public NodeType getNodeType() { + return nodeType; + } + + public void setNodeType(NodeType nodeType) { + this.nodeType = nodeType; + } + + public TypeTreeNode[] getChildren() { + return children; + } + + public void setChildren(TypeTreeNode[] children) { + this.children = children; + } + + public Class<?> getJavaClass() { + return javaClass; + } + + public void setJavaClass(Class<?> javaClass) { + this.javaClass = javaClass; + } + + public Object getAttributes() { + return attributes; + } + + public void setAttributes(Object attributes) { + this.attributes = attributes; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/UnionAttributes.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/UnionAttributes.java new file mode 100644 index 0000000000..34bee2a0e4 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/UnionAttributes.java @@ -0,0 +1,59 @@ +/* + * 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.types; + +import java.util.HashMap; +import java.util.Map; + +/** + * @version $Rev$ $Date$ + * Stores attributes for previously scanned CORBA union type + */ +public class UnionAttributes { + + public String discriminatorName; + public String defaultOptionName; + public Map<Integer, String> optionsMapping = new HashMap<Integer, String>(); + + public String getDiscriminatorName() { + return discriminatorName; + } + + public void setDiscriminatorName(String discriminatorName) { + this.discriminatorName = discriminatorName; + } + + public String getDefaultOptionName() { + return defaultOptionName; + } + + public void setDefaultOptionName(String defaultOptionName) { + this.defaultOptionName = defaultOptionName; + } + + public Map<Integer, String> getOptionsMapping() { + return optionsMapping; + } + + public void setOptionsMapping(Map<Integer, String> optionsMapping) { + this.optionsMapping = optionsMapping; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ArrayTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ArrayTypeHelper.java new file mode 100644 index 0000000000..35a1e539d9 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ArrayTypeHelper.java @@ -0,0 +1,53 @@ +/* + * 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.types.util; + +import java.lang.reflect.Array; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class ArrayTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + Object array = null; + try { + int size = (Integer)node.getAttributes(); + array = Array.newInstance(node.getChildren()[0].getJavaClass(), size); + for (int i = 0; i < size; i++) { + Array.set(array, i, TypeHelpersProxy.read(node.getChildren()[0], is)); + } + } catch (Exception e) { + e.printStackTrace(); + } + return array; + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + for (int i = 0; i < (Integer)node.getAttributes(); i++) { + TypeHelpersProxy.write(node.getChildren()[0], os, Array.get(data, i)); + } + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/BooleanTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/BooleanTypeHelper.java new file mode 100644 index 0000000000..bbc2012a38 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/BooleanTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class BooleanTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_boolean(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_boolean((Boolean)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ByteTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ByteTypeHelper.java new file mode 100644 index 0000000000..761cc5d62c --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ByteTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class ByteTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_octet(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_octet((Byte)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/CharTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/CharTypeHelper.java new file mode 100644 index 0000000000..b2d2afd011 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/CharTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class CharTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_char(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_char((Character)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/DoubleTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/DoubleTypeHelper.java new file mode 100644 index 0000000000..f667123bb7 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/DoubleTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class DoubleTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_double(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_double((Double)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/EnumTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/EnumTypeHelper.java new file mode 100644 index 0000000000..ae52bd6bbf --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/EnumTypeHelper.java @@ -0,0 +1,59 @@ +/* + * 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.types.util; + +import java.lang.reflect.Method; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class EnumTypeHelper implements TypeHelper { + + private static final Logger logger = Logger.getLogger(EnumTypeHelper.class.getName()); + + public Object read(TypeTreeNode node, InputStream is) { + int value = is.read_long(); + Object result = null; + try { + Method method = node.getJavaClass().getMethod("from_int", new Class[] {int.class}); + result = method.invoke(null, new Object[] {value}); + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during reading CORBA enum data", e); + e.printStackTrace(); + } + return result; + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + int value = 0; + try { + Method method = data.getClass().getMethod("value", new Class[] {}); + value = (Integer)method.invoke(data, new Object[] {}); + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during writing CORBA enum data", e); + } + os.write_long(value); + } +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/FloatTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/FloatTypeHelper.java new file mode 100644 index 0000000000..7c39725012 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/FloatTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class FloatTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_float(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_float((Float)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/IntTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/IntTypeHelper.java new file mode 100644 index 0000000000..e903b59e50 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/IntTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class IntTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_long(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_long((Integer)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/LongTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/LongTypeHelper.java new file mode 100644 index 0000000000..79d3c0cbc8 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/LongTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class LongTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_longlong(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_longlong((Long)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ReferenceTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ReferenceTypeHelper.java new file mode 100644 index 0000000000..c89a25401d --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ReferenceTypeHelper.java @@ -0,0 +1,42 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.reference.InterfaceInstanceCreator; +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.Object; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class ReferenceTypeHelper implements TypeHelper { + + public java.lang.Object read(TypeTreeNode node, InputStream is) { + Object reference = is.read_Object(); + return (java.lang.Object)InterfaceInstanceCreator.createInstance(reference, node.getJavaClass()); + } + + public void write(TypeTreeNode node, OutputStream os, java.lang.Object data) { + os.write_Object((Object)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/SequenceTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/SequenceTypeHelper.java new file mode 100644 index 0000000000..911c787b11 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/SequenceTypeHelper.java @@ -0,0 +1,70 @@ +/* + * 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.types.util; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class SequenceTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + Object sequence = null; + try { + int size = is.read_long(); + sequence = Array.newInstance(node.getChildren()[0].getJavaClass(), size); + for (int i = 0; i < size; i++) { + Array.set(sequence, i, TypeHelpersProxy.read(node.getChildren()[0], is)); + } + } catch (Exception e) { + e.printStackTrace(); + } + return sequence; + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + int sum = 0; + // determine length of array + List<Object> array = new ArrayList<Object>(); + while (true) { + try { + array.add(Array.get(data, sum)); + sum++; + } catch (ArrayIndexOutOfBoundsException e) { + break; + } + } + os.write_long(sum); + Iterator<Object> iter = array.iterator(); + while (iter.hasNext()) { + Object elem = iter.next(); + TypeHelpersProxy.write(node.getChildren()[0], os, elem); + } + + } +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ShortTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ShortTypeHelper.java new file mode 100644 index 0000000000..f4cdabc8e2 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/ShortTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class ShortTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_short(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_short((Short)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/StringTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/StringTypeHelper.java new file mode 100644 index 0000000000..5a4fcba221 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/StringTypeHelper.java @@ -0,0 +1,39 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class StringTypeHelper implements TypeHelper { + + public Object read(TypeTreeNode node, InputStream is) { + return is.read_string(); + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + os.write_string((String)data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/StructTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/StructTypeHelper.java new file mode 100644 index 0000000000..1fc729b926 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/StructTypeHelper.java @@ -0,0 +1,69 @@ +/* + * 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.types.util; + +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class StructTypeHelper implements TypeHelper { + + private static final Logger logger = Logger.getLogger(StructTypeHelper.class.getName()); + + public Object read(TypeTreeNode node, InputStream is) { + TypeTreeNode[] children = node.getChildren(); + Object result = null; + if (children != null) { + try { + result = node.getJavaClass().newInstance(); + for (int i = 0; i < children.length; i++) { + Object childResult = TypeHelpersProxy.read(children[i], is); + Field childField = result.getClass().getField(children[i].getName()); + childField.set(result, childResult); + } + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during reading CORBA struct data", e); + } + } + return result; + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + TypeTreeNode[] children = node.getChildren(); + if (children != null) { + try { + for (int i = 0; i < children.length; i++) { + Field childField = node.getJavaClass().getField(children[i].getName()); + TypeHelpersProxy.write(children[i], os, childField.get(data)); + } + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during writing CORBA struct data", e); + } + } + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/TypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/TypeHelper.java new file mode 100644 index 0000000000..0f1f973f49 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/TypeHelper.java @@ -0,0 +1,47 @@ +/* + * 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.types.util; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public interface TypeHelper { + + /** + * Reads CORBA object + * @param node + * @param is + * @return + */ + Object read(TypeTreeNode node, InputStream is); + + /** + * Writes CORBA object + * @param node + * @param os + * @param data + */ + void write(TypeTreeNode node, OutputStream os, Object data); + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/TypeHelpersProxy.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/TypeHelpersProxy.java new file mode 100644 index 0000000000..ded82bf12e --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/TypeHelpersProxy.java @@ -0,0 +1,119 @@ +/* + * 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.types.util; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.binding.corba.provider.types.NodeType; +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + * Proxies getType(), write(), read() methods to appropriate TypeHelper implementation. + */ +public class TypeHelpersProxy { + + /** + * Maps primitive types to its TypeHelper implementations + */ + private static Map<Class<?>, TypeHelper> primitiveTypes = null; + + /** + * Maps other types to its TypeHelper implementations + */ + private static Map<NodeType, TypeHelper> complexTypes = null; + + static { + // initiate type helpers + primitiveTypes = new HashMap<Class<?>, TypeHelper>(); + complexTypes = new HashMap<NodeType, TypeHelper>(); + + primitiveTypes.put(boolean.class, new BooleanTypeHelper()); + primitiveTypes.put(char.class, new CharTypeHelper()); + primitiveTypes.put(byte.class, new ByteTypeHelper()); + primitiveTypes.put(short.class, new ShortTypeHelper()); + primitiveTypes.put(int.class, new IntTypeHelper()); + primitiveTypes.put(long.class, new LongTypeHelper()); + primitiveTypes.put(float.class, new FloatTypeHelper()); + primitiveTypes.put(double.class, new DoubleTypeHelper()); + primitiveTypes.put(String.class, new StringTypeHelper()); + primitiveTypes.put(Boolean.class, primitiveTypes.get(boolean.class)); + primitiveTypes.put(Character.class, primitiveTypes.get(char.class)); + primitiveTypes.put(Byte.class, primitiveTypes.get(byte.class)); + primitiveTypes.put(Short.class, primitiveTypes.get(short.class)); + primitiveTypes.put(Integer.class, primitiveTypes.get(int.class)); + primitiveTypes.put(Long.class, primitiveTypes.get(long.class)); + primitiveTypes.put(Float.class, primitiveTypes.get(float.class)); + primitiveTypes.put(Double.class, primitiveTypes.get(double.class)); + primitiveTypes.put(String.class, primitiveTypes.get(String.class)); + complexTypes.put(NodeType.array, new ArrayTypeHelper()); + complexTypes.put(NodeType.struct, new StructTypeHelper()); + complexTypes.put(NodeType.reference, new ReferenceTypeHelper()); + complexTypes.put(NodeType.sequence, new SequenceTypeHelper()); + complexTypes.put(NodeType.idl_enum, new EnumTypeHelper()); + complexTypes.put(NodeType.exception, new StructTypeHelper()); + complexTypes.put(NodeType.union, new UnionTypeHelper()); + } + + /** + * Gets type helper basing on given type + * + * @param node + * @return + */ + private static TypeHelper getTypeHelper(TypeTreeNode node) { + TypeHelper typeHelper = null; + NodeType type = node.getNodeType(); + if (type.equals(NodeType.primitive)) { + typeHelper = primitiveTypes.get(node.getJavaClass()); + } else { + typeHelper = complexTypes.get(type); + } + return typeHelper; + } + + /** + * Proxies read method invocation to appropriate TypeHelper implementation. + * + * @param node + * @param is + * @return + */ + public static final Object read(TypeTreeNode node, InputStream is) { + TypeHelper helper = getTypeHelper(node); + return helper.read(node, is); + } + + /** + * Proxies write method invocation to appropriate TypeHelper implementation. + * + * @param node + * @param os + * @param data + */ + public static final void write(TypeTreeNode node, OutputStream os, Object data) { + TypeHelper helper = getTypeHelper(node); + helper.write(node, os, data); + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/UnionTypeHelper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/UnionTypeHelper.java new file mode 100644 index 0000000000..df2e833fcd --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/UnionTypeHelper.java @@ -0,0 +1,92 @@ +/* + * 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.types.util; + +import java.lang.reflect.Field; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.binding.corba.provider.types.TypeTreeNode; +import org.apache.tuscany.sca.binding.corba.provider.types.UnionAttributes; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * @version $Rev$ $Date$ + */ +public class UnionTypeHelper implements TypeHelper { + + private static final Logger logger = Logger.getLogger(UnionTypeHelper.class.getName()); + + public Object read(TypeTreeNode node, InputStream is) { + Object result = null; + try { + int discriminator = is.read_long(); + UnionAttributes attrs = (UnionAttributes)node.getAttributes(); + String childName = attrs.getOptionsMapping().get(discriminator); + if (childName == null) { + // get default if option numbers field not found + childName = attrs.getDefaultOptionName(); + } + result = node.getJavaClass().newInstance(); + Field discField = result.getClass().getDeclaredField(attrs.getDiscriminatorName()); + discField.setAccessible(true); + discField.set(result, discriminator); + for (int i = 0; i < node.getChildren().length; i++) { + if (node.getChildren()[i].getName().equals(childName)) { + Object unionValue = TypeHelpersProxy.read(node.getChildren()[i], is); + Field childField = result.getClass().getDeclaredField(childName); + childField.setAccessible(true); + childField.set(result, unionValue); + break; + } + } + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during reading CORBA union data", e); + } + return result; + } + + public void write(TypeTreeNode node, OutputStream os, Object data) { + try { + UnionAttributes attrs = (UnionAttributes)node.getAttributes(); + Field discriminatorField = data.getClass().getDeclaredField(attrs.getDiscriminatorName()); + discriminatorField.setAccessible(true); + int discriminator = discriminatorField.getInt(data); + os.write_long(discriminator); + String childName = attrs.getOptionsMapping().get(discriminator); + if (childName == null) { + // get default if option numbers field not found + childName = attrs.getDefaultOptionName(); + } + for (int i = 0; i < node.getChildren().length; i++) { + if (node.getChildren()[i].getName().equals(childName)) { + Field childField = data.getClass().getDeclaredField(childName); + childField.setAccessible(true); + TypeHelpersProxy.write(node.getChildren()[i], os, childField.get(data)); + break; + } + } + } catch (Exception e) { + logger.log(Level.WARNING, "Exception during writing CORBA union data", e); + } + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/Utils.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/Utils.java new file mode 100644 index 0000000000..7ccd70f69e --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/types/util/Utils.java @@ -0,0 +1,40 @@ +/* + * 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.types.util; + +/** + * @version $Rev$ $Date$ + * Class for type utilities + */ +public class Utils { + + /** + * Creates CORBA id for Java class + * @param forClass + * @return + */ + public static String getTypeId(Class<?> forClass) { + String result = forClass.getName().replace('.', '/'); + result = result.replaceAll("Package", ""); + result = "IDL:" + result + ":1.0"; + return result; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/MethodFinder.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/MethodFinder.java new file mode 100644 index 0000000000..f9facac0cc --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/MethodFinder.java @@ -0,0 +1,97 @@ +/* + * 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.util; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * @version $Rev$ $Date$ + * Utility for finding method in given class. + */ +public class MethodFinder { + + private static Map<Class<?>, Class<?>> boxingMapping; + + static { + boxingMapping = new HashMap<Class<?>, Class<?>>(); + boxingMapping.put(boolean.class, Boolean.class); + boxingMapping.put(byte.class, Byte.class); + boxingMapping.put(short.class, Short.class); + boxingMapping.put(char.class, Character.class); + boxingMapping.put(int.class, Integer.class); + boxingMapping.put(long.class, Long.class); + boxingMapping.put(float.class, Float.class); + boxingMapping.put(double.class, Double.class); + } + + /** + * Converts primitive class to its object equivalent. + * + * @param parameter class to convert + * @return object equivalent for primitive type. If parameter wasn't + * primitive then returns parameter. + */ + private static Class<?> normalizePrimitive(Class<?> parameter) { + Class<?> result = boxingMapping.get(parameter); + if (result != null) { + return result; + } else { + // not a primitive - no need to normalize + return parameter; + } + } + + /** + * Finds appropriate method. This method ignores difference between + * primitive types and theirs object equivalents. Ie. if we want to find + * method "get" in java.util.List with only one parameter, which type is + * Integer then we'll obtain method get(int). + * + * @param forClass class which possibly contains desired method + * @param methodName desired methods name + * @param parameterTypes desired methods parameter types + * @return desired method, if no method was found then null will be returned + */ + public static Method findMethod(Class<?> forClass, String methodName, Class<?>[] parameterTypes) { + Method[] methods = forClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(methodName)) { + Class<?>[] methodPTypes = methods[i].getParameterTypes(); + if (methodPTypes.length == parameterTypes.length) { + boolean parameterMatch = true; + for (int j = 0; j < methodPTypes.length; j++) { + Class<?> nMethodPType = normalizePrimitive(methodPTypes[j]); + Class<?> nParameterType = normalizePrimitive(parameterTypes[j]); + if (!nMethodPType.equals(nParameterType)) { + parameterMatch = false; + break; + } + } + if (parameterMatch) { + return methods[i]; + } + } + } + } + return null; + } +} diff --git a/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/OperationMapper.java b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/OperationMapper.java new file mode 100644 index 0000000000..414e50abf4 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/OperationMapper.java @@ -0,0 +1,578 @@ +/* + * 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.util; + +import java.lang.reflect.Method; +import java.rmi.RemoteException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.omg.CORBA.portable.IDLEntity; + +/** + * @version $Rev$ $Date$ + */ +public final class OperationMapper { + + private static Set<Class<?>> getAllInterfaces(Class<?> intfClass) { + Set<Class<?>> allInterfaces = new LinkedHashSet<Class<?>>(); + + LinkedList<Class<?>> stack = new LinkedList<Class<?>>(); + stack.addFirst(intfClass); + + while (!stack.isEmpty()) { + Class<?> intf = stack.removeFirst(); + allInterfaces.add(intf); + for (Class<?> i : intf.getInterfaces()) { + stack.add(0, i); + } + } + + return allInterfaces; + } + + /** + * Maps Java methods to operation names + * @param intfClass + * @return + */ + @SuppressWarnings("unchecked") + public static Map<Method, String> mapMethodToOperationName(Class<?> intfClass) { + return iiopMap(intfClass, false); + } + + /** + * Maps operation names to Java methods + * @param intfClass + * @return + */ + @SuppressWarnings("unchecked") + public static Map<String, Method> mapOperationNameToMethod(Class<?> intfClass) { + return iiopMap(intfClass, true); + } + + @SuppressWarnings("unchecked") + private static Map iiopMap(Class<?> intfClass, boolean operationToMethod) { + Method[] methods = getAllMethods(intfClass); + + // find every valid getter + Map<Method, String> getterByMethod = new HashMap<Method, String>(methods.length); + Map<String, Method> getterByName = new HashMap<String, Method>(methods.length); + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + String methodName = method.getName(); + + // no arguments allowed + if (method.getParameterTypes().length != 0) { + continue; + } + + // must start with get or is + String verb; + if (methodName.startsWith("get") && methodName.length() > 3 && method.getReturnType() != void.class) { + verb = "get"; + } else if (methodName.startsWith("is") && methodName.length() > 2 && method.getReturnType() == boolean.class) { + verb = "is"; + } else { + continue; + } + + // must only throw Remote or Runtime Exceptions + boolean exceptionsValid = true; + Class[] exceptionTypes = method.getExceptionTypes(); + for (int j = 0; j < exceptionTypes.length; j++) { + Class<?> exceptionType = exceptionTypes[j]; + if (!RemoteException.class.isAssignableFrom(exceptionType) && + !RuntimeException.class.isAssignableFrom(exceptionType) && + !Error.class.isAssignableFrom(exceptionType)) { + exceptionsValid = false; + break; + } + } + if (!exceptionsValid) { + continue; + } + + String propertyName; + if (methodName.length() > verb.length() + 1 && Character.isUpperCase(methodName.charAt(verb.length() + 1))) { + propertyName = methodName.substring(verb.length()); + } else { + propertyName = Character.toLowerCase(methodName.charAt(verb.length())) + methodName.substring(verb.length() + 1); + } + getterByMethod.put(method, propertyName); + getterByName.put(propertyName, method); + } + + Map<Method, String> setterByMethod = new HashMap<Method, String>(methods.length); + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + String methodName = method.getName(); + + // must have exactally one arg + if (method.getParameterTypes().length != 1) { + continue; + } + + // must return non void + if (method.getReturnType() != void.class) { + continue; + } + + // must start with set + if (!methodName.startsWith("set") || methodName.length() <= 3) { + continue; + } + + // must only throw Remote or Runtime Exceptions + boolean exceptionsValid = true; + Class<?>[] exceptionTypes = method.getExceptionTypes(); + for (int j = 0; j < exceptionTypes.length; j++) { + Class<?> exceptionType = exceptionTypes[j]; + if (!RemoteException.class.isAssignableFrom(exceptionType) && + !RuntimeException.class.isAssignableFrom(exceptionType) && + !Error.class.isAssignableFrom(exceptionType)) { + exceptionsValid = false; + break; + } + } + if (!exceptionsValid) { + continue; + } + + String propertyName; + if (methodName.length() > 4 && Character.isUpperCase(methodName.charAt(4))) { + propertyName = methodName.substring(3); + } else { + propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + } + + // must have a matching getter + Method getter = (Method) getterByName.get(propertyName); + if (getter == null) { + continue; + } + + // setter property must match getter return value + if (!method.getParameterTypes()[0].equals(getter.getReturnType())) { + continue; + } + setterByMethod.put(method, propertyName); + } + + // index the methods by name... used to determine which methods are overloaded + HashMap<String, List<Method>> overloadedMethods = new HashMap<String, List<Method>>(methods.length); + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) { + continue; + } + String methodName = method.getName(); + List<Method> methodList = overloadedMethods.get(methodName); + if (methodList == null) { + methodList = new LinkedList<Method>(); + overloadedMethods.put(methodName, methodList); + } + methodList.add(method); + } + + // index the methods by lower case name... used to determine which methods differ only by case + Map<String, Set<String>> caseCollisionMethods = new HashMap<String, Set<String>>(methods.length); + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) { + continue; + } + String lowerCaseMethodName = method.getName().toLowerCase(); + Set<String> methodSet = caseCollisionMethods.get(lowerCaseMethodName); + if (methodSet == null) { + methodSet = new HashSet<String>(); + caseCollisionMethods.put(lowerCaseMethodName, methodSet); + } + methodSet.add(method.getName()); + } + + String className = getClassName(intfClass); + Map iiopMap = new HashMap(methods.length); + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + + String iiopName = (String) getterByMethod.get(method); + if (iiopName != null) { + // if we have a leading underscore prepend with J + if (iiopName.charAt(0) == '_') { + iiopName = "J_get_" + iiopName.substring(1); + } else { + iiopName = "_get_" + iiopName; + } + } else { + iiopName = (String) setterByMethod.get(method); + if (iiopName != null) { + // if we have a leading underscore prepend with J + if (iiopName.charAt(0) == '_') { + iiopName = "J_set_" + iiopName.substring(1); + } else { + iiopName = "_set_" + iiopName; + } + } else { + iiopName = method.getName(); + + // if we have a leading underscore prepend with J + if (iiopName.charAt(0) == '_') { + iiopName = "J" + iiopName; + } + } + } + + // if this name only differs by case add the case index to the end + Set<String> caseCollisions = caseCollisionMethods.get(method.getName().toLowerCase()); + if (caseCollisions != null && caseCollisions.size() > 1) { + iiopName += upperCaseIndexString(iiopName); + } + + // if this is an overloaded method append the parameter string + List<Method> overloads = overloadedMethods.get(method.getName()); + if (overloads != null && overloads.size() > 1) { + iiopName += buildOverloadParameterString(method.getParameterTypes()); + } + + // if we have a leading underscore prepend with J + iiopName = replace(iiopName, '$', "U0024"); + + // if we have matched a keyword prepend with an underscore + if (keywords.contains(iiopName.toLowerCase())) { + iiopName = "_" + iiopName; + } + + // if the name is the same as the class name, append an underscore + if (iiopName.equalsIgnoreCase(className)) { + iiopName += "_"; + } + + if (operationToMethod) { + iiopMap.put(iiopName, method); + } else { + iiopMap.put(method, iiopName); + } + } + + return iiopMap; + } + + private static Method[] getAllMethods(Class<?> intfClass) { + List<Method> methods = new LinkedList<Method>(); + for (Iterator<Class<?>> iterator = getAllInterfaces(intfClass).iterator(); iterator.hasNext();) { + Class<?> intf = iterator.next(); + methods.addAll(Arrays.asList(intf.getDeclaredMethods())); + } + + return (Method[]) methods.toArray(new Method[methods.size()]); + } + + /** + * Return the a string containing an underscore '_' index of each uppercase + * character in the IIOP name. This is used for distinction of names that + * only differ by case, since CORBA does not support case sensitive names. + */ + private static String upperCaseIndexString(String iiopName) { + StringBuffer stringBuffer = new StringBuffer(); + for (int i = 0; i < iiopName.length(); i++) { + char c = iiopName.charAt(i); + if (Character.isUpperCase(c)) { + stringBuffer.append('_').append(i); + } + } + return stringBuffer.toString(); + } + + /** + * Replaces any occurances of the specified "oldChar" with the new string. + * This is used to replace occurances if '$' in CORBA names since '$' is a + * special character + */ + private static String replace(String source, char oldChar, String newString) { + StringBuffer stringBuffer = new StringBuffer(source.length()); + for (int i = 0; i < source.length(); i++) { + char c = source.charAt(i); + if (c == oldChar) { + stringBuffer.append(newString); + } else { + stringBuffer.append(c); + } + } + return stringBuffer.toString(); + } + + /** + * Return the a string containing a double underscore '__' list of parameter + * types encoded using the Java to IDL rules. This is used for distinction + * of methods that only differ by parameter lists. + */ + private static String buildOverloadParameterString(Class<?>[] parameterTypes) { + String name = ""; + if (parameterTypes.length == 0) { + name += "__"; + } else { + for (int i = 0; i < parameterTypes.length; i++) { + Class<?> parameterType = parameterTypes[i]; + name += buildOverloadParameterString(parameterType); + } + } + return name.replace('.', '_'); + } + + /** + * Returns a single parameter type encoded using the Java to IDL rules. + */ + private static String buildOverloadParameterString(Class<?> parameterType) { + String name = "_"; + + int arrayDimensions = 0; + while (parameterType.isArray()) { + arrayDimensions++; + parameterType = parameterType.getComponentType(); + } + + // arrays start with org_omg_boxedRMI_ + if (arrayDimensions > 0) { + name += "_org_omg_boxedRMI"; + } + + // IDLEntity types must be prefixed with org_omg_boxedIDL_ + if (IDLEntity.class.isAssignableFrom(parameterType)) { + name += "_org_omg_boxedIDL"; + } + + // add package... some types have special mappings in corba + String packageName = (String)specialTypePackages.get(parameterType.getName()); + if (packageName == null) { + packageName = getPackageName(parameterType.getName()); + } + if (packageName.length() > 0) { + name += "_" + packageName; + } + + // arrays now contain a dimension indicator + if (arrayDimensions > 0) { + name += "_" + "seq" + arrayDimensions; + } + + // add the class name + String className = (String)specialTypeNames.get(parameterType.getName()); + if (className == null) { + className = buildClassName(parameterType); + } + name += "_" + className; + + return name; + } + + /** + * Returns a string containing an encoded class name. + */ + private static String buildClassName(Class<?> type) { + if (type.isArray()) { + throw new IllegalArgumentException("type is an array: " + type); + } + + // get the classname + String typeName = type.getName(); + int endIndex = typeName.lastIndexOf('.'); + if (endIndex < 0) { + return typeName; + } + StringBuffer className = new StringBuffer(typeName.substring(endIndex + 1)); + + // for innerclasses replace the $ separator with two underscores + // we can't just blindly replace all $ characters since class names can + // contain the $ character + if (type.getDeclaringClass() != null) { + String declaringClassName = getClassName(type.getDeclaringClass()); + assert className.toString().startsWith(declaringClassName + "$"); + className.replace(declaringClassName.length(), declaringClassName.length() + 1, "__"); + } + + // if we have a leading underscore prepend with J + if (className.charAt(0) == '_') { + className.insert(0, "J"); + } + return className.toString(); + } + + private static String getClassName(Class<?> type) { + if (type.isArray()) { + throw new IllegalArgumentException("type is an array: " + type); + } + + // get the classname + String typeName = type.getName(); + int endIndex = typeName.lastIndexOf('.'); + if (endIndex < 0) { + return typeName; + } + return typeName.substring(endIndex + 1); + } + + private static String getPackageName(String interfaceName) { + int endIndex = interfaceName.lastIndexOf('.'); + if (endIndex < 0) { + return ""; + } + return interfaceName.substring(0, endIndex); + } + + private static final Map<String, String> specialTypeNames; + private static final Map<String, String> specialTypePackages; + private static final Set<String> keywords; + + static { + specialTypeNames = new HashMap<String, String>(); + specialTypeNames.put("boolean", "boolean"); + specialTypeNames.put("char", "wchar"); + specialTypeNames.put("byte", "octet"); + specialTypeNames.put("short", "short"); + specialTypeNames.put("int", "long"); + specialTypeNames.put("long", "long_long"); + specialTypeNames.put("float", "float"); + specialTypeNames.put("double", "double"); + specialTypeNames.put("java.lang.Class", "ClassDesc"); + specialTypeNames.put("java.lang.String", "WStringValue"); + specialTypeNames.put("org.omg.CORBA.Object", "Object"); + + specialTypePackages = new HashMap<String, String>(); + specialTypePackages.put("boolean", ""); + specialTypePackages.put("char", ""); + specialTypePackages.put("byte", ""); + specialTypePackages.put("short", ""); + specialTypePackages.put("int", ""); + specialTypePackages.put("long", ""); + specialTypePackages.put("float", ""); + specialTypePackages.put("double", ""); + specialTypePackages.put("java.lang.Class", "javax.rmi.CORBA"); + specialTypePackages.put("java.lang.String", "CORBA"); + specialTypePackages.put("org.omg.CORBA.Object", ""); + + keywords = new HashSet<String>(); + keywords.add("abstract"); + keywords.add("any"); + keywords.add("attribute"); + keywords.add("boolean"); + keywords.add("case"); + keywords.add("char"); + keywords.add("const"); + keywords.add("context"); + keywords.add("custom"); + keywords.add("default"); + keywords.add("double"); + keywords.add("enum"); + keywords.add("exception"); + keywords.add("factory"); + keywords.add("false"); + keywords.add("fixed"); + keywords.add("float"); + keywords.add("in"); + keywords.add("inout"); + keywords.add("interface"); + keywords.add("long"); + keywords.add("module"); + keywords.add("native"); + keywords.add("object"); + keywords.add("octet"); + keywords.add("oneway"); + keywords.add("out"); + keywords.add("private"); + keywords.add("public"); + keywords.add("raises"); + keywords.add("readonly"); + keywords.add("sequence"); + keywords.add("short"); + keywords.add("string"); + keywords.add("struct"); + keywords.add("supports"); + keywords.add("switch"); + keywords.add("true"); + keywords.add("truncatable"); + keywords.add("typedef"); + keywords.add("union"); + keywords.add("unsigned"); + keywords.add("valuebase"); + keywords.add("valuetype"); + keywords.add("void"); + keywords.add("wchar"); + keywords.add("wstring"); + } + + @SuppressWarnings("unchecked") + public static Map<Operation, Method> mapOperationToMethod(List<Operation> operations, Class<?> forClass) { + return (Map<Operation, Method>)createMethod2OperationMapping(operations, forClass, false); + } + + @SuppressWarnings("unchecked") + public static Map<Method, Operation> mapMethodToOperation(List<Operation> operations, Class<?> forClass) { + return (Map<Method, Operation>)createMethod2OperationMapping(operations, forClass, true); + } + + /** + * Maps Java methods to Tuscany operations + */ + @SuppressWarnings("unchecked") + private static Map createMethod2OperationMapping(List<Operation> operations, Class<?> forClass, boolean method2operation) { + // for every operation find all methods with the same name, then + // compare operations and methods parameters + Map mapping = new HashMap(); + for (Operation operation : operations) { + List<DataType> inputTypes = operation.getInputType().getLogical(); + Method[] methods = forClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(operation.getName()) && inputTypes.size() == methods[i] + .getParameterTypes().length) { + Class<?>[] parameterTypes = methods[i].getParameterTypes(); + int j = 0; + boolean parameterMatch = true; + for (DataType dataType : inputTypes) { + if (!dataType.getPhysical().equals(parameterTypes[j])) { + parameterMatch = false; + break; + } + j++; + } + if (parameterMatch) { + // match found + if (method2operation) { + mapping.put(methods[i], operation); + } else { + mapping.put(operation, methods[i]); + } + break; + } + } + } + } + return mapping; + } + +} |