Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.amazonaws.services.simpleworkflow.flow.pojo.POJOActivityImplementationFactory Maven / Gradle / Ivy
Go to download
The Amazon Web Services SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).
/*
* Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 com.amazonaws.services.simpleworkflow.flow.pojo;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.amazonaws.services.simpleworkflow.flow.DataConverter;
import com.amazonaws.services.simpleworkflow.flow.JsonDataConverter;
import com.amazonaws.services.simpleworkflow.flow.annotations.Activities;
import com.amazonaws.services.simpleworkflow.flow.annotations.Activity;
import com.amazonaws.services.simpleworkflow.flow.annotations.ActivityRegistrationOptions;
import com.amazonaws.services.simpleworkflow.flow.annotations.ManualActivityCompletion;
import com.amazonaws.services.simpleworkflow.flow.annotations.NullDataConverter;
import com.amazonaws.services.simpleworkflow.flow.annotations.SkipTypeRegistration;
import com.amazonaws.services.simpleworkflow.flow.common.FlowConstants;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementation;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementationFactory;
import com.amazonaws.services.simpleworkflow.flow.worker.ActivityTypeExecutionOptions;
import com.amazonaws.services.simpleworkflow.flow.worker.ActivityTypeRegistrationOptions;
import com.amazonaws.services.simpleworkflow.model.ActivityType;
public class POJOActivityImplementationFactory extends ActivityImplementationFactory {
private static class ParentInterfaceOptions {
private String version;
private String prefix;
private ActivityRegistrationOptions registrationOptions;
private boolean skipRegistration;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public ActivityRegistrationOptions getRegistrationOptions() {
return registrationOptions;
}
public void setRegistrationOptions(ActivityRegistrationOptions options) {
if (options != null) {
setSkipRegistration(false);
}
this.registrationOptions = options;
}
public boolean isSkipRegistration() {
return skipRegistration;
}
public void setSkipRegistration(boolean skipRegistration) {
if (skipRegistration) {
registrationOptions = null;
}
this.skipRegistration = skipRegistration;
}
}
private List activityTypesToRegister = new ArrayList();
private Map implementationsMap = new HashMap();
private DataConverter dataConverter = new JsonDataConverter();
public POJOActivityImplementationFactory() {
super();
}
public POJOActivityImplementationFactory(Iterable activityImplementationObjects)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
this();
addActivitiesImplementations(activityImplementationObjects, null);
}
public POJOActivityImplementationFactory(Iterable activityImplementationObjects, DataConverter dataConverter)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
this();
addActivitiesImplementations(activityImplementationObjects, dataConverter);
}
public DataConverter getDataConverter() {
return dataConverter;
}
public void setDataConverter(DataConverter dataConverter) {
if (dataConverter == null) {
throw new IllegalArgumentException("null dataConverter");
}
this.dataConverter = dataConverter;
}
public void setActivitiesImplementations(Iterable activitiesImplementations)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
addActivitiesImplementations(activitiesImplementations, null);
}
public Iterable getActivitiesImplementations() {
List result = new ArrayList();
for (POJOActivityImplementation impl : implementationsMap.values()) {
result.add(impl.getActivitiesImplementation());
}
return result;
}
public List addActivitiesImplementations(Iterable activitiesImplementations)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
return addActivitiesImplementations(activitiesImplementations, null);
}
public List addActivitiesImplementations(Iterable activitiesImplementations, DataConverter dataConverter)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
List result = new ArrayList();
for (Object activityImplementationObject : activitiesImplementations) {
result.addAll(addActivitiesImplementation(activityImplementationObject, dataConverter));
}
return result;
}
public List addActivitiesImplementation(Object activitiesImplementation)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
return addActivitiesImplementation(activitiesImplementation, null);
}
public List addActivitiesImplementation(Object activitiesImplementation, DataConverter converter)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException {
if (activitiesImplementation == null) {
throw new IllegalArgumentException("activitiesImplementation is null.");
}
Set result = new HashSet();
Set> activitiesInterfaces = new HashSet>();
getImplementedInterfacesAnnotatedWithActivities(activitiesImplementation.getClass(), activitiesInterfaces);
if (activitiesInterfaces.size() == 0) {
throw new IllegalArgumentException(
"Activity implementation object does not implement any interface annotated with @Activities: "
+ activitiesImplementation.getClass());
}
for (Class> interfaze : activitiesInterfaces) {
Map methods = new HashMap();
ParentInterfaceOptions parentOptions = new ParentInterfaceOptions();
addActivities(activitiesImplementation, interfaze, methods, parentOptions, converter, result);
}
return new ArrayList(result);
}
private void addActivities(Object implementation, Class> interfaze, Map methods,
ParentInterfaceOptions parentOptions, DataConverter converter, Set addedTypes)
throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException {
Activities activitiesAnnotation = interfaze.getAnnotation(Activities.class);
for (Class> parent : interfaze.getInterfaces()) {
addActivities(implementation, parent, methods, parentOptions, converter, addedTypes);
}
if (activitiesAnnotation != null) {
String interfaceName = interfaze.getSimpleName();
if (!nullOrEmpty(activitiesAnnotation.activityNamePrefix())) {
parentOptions.setPrefix(activitiesAnnotation.activityNamePrefix());
}
if (!nullOrEmpty(activitiesAnnotation.version())) {
parentOptions.setVersion(activitiesAnnotation.version());
}
converter = (converter == null) ? createConverter(activitiesAnnotation.dataConverter()) : converter;
ActivityRegistrationOptions interfaceRegistrationOptionsAnnotation = interfaze.getAnnotation(ActivityRegistrationOptions.class);
SkipTypeRegistration interfaceSkipTypeRegistrationAnnotation = interfaze.getAnnotation(SkipTypeRegistration.class);
if (interfaceRegistrationOptionsAnnotation != null) {
if (interfaceSkipTypeRegistrationAnnotation != null) {
throw new IllegalArgumentException(
"@ActivityRegistrationOptions is not allowed for the interface annotated with @SkipTypeRegistration.");
}
parentOptions.setRegistrationOptions(interfaceRegistrationOptionsAnnotation);
}
else if (interfaceSkipTypeRegistrationAnnotation != null) {
parentOptions.setSkipRegistration(true);
}
for (Method method : interfaze.getMethods()) {
if (!method.getDeclaringClass().equals(interfaze)) {
continue;
}
Activity activityAnnotation = method.getAnnotation(Activity.class);
ActivityType activityType = getActivityType(interfaceName, method, activityAnnotation, parentOptions);
ActivityRegistrationOptions registrationOptionsAnnotation = method.getAnnotation(ActivityRegistrationOptions.class);
SkipTypeRegistration skipTypeRegistrationAnnotation = interfaze.getAnnotation(SkipTypeRegistration.class);
ActivityTypeRegistrationOptions registrationOptions = null;
if (skipTypeRegistrationAnnotation != null) {
if (registrationOptionsAnnotation != null) {
throw new IllegalArgumentException(
"@ActivityRegistrationOptions is not allowed for the method annotated with @SkipTypeRegistration: "
+ method);
}
}
else {
if (registrationOptionsAnnotation != null || parentOptions.getRegistrationOptions() != null) {
POJOActivityImplementation existingImplementation = implementationsMap.get(activityType);
if (existingImplementation != null && !addedTypes.contains(activityType)) {
String message = "Duplicate declaration for activity type=" + activityType.getName() + ", version="
+ activityType.getVersion() + ": " + existingImplementation.getMethod() + " and " + method;
throw new IllegalArgumentException(message);
}
registrationOptions = createRegistrationOptions(registrationOptionsAnnotation,
parentOptions.getRegistrationOptions());
}
else if (!parentOptions.isSkipRegistration()) {
throw new IllegalArgumentException(
"No @ActivityRegistationOptions found either on interface or method for " + method);
}
}
//TODO: support methods defined in parents as well as overrides
if (!addedTypes.contains(activityType)) {
Method activityImplementationMethod = implementation.getClass().getMethod(method.getName(),
method.getParameterTypes());
ActivityTypeExecutionOptions executionOptions = createExecutionOptions(activityType, activityImplementationMethod);
POJOActivityImplementation activityImplementation = new POJOActivityImplementation(implementation, method,
registrationOptions, executionOptions, converter);
activityTypesToRegister.add(activityType);
addedTypes.add(activityType);
implementationsMap.put(activityType, activityImplementation);
}
}
}
}
@Override
public Iterable getActivityTypesToRegister() {
return activityTypesToRegister;
}
@Override
public ActivityImplementation getActivityImplementation(ActivityType activityType) {
return implementationsMap.get(activityType);
}
private DataConverter createConverter(Class extends DataConverter> converterType)
throws InstantiationException, IllegalAccessException {
if (converterType == null || converterType.equals(NullDataConverter.class)) {
return dataConverter == null ? new JsonDataConverter() : dataConverter;
}
return converterType.newInstance();
}
private static ActivityType getActivityType(String interfaceName, Method activity, Activity activityAnnotation,
ParentInterfaceOptions parentOptions) {
ActivityType activityType = new ActivityType();
String activityName = null;
String activityVersion = null;
if (activityAnnotation != null) {
if (!nullOrEmpty(activityAnnotation.name())) {
activityName = activityAnnotation.name();
}
if (!nullOrEmpty(activityAnnotation.version())) {
activityVersion = activityAnnotation.version();
}
}
if (activityName == null) {
if (!nullOrEmpty(parentOptions.getPrefix())) {
activityName = parentOptions.getPrefix() + activity.getName();
}
else {
activityName = interfaceName + "." + activity.getName();
}
}
if (activityVersion == null) {
if (!nullOrEmpty(parentOptions.getVersion())) {
activityVersion = parentOptions.getVersion();
}
else {
throw new IllegalArgumentException("No version found for activity defined by " + activity);
}
}
activityType.setName(activityName);
activityType.setVersion(activityVersion);
return activityType;
}
private static boolean nullOrEmpty(String nameFromAnnotation) {
return nameFromAnnotation == null || nameFromAnnotation.isEmpty();
}
/**
* Recursively find all interfaces annotated with @Activities that given
* class implements. Do not include interfaces that @Activities annotated
* interface extends.
*/
private void getImplementedInterfacesAnnotatedWithActivities(Class> implementationType, Set> implementedInterfaces) {
Class> superClass = implementationType.getSuperclass();
if (superClass != null) {
getImplementedInterfacesAnnotatedWithActivities(superClass, implementedInterfaces);
}
Class>[] interfaces = implementationType.getInterfaces();
for (Class> i : interfaces) {
if (i.getAnnotation(Activities.class) != null && !implementedInterfaces.contains(i)) {
boolean skipAdd = removeSuperInterfaces(i, implementedInterfaces);
if (!skipAdd) {
implementedInterfaces.add(i);
}
}
else {
getImplementedInterfacesAnnotatedWithActivities(i, implementedInterfaces);
}
}
}
private boolean removeSuperInterfaces(Class> interfaceToAdd, Set> implementedInterfaces) {
boolean skipAdd = false;
List> interfacesToRemove = new ArrayList>();
for (Class> addedInterface : implementedInterfaces) {
if (addedInterface.isAssignableFrom(interfaceToAdd)) {
interfacesToRemove.add(addedInterface);
}
if (interfaceToAdd.isAssignableFrom(addedInterface)) {
skipAdd = true;
}
}
for (Class> interfaceToRemove : interfacesToRemove) {
implementedInterfaces.remove(interfaceToRemove);
}
return skipAdd;
}
private static ActivityTypeRegistrationOptions createRegistrationOptions(ActivityRegistrationOptions registrationOptions,
ActivityRegistrationOptions parentRegistrationOptions) {
ActivityRegistrationOptions registrationOptionsAnnotation = registrationOptions != null ? registrationOptions
: parentRegistrationOptions;
ActivityTypeRegistrationOptions result = new ActivityTypeRegistrationOptions();
result.setDescription(emptyStringToNull(registrationOptionsAnnotation.description()));
long taskHeartbeatTimeoutSeconds = registrationOptionsAnnotation.defaultTaskHeartbeatTimeoutSeconds();
if (taskHeartbeatTimeoutSeconds > FlowConstants.USE_REGISTERED_DEFAULTS) {
result.setDefaultTaskHeartbeatTimeoutSeconds(taskHeartbeatTimeoutSeconds);
}
long taskScheduleToCloseTimeoutSeconds = registrationOptionsAnnotation.defaultTaskScheduleToCloseTimeoutSeconds();
if (taskScheduleToCloseTimeoutSeconds > FlowConstants.USE_REGISTERED_DEFAULTS) {
result.setDefaultTaskScheduleToCloseTimeoutSeconds(taskScheduleToCloseTimeoutSeconds);
}
long taskScheduleToStartTimeoutSeconds = registrationOptionsAnnotation.defaultTaskScheduleToStartTimeoutSeconds();
if (taskScheduleToStartTimeoutSeconds > FlowConstants.USE_REGISTERED_DEFAULTS) {
result.setDefaultTaskScheduleToStartTimeoutSeconds(taskScheduleToStartTimeoutSeconds);
}
long taskStartToCloseTimeoutSeconds = registrationOptionsAnnotation.defaultTaskStartToCloseTimeoutSeconds();
if (taskStartToCloseTimeoutSeconds > FlowConstants.USE_REGISTERED_DEFAULTS) {
result.setDefaultTaskStartToCloseTimeoutSeconds(taskStartToCloseTimeoutSeconds);
}
String taskList = registrationOptionsAnnotation.defaultTaskList();
if (!taskList.equals(FlowConstants.USE_WORKER_TASK_LIST)) {
result.setDefaultTaskList(taskList);
}
else if (taskList.equals(FlowConstants.NO_DEFAULT_TASK_LIST)) {
result.setDefaultTaskList(null);
}
return result;
}
private static ActivityTypeExecutionOptions createExecutionOptions(ActivityType activityType, Method activityImplementation) {
assert (activityType != null);
ActivityTypeExecutionOptions executionOptions = new ActivityTypeExecutionOptions();
if (activityImplementation != null) {
ManualActivityCompletion manualCompletion = activityImplementation.getAnnotation(ManualActivityCompletion.class);
executionOptions.setManualActivityCompletion(manualCompletion != null);
}
return executionOptions;
}
private static String emptyStringToNull(String value) {
if (value.length() == 0) {
return null;
}
return value;
}
}