
org.kuali.maven.plugins.guice.GuiceMojo Maven / Gradle / Ivy
/**
* Copyright 2011-2013 The Kuali Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
*
* 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.kuali.maven.plugins.guice;
import static com.google.common.base.Optional.absent;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.inject.Guice.createInjector;
import static java.lang.Character.toUpperCase;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.kuali.common.jute.base.Exceptions.illegalArgument;
import static org.kuali.common.jute.base.Optionals.fromTrimToNull;
import java.lang.annotation.Annotation;
import java.util.List;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import com.google.common.base.Optional;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Key;
/**
*
* Create a Guice injector from the configured modules, get a {@code java.lang.Runnable} from the injector, and run it.
*
*
*
* If no explicit modules are configured, look for a default module using {@code groupId + artifactId} by converting {@code artifactId} to camel case and appending the word
* {@code Module}. For example, the default module that would be loaded using this plugin's GAV information is:
*
*
* org.kuali.maven.plugins.GuiceMavenPluginModule
*
*
*
*/
@Mojo(name = GuiceMojo.RUN, threadSafe = true)
@Execute(goal = GuiceMojo.RUN)
public class GuiceMojo extends AbstractMojo {
static final String RUN = "run";
private static final String MODULE = "Module";
@Component
MavenProject project;
@Component
Settings settings;
/**
* List of Guice modules to use when creating the injector. If supplied, these come before {@code guice.module}
*/
@Parameter(property = "guice.modules")
List modules = newArrayList();
/**
* The Guice module to use when creating the injector. This comes after {@code guice.modules} (if any were supplied).
*/
@Parameter(property = "guice.module")
String module;
/**
* If supplied, the {@code java.lang.Runnable} must be injected using this annotation
*/
@Parameter(property = "guice.annotation")
String annotation;
@Override
public void execute() {
// TODO Gain a better understanding of Guice scopes and if a custom scope might be appropriate here
// TODO Strongly suspect what is being done here would be considered naive, and better accomplished via some kind
// TODO of "project scope", or "reactor scope" or something similar, possibly not even being done as a plugin
// TODO https://github.com/google/guice/wiki/CustomScopes
Optional module = getModule(this);
checkState(module.isPresent() || !getModules().isEmpty(), "no modules");
List modules = getModules(module, getModules(), new MavenModule(this));
Injector injector = createInjector(modules);
Runnable runnable = getRunnable(injector, fromTrimToNull(annotation));
runnable.run();
}
protected Optional getModule(GuiceMojo mojo) {
if (isNotBlank(mojo.getModule())) {
// they've supplied a specific module, use it
AbstractModule module = getModule(mojo.getModule());
return Optional.of(module);
} else {
// otherwise see if we can find a default module
return getDefaultModule(mojo.getProject());
}
}
private List getModules(Optional module, List modules, MavenModule maven) {
List list = newArrayList();
list.add(maven);
for (String moduleName : modules) {
AbstractModule element = getModule(moduleName);
list.add(element);
}
if (module.isPresent()) {
list.add(module.get());
}
return list;
}
private Runnable getRunnable(Injector injector, Optional annotation) {
if (annotation.isPresent()) {
Class extends Annotation> type = newClass(annotation.get());
Key key = Key.get(Runnable.class, type);
return injector.getInstance(key);
} else {
return injector.getInstance(Runnable.class);
}
}
private Optional getDefaultModule(MavenProject project) {
String className = getDefaultModuleClassName(project);
try {
AbstractModule module = getModule(className);
return Optional.of(module);
} catch (IllegalArgumentException e) {
// if we can't lookup a default module, just return absent
return absent();
}
}
private String getDefaultModuleClassName(MavenProject project) {
String groupId = project.getGroupId();
String artifactId = project.getArtifactId();
return groupId + "." + capitalize(artifactId) + MODULE;
}
protected String capitalize(String artifactId) {
char[] chars = artifactId.replace('_', '-').toCharArray();
StringBuilder sb = new StringBuilder();
char prevChar = 0;
for (char c : chars) {
if (c == '-') {
// skip it, don't add it to the string
} else if (prevChar == 0 || prevChar == '-') {
// if it's the first character OR the previous character was a dash
// convert the current character to upper case and append it
sb.append(toUpperCase(c));
} else {
// otherwise just append the current character
sb.append(c);
}
prevChar = c;
}
return sb.toString();
}
protected AbstractModule getModule(String module) {
Class extends AbstractModule> type = newClass(module);
return newInstance(type);
}
@SuppressWarnings("unchecked")
protected T newClass(String type) {
try {
return (T) Class.forName(type);
} catch (Exception e) {
throw illegalArgument(e);
}
}
protected T newInstance(Class type) {
try {
return type.newInstance();
} catch (Exception e) {
throw illegalArgument(e);
}
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
public MavenProject getProject() {
return project;
}
public Settings getSettings() {
return settings;
}
public void setModules(List modules) {
this.modules = modules;
}
public List getModules() {
return modules;
}
public String getAnnotation() {
return annotation;
}
public void setAnnotation(String annotation) {
this.annotation = annotation;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy