/* * 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.implementation.java.introspect.impl; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.logging.Logger; import org.apache.tuscany.sca.assembly.AssemblyFactory; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.implementation.java.IntrospectionException; import org.apache.tuscany.sca.implementation.java.JavaImplementation; import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl; import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; /** * Processes an {@link org.osoa.sca.annotations.Service} annotation and updates * the component type with corresponding {@link Service}s. Also processes * related {@link org.osoa.sca.annotations.Callback} annotations. * * @version $$ */ public class ConsumerProcessor extends BaseJavaClassVisitor { @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(ConsumerProcessor.class.getName()); private JavaInterfaceFactory javaFactory; public ConsumerProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) { super(assemblyFactory); this.javaFactory = javaFactory; } @Override public void visitMethod(Method method, JavaImplementation type) throws IntrospectionException { org.osoa.sca.annotations.Consumer annotation = method.getAnnotation(org.osoa.sca.annotations.Consumer.class); if (annotation == null) { return; } if(Modifier.isPrivate(method.getModifiers())) { throw new IllegalConsumerException("Illegal annotation @Consumer found on "+method, method); } if (method.getParameterTypes().length != 1) { throw new IllegalConsumerException("Consumer must have one parameter", method); } JavaElementImpl element = new JavaElementImpl(method.getDeclaringClass()); try { createConsumer(type, element, annotation.name(), method); } catch (InvalidInterfaceException e) { throw new IntrospectionException(e); } } /** * Creates or updates a Consumer * @param type - the JavaImplementation to which the consumer applies * @param element - the Java class implementing the consumer * @param consumerName - the Name of the consumer * @param operationName - the Name of the operation (ie Method) annotated with @Consumer * @throws IllegalConsumerException */ private void createConsumer(JavaImplementation type, JavaElementImpl element, String consumerName, Method method ) throws IllegalConsumerException, InvalidInterfaceException { // First, see if the Consumer already exists org.apache.tuscany.sca.assembly.Consumer consumer = findConsumerByName( type, consumerName ); if( consumer == null ) { // Create the consumer object and add it to the JavaImplementation Class consumerClass = element.getType(); consumer = assemblyFactory.createConsumer(); JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract(); consumer.setInterfaceContract(interfaceContract); consumer.setName(consumerName); JavaInterface consumerInterface = javaFactory.createJavaInterface(); consumerInterface.setRemotable(true); javaFactory.createJavaInterface(consumerInterface, consumerClass); consumer.getInterfaceContract().setInterface(consumerInterface); type.getConsumers().add(consumer); } // end if // Add the operation to the consumer consumer.addOperation(method.getName(), getOperationEventTypes(method) ); } // end method createConsumer private static String getOperationEventTypes( Method method ) { // 1) If the method is annotated with @EventTypes, extract the supported event types from the annotation org.osoa.sca.annotations.EventTypes annotation = method.getAnnotation(org.osoa.sca.annotations.EventTypes.class); if (annotation != null) { return annotation.value(); } // end if // 2) If the method has a parameter that is NOT java.lang.Object, return its event type or its base Java type Class parameter = method.getParameterTypes()[0]; String className = parameter.getCanonicalName(); if( !className.equals("java.lang.Object")) { org.osoa.sca.annotations.EventType eventType = parameter.getAnnotation(org.osoa.sca.annotations.EventType.class); if (eventType != null) { return eventType.name(); } else { return className; }// end if } // end if // 3) Else, return "null" meaning that the method supports "any event type" return null; } // end getOperationEventTypes /** * Finds a Consumer within a Java implementation by the name of the consumer * @param impl - the Java implementation * @param name - the consumer name * @return - the Consumer with the specified name, or null if it does not exist */ private static org.apache.tuscany.sca.assembly.Consumer findConsumerByName( JavaImplementation impl, String name ) { for( org.apache.tuscany.sca.assembly.Consumer consumer : impl.getConsumers() ) { if( name.equals(consumer.getName()) ) return consumer; } // end for return null; } // end method findConsumerByName }