org.grails.plugins.AbstractGrailsPlugin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grails-core Show documentation
Show all versions of grails-core Show documentation
Grails Web Application Framework
/*
* Copyright 2004-2005 the original author or authors.
*
* 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 org.grails.plugins;
import grails.config.Config;
import grails.core.GrailsApplication;
import grails.io.IOUtils;
import grails.plugins.GrailsPlugin;
import grails.plugins.GrailsPluginManager;
import grails.util.GrailsNameUtils;
import groovy.lang.GroovyObjectSupport;
import org.grails.config.yaml.YamlPropertySourceLoader;
import org.grails.core.AbstractGrailsClass;
import org.grails.core.cfg.GroovyConfigPropertySourceLoader;
import org.grails.core.legacy.LegacyGrailsApplication;
import org.grails.plugins.support.WatchPattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
import java.io.IOException;
import java.net.URL;
import java.util.*;
/**
* Abstract implementation that provides some default behaviours
*
* @author Graeme Rocher
*/
public abstract class AbstractGrailsPlugin extends GroovyObjectSupport implements GrailsPlugin {
private static final Logger LOG = LoggerFactory.getLogger(AbstractGrailsPlugin.class);
public static final String PLUGIN_YML = "plugin.yml";
public static final String PLUGIN_YML_PATH = "/" + PLUGIN_YML;
public static final String PLUGIN_GROOVY = "plugin.groovy";
public static final String PLUGIN_GROOVY_PATH = "/" + PLUGIN_GROOVY;
private static final List DEFAULT_CONFIG_IGNORE_LIST = Arrays.asList("dataSource", "hibernate");
private static Resource basePluginResource = null;
protected PropertySource> propertySource;
protected org.codehaus.groovy.grails.commons.GrailsApplication application;
protected GrailsApplication grailsApplication;
protected boolean isBase = false;
protected String version = "1.0";
protected Map dependencies = new HashMap();
protected String[] dependencyNames = {};
protected Class> pluginClass;
protected ApplicationContext applicationContext;
protected GrailsPluginManager manager;
protected String[] evictionList = {};
protected Config config;
/**
* Wrapper Grails class for plugins.
*
* @author Graeme Rocher
*/
class GrailsPluginClass extends AbstractGrailsClass {
public GrailsPluginClass(Class> clazz) {
super(clazz, TRAILING_NAME);
}
}
public AbstractGrailsPlugin(Class> pluginClass, GrailsApplication application) {
Assert.notNull(pluginClass, "Argument [pluginClass] cannot be null");
Assert.isTrue(pluginClass.getName().endsWith(TRAILING_NAME),
"Argument [pluginClass] with value [" + pluginClass +
"] is not a Grails plugin (class name must end with 'GrailsPlugin')");
this.application = new LegacyGrailsApplication(application);
this.grailsApplication = application;
this.pluginClass = pluginClass;
Resource resource = readPluginConfiguration(pluginClass);
if(resource != null && resource.exists()) {
final String filename = resource.getFilename();
try {
if (filename.equals(PLUGIN_YML)) {
YamlPropertySourceLoader propertySourceLoader = new YamlPropertySourceLoader();
this.propertySource = propertySourceLoader.load(GrailsNameUtils.getLogicalPropertyName(pluginClass.getSimpleName(), "GrailsPlugin") + "-" + PLUGIN_YML, resource, null, true, DEFAULT_CONFIG_IGNORE_LIST);
} else if (filename.equals(PLUGIN_GROOVY)) {
GroovyConfigPropertySourceLoader propertySourceLoader = new GroovyConfigPropertySourceLoader();
this.propertySource = propertySourceLoader.load(GrailsNameUtils.getLogicalPropertyName(pluginClass.getSimpleName(), "GrailsPlugin") + "-" + PLUGIN_GROOVY, resource, null, DEFAULT_CONFIG_IGNORE_LIST);
}
} catch (IOException e) {
LOG.warn("Error loading " + filename + " for plugin: " + pluginClass.getName() +": " + e.getMessage(), e);
}
}
}
@Override
public PropertySource> getPropertySource() {
return propertySource;
}
/* (non-Javadoc)
* @see grails.plugins.GrailsPlugin#refresh()
*/
public void refresh() {
// do nothing
}
@Override
public boolean isEnabled(String[] profiles) {
return true;
}
protected Resource readPluginConfiguration(Class> pluginClass) {
Resource ymlResource = getConfigurationResource(pluginClass, PLUGIN_YML_PATH);
Resource groovyResource = getConfigurationResource(pluginClass, PLUGIN_GROOVY_PATH);
Boolean groovyResourceExists = groovyResource != null && groovyResource.exists();
if(ymlResource != null && ymlResource.exists()) {
if (groovyResourceExists) {
throw new RuntimeException("A plugin may define a plugin.yml or a plugin.groovy, but not both");
}
return ymlResource;
}
if(groovyResourceExists) {
return groovyResource;
}
return null;
}
protected Resource getConfigurationResource(Class> pluginClass, String path) {
final URL urlToConfig = IOUtils.findResourceRelativeToClass(pluginClass, path);
return urlToConfig != null ? new UrlResource(urlToConfig) : null;
}
public String getFileSystemName() {
return getFileSystemShortName() + '-' + getVersion();
}
public String getFileSystemShortName() {
return GrailsNameUtils.getScriptName(getName());
}
public Class> getPluginClass() {
return pluginClass;
}
public boolean isBasePlugin() {
return isBase;
}
public void setBasePlugin(boolean isBase) {
this.isBase = isBase;
}
public List getWatchedResourcePatterns() {
return Collections.emptyList();
}
public boolean hasInterestInChange(String path) {
return false;
}
public boolean checkForChanges() {
return false;
}
public String[] getDependencyNames() {
return dependencyNames;
}
public String getDependentVersion(String name) {
return null;
}
public String getName() {
return pluginClass.getName();
}
public String getVersion() {
return version;
}
public String getPluginPath() {
return PLUGINS_PATH + '/' + GrailsNameUtils.getScriptName(getName()) + '-' + getVersion();
}
// https://github.com/grails/grails-core/issues/9406
// The name of the plugin for my-plug on the path is myPlugin the GrailsNameUtils.getScriptName(getName()) will always use my-plugin
public String getPluginPathCamelCase() {
return PLUGINS_PATH + '/' + GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(getName()) + '-' + getVersion();
}
public GrailsPluginManager getManager() {
return manager;
}
public String[] getLoadAfterNames() {
return new String[0];
}
public String[] getLoadBeforeNames() {
return new String[0];
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/* (non-Javadoc)
* @see grails.plugins.GrailsPlugin#setManager(grails.plugins.GrailsPluginManager)
*/
public void setManager(GrailsPluginManager manager) {
this.manager = manager;
}
/* (non-Javadoc)
* @see grails.plugins.GrailsPlugin#setApplication(grails.core.GrailsApplication)
*/
public void setApplication(GrailsApplication application) {
this.application = new LegacyGrailsApplication(application);
}
public String[] getEvictionNames() {
return evictionList;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AbstractGrailsPlugin)) return false;
AbstractGrailsPlugin that = (AbstractGrailsPlugin) o;
if (!pluginClass.equals(that.pluginClass)) return false;
if (!version.equals(that.version)) return false;
return true;
}
@Override
public int hashCode() {
int result = version.hashCode();
result = 31 * result + pluginClass.hashCode();
return result;
}
public int compareTo(Object o) {
AbstractGrailsPlugin that = (AbstractGrailsPlugin) o;
if (equals(that)) return 0;
String thatName = that.getName();
for (String pluginName : getLoadAfterNames()) {
if (pluginName.equals(thatName)) return -1;
}
for (String pluginName : getLoadBeforeNames()) {
if (pluginName.equals(thatName)) return 1;
}
for (String pluginName : that.getLoadAfterNames()) {
if (pluginName.equals(getName())) return 1;
}
for (String pluginName : that.getLoadBeforeNames()) {
if (pluginName.equals(getName())) return -1;
}
return 0;
}
}