io.nuun.kernel.core.AbstractPlugin Maven / Gradle / Ivy
Show all versions of kernel-core Show documentation
/**
* Copyright (C) 2013-2014 Kametic
*
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3, 29 June 2007;
* or any later version
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* 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 io.nuun.kernel.core;
import io.nuun.kernel.api.Plugin;
import io.nuun.kernel.api.di.UnitModule;
import io.nuun.kernel.api.plugin.InitState;
import io.nuun.kernel.api.plugin.Round;
import io.nuun.kernel.api.plugin.context.Context;
import io.nuun.kernel.api.plugin.context.InitContext;
import io.nuun.kernel.api.plugin.request.*;
import io.nuun.kernel.api.plugin.request.builders.BindingRequestBuilderMain;
import io.nuun.kernel.core.internal.injection.ModuleEmbedded;
import io.nuun.kernel.spi.DependencyInjectionProvider;
import org.kametic.specifications.*;
import org.kametic.specifications.reflect.ClassMethodsAnnotatedWith;
import org.kametic.specifications.reflect.DescendantOfSpecification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.*;
/**
* @author Epo Jemba
*/
public abstract class AbstractPlugin implements Plugin
{
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPlugin.class);
protected Context context = null;
protected Object containerContext = null;
protected Round round;
// ============================= PLUGIN LIFE CYCLE USED BY KERNEL =============================
@Override
public InitState init(InitContext initContext)
{
return InitState.INITIALIZED;
}
@Override
public void start(Context context)
{
this.context = context;
}
@Override
public void stop()
{
}
// ============================= PLUGIN request builders =============================
protected KernelParamsRequestBuilder kernelParamsRequestBuilder()
{
return new KernelParamsRequestBuilder();
}
protected ClasspathScanRequestBuilder classpathScanRequestBuilder()
{
return new ClasspathScanRequestBuilder();
}
protected BindingRequestBuilderMain bindingRequestsBuilder()
{
return new BindingRequestBuilder();
}
// ============================= PLUGIN Utilities Helpers =============================
protected Specification> or(Specification>... participants)
{
return new OrSpecification>(participants);
}
protected Specification> and(Specification>... participants)
{
return new AndSpecification>(participants);
}
protected Specification> not(Specification> participant)
{
return new NotSpecification>(participant);
}
protected Specification> descendantOf(Class> ancestor)
{
return new DescendantOfSpecification(ancestor);
}
protected Specification> classMethodsAnnotatedWith(final Class extends Annotation> annotationClass)
{
return new ClassMethodsAnnotatedWith(annotationClass);
}
protected Specification> fieldAnnotatedWith(final Class extends Annotation> annotationClass)
{
return new AbstractSpecification> ()
{
@Override
public boolean isSatisfiedBy(Class> candidate) {
if (candidate != null)
{
try
{
for (Field field : candidate.getDeclaredFields())
{
if (field.isAnnotationPresent(annotationClass))
{
return true;
}
}
}
catch (Throwable throwable)
{
LOGGER.debug("fieldAnnotatedWith : " + candidate + " missing " + throwable);
}
}
return false;
}
};
}
protected Specification> classAnnotatedWith(final Class extends Annotation> klass)
{
return new AbstractSpecification>()
{
@Override
public boolean isSatisfiedBy(Class> candidate)
{
return candidate != null && candidate.getAnnotation(klass) != null;
}
};
}
// TODO replace this implementation by the one in ClassMethodsAnnotatedWithSpecification
protected Specification> classImplements(final Class> klass)
{
return new AbstractSpecification>()
{
@Override
public boolean isSatisfiedBy(Class> candidate)
{
if (candidate != null && klass.isInterface())
{
for (Class> i : candidate.getInterfaces())
{
if (i.equals(klass))
{
return true;
}
}
}
return false;
}
};
}
// * ============================= PLUGIN info and requests * ============================= //
@Override
public abstract String name();
@Override
public String description()
{
return name() + " Nuun Based Plugin.";
}
@Override
public Collection kernelParamsRequests()
{
return Collections.emptySet();
}
@Override
public Collection classpathScanRequests()
{
return Collections.emptySet();
}
@Override
public Collection bindingRequests()
{
return Collections.emptySet();
}
@Override
public Collection> requiredPlugins()
{
return Collections.emptySet();
}
@Override
public Collection> dependentPlugins()
{
return Collections.emptySet();
}
@Override
public String pluginPropertiesPrefix()
{
return "";
}
@Override
public String pluginPackageRoot()
{
return "";
}
@Override
public UnitModule unitModule()
{
return nativeUnitModule() != null ? new ModuleEmbedded(nativeUnitModule()) : null;
}
/**
* Convenient method for plugin to return directly a native module rather than a UnitModule.
*
* then {@link AbstractPlugin#unitModule()} will use {@link AbstractPlugin#nativeUnitModule()} to create the UnitModule.
*
* @return the nativeModule.
*/
public Object nativeUnitModule()
{
return null;
}
/**
* Convenient method for plugin to return directly a native module rather than a UnitModule.
*
* then {@link AbstractPlugin#unitModule()} will use {@link AbstractPlugin#nativeUnitModule()} to create the UnitModule.
*
* @return the nativeModule for overring purpose.
*/
public Object nativeOverridingUnitModule()
{
return null;
}
@Override
public UnitModule overridingUnitModule()
{
return nativeOverridingUnitModule() != null ? new ModuleEmbedded(nativeOverridingUnitModule()) : null;
}
@Override
public void provideContainerContext(Object containerContext){
this.containerContext = containerContext;
}
@Override
public Set computeAdditionalClasspathScan()
{
return Collections.emptySet();
}
@Override
public DependencyInjectionProvider dependencyInjectionProvider()
{
return null;
}
@Override
public void provideRound(Round round)
{
this.round = round;
}
@Override
public Map kernelParametersAliases()
{
return new HashMap();
}
protected UnitModule unitModule(Object module)
{
return new ModuleEmbedded(module);
}
}