Creating a Grails Plugin in NetBeans IDE
Let's create a plugin for Grails. Grails is, after all, modular and pluggable. Here's the ultimate simple Grails plugin, just to give an idea what is involved, from start to finish. The most useful references I have found so far are these:
Between those three, you should have enough to figure things out. I still found it hard, despite those instructions and so to avoid having to figure things out again some time in the future, I'll write absolutely everything here.
Creating the Plugin
- On the command line, run this:
grails create-plugin SamplePlugin
Now you have a Grails plugin. However, at the same time it is just another Grails application, which means you can simply open it in NetBeans IDE. (I.e., there is no import process and no NetBeans artifacts are added to the plugin in order to be able to open it in the IDE.)
- So open the plugin in the IDE. The Projects window isn't very interesting, it just shows you the same as you would normally see for Grails applications:
The Files window (Ctrl-2) however, shows a lot more:
Open the "SamplePluginGrailsPlugin.groovy" file and there you see the following:
class SamplePluginGrailsPlugin {
def version = 0.1
def dependsOn = [:]
def doWithSpring = {
// TODO Implement runtime spring config (optional)
}
def doWithApplicationContext = { applicationContext ->
// TODO Implement post initialization spring config (optional)
}
def doWithWebDescriptor = { xml ->
// TODO Implement additions to web.xml (optional)
}
def doWithDynamicMethods = { ctx ->
// TODO Implement registering dynamic methods to classes (optional)
}
def onChange = { event ->
// TODO Implement code that is executed when this class plugin class is changed
// the event contains: event.application and event.applicationContext objects
}
def onApplicationChange = { event ->
// TODO Implement code that is executed when any class in a GrailsApplication changes
// the event contain: event.source, event.application and event.applicationContext objects
}
}
I.e., you have hooks for integrating your code into meaningful places in the plugin.
- Now we'll create code that will let our plugin provide a new "constraint". (If you don't know what that is, you will know by the time you finish reading all this.) To do so, we will need to extend org.codehaus.groovy.grails.validation.AbstractConstraint, in a package within src/groovy:
import org.codehaus.groovy.grails.validation.AbstractConstraint
import org.springframework.validation.Errors
class BestFrameworkConstraint extends AbstractConstraint {
private static final String DEFAULT_MESSAGE_CODE = "default.answer.invalid.message";
public static final String NAME = "oneCorrectResponse";
private boolean validateConstraint
//The parameter which the constraint is validated against:
@Override
public void setParameter(Object constraintParameter) {
if (!(constraintParameter instanceof Boolean))
throw new IllegalArgumentException("Parameter for constraint ["
+ NAME + "] of property ["
+ constraintPropertyName + "] of class ["
+ constraintOwningClass + "] must be a boolean value");
this.validateConstraint = ((Boolean) constraintParameter).booleanValue()
super.setParameter(constraintParameter);
}
//Returns the default message for the given message code in the current locale:
@Override
protected void processValidate(Object target, Object propertyValue, Errors errors) {
if (validateConstraint && !validate(target, propertyValue)) {
def args = (Object[]) [constraintPropertyName, constraintOwningClass,
propertyValue]
super.rejectValue(target, errors, DEFAULT_MESSAGE_CODE,
"not." + NAME, args);
}
}
//Returns whether the constraint supports being applied against the specified type:
@Override
boolean supports(Class type) {
return type != null && String.class.isAssignableFrom(type);
}
//The name of the constraint, which the user of the plugin will use
//when working with your plugin.
@Override
String getName() {
return NAME;
}
//Validate this constraint against a property value,
//In this case, ONLY "Grails" is valid, everything else will cause an error:
@Override
boolean validate(target, propertyValue) {
propertyValue ==~ /^Grails$/
}
}
- Next, back in the Groovy plugin class that we looked at earlier, hook the above class into the plugin, using the "doWithSpring" closure to do so:
def doWithSpring = {
org.codehaus.groovy.grails.validation.ConstrainedProperty.registerNewConstraint(
BestFrameworkConstraint.NAME,
BestFrameworkConstraint.class);
}
- Now, back on the command line, navigate to within the "SamplePlugin" folder. There, run the following:
grails package-plugin
Back in the IDE, examine the ZIP file that the above command created:
That ZIP file is your Grails plugin.
Installing the Plugin
Now we will install our plugin in a new application.
- First, create a new Grails application by going to the New Project wizard (Ctrl-Shift-N) and choosing Groovy | Grails Application. Click Next and type "SampleApplication" and then click Finish.
- After the IDE has finished running the "grails create-app" command for you, you will see the new application open in the IDE. Right-click it and choose "Plugins", as shown here:
- In the Grails Plugins dialog, notice that the list gets filled with many potential plugins that you might want to install, from the Grails plugins repository. Instead, we'll install our own. Click Browse and browse to the ZIP file that we created three steps ago and notice that it appears in the text field at the bottom of the dialog:
- Click "Install" and then a progress bar appears, ending with the plugin being installed. Notice that you can also uninstall it:
- Take a look at your application and notice (in the Files window) what's happened to the plugin. It's been unzipped, plus the ZIP file is still there. And all that's been done in the "plugins" folder. Nothing else has changed, which means that uninstallation is as simple as removing the folder from the "plugins" folder:
Thanks to "convention over configuration", Grails knows exactly where everything is—so that, for example, the "plugin.xml" file that you see above, if found within the folder structure you see above, is the indicator to Grails that a plugin is available for use.
Using the Functionality Provided By the Plugin
- Let's now use our plugin. Create a domain class called "Quiz", after right-clicking the "Domain Classes" node and choosing "Create new Domain Class":
- Right-click the "Controllers" node and choose "Create new controller". Type "Quiz" and then click Finish. Use the Groovy editor to add one line for adding the scaffolding (and uncomment the other line):
- Back in the "Quiz" domain class, add your property and use the "oneCorrectResponse" constraint defined in your plugin, as shown here:
Note: The "oneCorrectResponse" constraint that you see above is the name of the constraint defined in the plugin.
- And then add the message to the messages.properties file, which is within the "Messages Bundles" node:
- Run the application and you will see that your constraint will prevent anything other than "Grails" from being considered acceptable, when "Create" is clicked below:
Congratulations, you've created, installed, and used your first Grails plugin!
posted on 2008-07-28 11:35
周锐 阅读(448)
评论(0) 编辑 收藏 所属分类:
Groovy&Grails