/** * Creates {@link TaskDescriptor} for given Task's bean entry class. To be used for tasks without * descriptors, it will create one on the fly with defaults. */ private <T extends Task> TaskDescriptor<T> createTaskDescriptor( final BeanEntry<Named, Task> taskBeanEntry) { final String taskName = taskBeanEntry.getDescription() != null ? taskBeanEntry.getDescription() : taskBeanEntry.getImplementationClass().getSimpleName(); // by default, tasks w/o descriptors are not exposed, and not visible while run/scheduled return new TaskDescriptorSupport<T>( (Class<T>) taskBeanEntry.getImplementationClass(), taskName, false, false) {}; }
@Override public <T extends Task> TaskDescriptor<T> resolveTaskDescriptorByTypeId(final String taskTypeId) { // look for descriptors first for (TaskDescriptor<?> taskDescriptor : taskDescriptors) { if (taskDescriptor.getId().equals(taskTypeId)) { return (TaskDescriptor<T>) taskDescriptor; } } // not found by descriptor, try tasks directly for (BeanEntry<Named, Task> entry : tasks) { // checks: task FQCN, task SimpleName or @Named if (entry.getImplementationClass().getName().equals(taskTypeId) || entry.getImplementationClass().getSimpleName().equals(taskTypeId) || entry.getKey().value().equals(taskTypeId)) { return (TaskDescriptor<T>) findTaskDescriptor(entry); } } return null; }
/** * Returns {@link TaskDescriptor} by given Task's bean entry. Will perform a search for provided * task descriptors, and if not found, will create one using {@link * #createTaskDescriptor(BeanEntry)}. */ private <T extends Task> TaskDescriptor<T> findTaskDescriptor( final BeanEntry<Named, Task> taskBeanEntry) { // look for descriptor first for (TaskDescriptor<?> taskDescriptor : taskDescriptors) { if (taskDescriptor.getType().equals(taskBeanEntry.getImplementationClass())) { return (TaskDescriptor<T>) taskDescriptor; } } // not found by descriptor, create one for it return (TaskDescriptor<T>) createTaskDescriptor(taskBeanEntry); }
@Override public void add(final BeanEntry<Named, Action> beanEntry, final BundleContext bundleContext) throws Exception { Command command = beanEntry.getImplementationClass().getAnnotation(Command.class); if (command != null) { // TODO: warn if @Singleton is present, this is probably not desired due to // @Option/@Argument processing ? Dictionary<String, ?> config = CommandHelper.config(command); log.debug("Adding action: {}, config: {}", beanEntry, config); bundleContext.registerService( Function.class, new BeanEntryCommand(beanLocator, beanEntry), config); } else { log.warn("Missing @Command annotation on action: {}", beanEntry); } }
@Override public <T extends Task> T createTaskInstance(final TaskConfiguration taskConfiguration) throws IllegalArgumentException { checkNotNull(taskConfiguration); taskConfiguration.validate(); log.debug("Creating task by hint: {}", taskConfiguration); final TaskDescriptor<T> taskDescriptor = getTaskDescriptorByTypeId(taskConfiguration.getTypeId()); for (BeanEntry<Named, Task> entry : tasks) { if (entry.getImplementationClass().equals(taskDescriptor.getType())) { final T task = (T) entry.getProvider().get(); task.configure(taskConfiguration); return task; } } throw new IllegalArgumentException( "No Task of type \'" + taskConfiguration.getTypeId() + "\' found"); }
/** * Returns a map with "typeId" Task descriptor mapping for all existing tasks. For tasks without * descriptors, descriptor will be created. */ private Map<String, TaskDescriptor<?>> allTaskDescriptors() { // TODO: consistency checks? a) task : descriptors are 1:1, b) descriptor IDs are unique? // TODO: we might emit warning if some of those does not stand // using task class as "key" to detect tasks w/ descriptor vs tasks w/o descriptor final Map<Class<? extends Task>, TaskDescriptor<?>> descriptorMap = Maps.newHashMap(); for (TaskDescriptor<?> taskDescriptor : taskDescriptors) { descriptorMap.put(taskDescriptor.getType(), taskDescriptor); } for (BeanEntry<Named, Task> entry : tasks) { if (!descriptorMap.containsKey(entry.getImplementationClass())) { final TaskDescriptor<?> taskDescriptor = createTaskDescriptor(entry); descriptorMap.put(taskDescriptor.getType(), taskDescriptor); } } // repack the map into result map keyed by typeId final Map<String, TaskDescriptor<?>> result = Maps.newHashMap(); for (TaskDescriptor<?> taskDescriptor : descriptorMap.values()) { result.put(taskDescriptor.getId(), taskDescriptor); } return result; }
@Override public Class<?> getScannableClass() { return entry.getImplementationClass(); }