/* * Copyright 2014 Effektif GmbH. * * Licensed 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 com.effektif.workflow.impl.activity; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.ServiceLoader; import com.effektif.workflow.api.Configuration; import com.effektif.workflow.api.json.TypeName; import com.effektif.workflow.api.workflow.Activity; import com.effektif.workflow.api.workflow.Trigger; import com.effektif.workflow.impl.configuration.Brewery; import com.effektif.workflow.impl.configuration.Startable; import com.effektif.workflow.impl.data.types.ObjectTypeImpl; import com.effektif.workflow.impl.util.Exceptions; /** * @author Tom Baeyens */ public class ActivityTypeService implements Startable { // private static final Logger log = LoggerFactory.getLogger(ActivityTypeService.class); protected Configuration configuration; // maps json type names to activity descriptors protected Map<String, ActivityDescriptor> activityTypeDescriptors = new LinkedHashMap<>(); // maps activity api configuration classes to activity type implementation classes protected Map<Class<?>, Class<? extends ActivityType>> activityTypeClasses = new HashMap<>(); protected Map<Class<?>, ActivityType> activityTypes = new LinkedHashMap<>(); protected Map<Class<?>, ObjectTypeImpl> activityTypeSerializers = new HashMap<>(); protected Map<Class<?>, Class<? extends AbstractTriggerImpl>> triggerClasses = new HashMap<>(); public ActivityTypeService() { } @Override public void start(Brewery brewery) { this.configuration = brewery.get(Configuration.class); initializeActivityTypes(); initializeTriggerTypes(); } protected void initializeActivityTypes() { ServiceLoader<ActivityType> loader = ServiceLoader.load(ActivityType.class); for (ActivityType type: loader) { registerActivityType(type); } } protected void initializeTriggerTypes() { ServiceLoader<AbstractTriggerImpl> loader = ServiceLoader.load(AbstractTriggerImpl.class); for (AbstractTriggerImpl type: loader) { registerTriggerType(type); } } public void registerActivityType(ActivityType activityType) { Class<? extends Activity> activityTypeApiClass = activityType.getActivityApiClass(); ActivityDescriptor descriptor = activityType.getDescriptor(); activityTypeClasses.put(activityTypeApiClass, activityType.getClass()); activityTypes.put(activityTypeApiClass, activityType); TypeName jsonTypeName = activityTypeApiClass.getAnnotation(TypeName.class); if (jsonTypeName==null) { throw new RuntimeException("Please add @TypeName annotation to "+activityTypeApiClass); } activityTypeDescriptors.put(jsonTypeName.value(), descriptor); } public ActivityDescriptor getActivityDescriptor(String jsonTypeName) { return activityTypeDescriptors.get(jsonTypeName); } public void registerTriggerType(AbstractTriggerImpl trigger) { Class triggerApiClass = trigger.getTriggerApiClass(); triggerClasses.put(triggerApiClass, trigger.getClass()); } public ActivityType instantiateActivityType(Activity activityApi) { Exceptions.checkNotNullParameter(activityApi, "activityApi"); Class<? extends ActivityType> activityTypeClass = activityTypeClasses.get(activityApi.getClass()); if (activityTypeClass==null) { throw new RuntimeException("No ActivityType defined for "+activityApi.getClass().getName()); } try { return activityTypeClass.newInstance(); } catch (Exception e) { throw new RuntimeException("Couldn't instantiate "+activityTypeClass+": "+e.getMessage(), e); } } public AbstractTriggerImpl instantiateTriggerType(Trigger trigger) { Exceptions.checkNotNullParameter(trigger, "trigger"); Class<? extends AbstractTriggerImpl> triggerImplClass = triggerClasses.get(trigger.getClass()); if (triggerImplClass==null) { throw new RuntimeException("No trigger type defined for "+trigger.getClass().getName()); } try { return triggerImplClass.newInstance(); } catch (Exception e) { throw new RuntimeException("Couldn't instantiate "+triggerImplClass+": "+e.getMessage(), e); } } public Collection<ActivityType> getActivityTypes() { return activityTypes.values(); } public ActivityType<Activity> getActivityType(Class<? extends Activity> activityType) { return activityTypes.get(activityType); } }