/*
* Copyright (C) 2013 Andrey Chaschev.
*
* 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 bear.plugins;
import bear.annotations.Shell;
import bear.console.AbstractConsole;
import bear.core.Bear;
import bear.core.GlobalContext;
import bear.core.Role;
import bear.core.SessionContext;
import bear.session.DynamicVariable;
import bear.session.Variables;
import bear.task.*;
import org.apache.commons.lang3.text.WordUtils;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.Set;
/**
* @author Andrey Chaschev chaschev@gmail.com
*/
public abstract class Plugin<TASK_DEF extends TaskDef> {
public String name;
protected String desc;
public final Bear bear;
protected GlobalContext global;
protected Dependencies dependencies = new Dependencies();
protected boolean transitiveDependency;
Set<Plugin<TaskDef>> pluginDependencies;
protected final TASK_DEF taskDefMixin;
protected PluginShellMode shell;
public Plugin(GlobalContext global) {
this(global, null);
}
public Plugin(GlobalContext global, TASK_DEF taskDef) {
this.global = global;
this.bear = global.bear;
name = getClass().getSimpleName();
taskDefMixin = taskDef;
}
public static String shortenName(String className) {
int lastDotIndex = className.lastIndexOf('.');
int end = className.lastIndexOf("Plugin");
if(end == -1) end = className.length();
return WordUtils.uncapitalize(className.substring(lastDotIndex + 1, end));
}
public Task<Object, TaskResult<?>> newSession(SessionContext $, Task<Object, TaskResult<?>> parent) {
throw new UnsupportedOperationException("todo");
}
public void initPlugin() {
if (shell != null) {
shell.init();
}
}
public InstallationTaskDef<? extends InstallationTask> getInstall() {
return InstallationTaskDef.EMPTY;
}
public DependencyResult checkPluginDependencies() {
return DependencyResult.OK;
}
@Override
public String toString() {
return name;
}
protected DependencyResult require(Class... pluginClasses) {
final DependencyResult r = new DependencyResult(this.getClass().getSimpleName());
for (Class pluginClass : pluginClasses) {
require(r, pluginClass);
}
return r.updateResult();
}
public AbstractConsole getConsole() {
throw new UnsupportedOperationException("plugin does not support console");
}
public boolean isConsoleSupported() {
try {
getConsole();
return true;
} catch (UnsupportedOperationException e) {
return !e.getMessage().contains("plugin does not support console");
}
}
protected void require(DependencyResult r, Class<? extends Plugin<? extends TaskDef>> pluginClass) {
final Plugin<? extends TaskDef> plugin = global.plugin(pluginClass);
if (plugin == null) {
r.add(plugin.getClass().getSimpleName() + " plugin is required");
}
}
public Dependencies getDependencies() {
return dependencies;
}
protected final Dependencies addDependency(Dependency... dependencies) {
return this.dependencies.addDependencies(dependencies);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Plugin<? extends TaskDef> plugin = (Plugin<? extends TaskDef>) o;
if (!name.equals(plugin.name)) return false;
return true;
}
@Override
public int hashCode() {
return name.hashCode();
}
public Set<Plugin<TaskDef>> getPluginDependencies() {
return pluginDependencies;
}
public Set<Plugin<TaskDef>> getAllPluginDependencies() {
Set<Plugin<TaskDef>> result = new HashSet<Plugin<TaskDef>>();
for (Plugin<TaskDef> dep : pluginDependencies) {
result.add(dep);
result.addAll(dep.getAllPluginDependencies());
}
return result;
}
public Set<Role> getRoles() {
return taskDefMixin.getRoles();
}
public TASK_DEF getTaskDef() {
return taskDefMixin;
}
public PluginShellMode getShell() {
return shell;
}
public GlobalContext getGlobal() {
return global;
}
public final String getName(){
Class<? extends Plugin> pluginClass = getClass();
return getName(pluginClass);
}
public static String getName(Class<? extends Plugin> pluginClass) {
bear.annotations.Plugin plugin = pluginClass.getAnnotation(bear.annotations.Plugin.class);
if(plugin != null) return plugin.value();
Shell shell = pluginClass.getAnnotation(Shell.class);
if(shell != null) return shell.value();
return shortenName(pluginClass.getName());
}
public final String cmdAnnotation() {
return getClass().getAnnotation(Shell.class).value();
}
public TASK_DEF getTaskDefMixin() {
return taskDefMixin;
}
protected void requireVars(DynamicVariable... vars) {
String msg = Variables.checkSet(global, getName(), vars);
if (msg != null) {
LoggerFactory.getLogger("log").error(msg);
throw new RuntimeException(msg);
}
}
}