All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cloudbees.sdk.extensibility.ExtensionLoaderModule Maven / Gradle / Ivy

/*
 * Copyright 2010-2013, CloudBees Inc.
 *
 * 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.cloudbees.sdk.extensibility;

import com.google.inject.AbstractModule;
import com.google.inject.Binding;
import com.google.inject.BindingAnnotation;
import com.google.inject.Injector;
import com.google.inject.Key;

import javax.inject.Named;
import javax.inject.Qualifier;
import java.lang.annotation.Annotation;

/**
 * Responsible for producing {@link Binding}s inside {@link Injector}
 * from a discovered extension.
 *
 * @author Kohsuke Kawaguchi
 * @see ExtensionPoint
 */
public abstract class ExtensionLoaderModule extends AbstractModule {
    /**
     * The type of the extension implementation discovered.
     */
    protected Class impl;
    /**
     * The type of the extension point.
     */
    protected Class extensionPoint;

    /**
     * Called by {@link ExtensionFinder} to initialize this module.
     */
    public void init(Class impl, Class extensionPoint) {
        this.impl = impl;
        this.extensionPoint = extensionPoint;
    }

    /**
     * The default implementation of {@link ExtensionLoaderModule}.
     *
     * If the discovered implementation has any {@linkplain BindingAnnotation binding annotation},
     * that is used as the key. This allows an extension point that supports named lookup, such as:
     *
     * 
     * @Retention(RUNTIME)
     * @Target(TYPE)
     * @Indexed
     * @BindingAnnotation
     * @ExtensionImplementation
     * public @interface CLICommand {
     *     String value();
     * }
     *
     * @CLICommand("acme")
     * public class AcmeCommand extends Command { ... }
     *
     * // then somewhere else
     * Command cmd = injector.getBinding(Key.get(Command.class,AnnotationLiteral.of(CLICommand.class,"acme"))
     * 
* * If no binding annotation is present, this implementation creates a unique binding * annotation, so that at least it can be looked up via {@link ExtensionPointList}. */ static class Default extends ExtensionLoaderModule { @Override protected void configure() { Annotation qa = findQualifierAnnotation(impl); if (qa==null) // this is just to make it unique among others that implement the same contract qa = AnnotationLiteral.of(Named.class,impl.getName()); binder().withSource(impl).bind(Key.get(extensionPoint, qa)).to(impl); bind(impl); } private Annotation findQualifierAnnotation(Class impl) { for (Annotation a : impl.getAnnotations()) { Class at = a.annotationType(); if (at.isAnnotationPresent(Qualifier.class) || at.isAnnotationPresent(BindingAnnotation.class)) return a; } return null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy