Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Groovy
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<p>Here are some larger examples of DSLDs.</p> <p>All scripts here are available under an EPL license. You are free to redistribute any of the scripts below, but please include the following header in the file:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> /******************************************************************************* * Copyright (c) 2011 Codehaus.org, SpringSource, and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Andrew Eisenberg - Initial implementation *******************************************************************************/ </pre></td></tr></table> <p>Feel free to add your own scripts to this page.</p> <img class="editor-inline-macro" src="/plugins/servlet/confluence/placeholder/macro?definition=e3RvY30&locale=en_GB&version=2" data-macro-name="toc"> <h3>Delegate</h3> <p>This DSLD handles the <code>@Delegate</code> AST transform through a call to <code>delegatesTo</code>.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> currentType(fields : fields(annotatedBy(Delegate))).accept { provider = "Delegate AST Transform" // fields is a collection of FieldNodes for (field in fields) { delegatesTo(field.type) } } </pre></td></tr></table> <p>Note that we could have used <code>bind</code> instead of <code>currentType</code> and had the same behavior.</p> <h3>Singleton</h3> <p>This shows how <code>@Singleton</code> is implemented. We need to explicitly use a bind pointcut here since we want to bind to the outermost pointcut.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> // Don't need to bind here since currentType is always available in a contribution block currentType(annotatedBy(Singleton)).accept { provider = "Singeton AST Transform" property name:"instance", type:currentType, isStatic:true, declaringType:currentType, doc:"Get the singleton instance of this Class" method name:"getInstance", type:currentType, isStatic:true, declaringType:currentType, doc:"Get the singleton instance of this Class" } </pre></td></tr></table> <h3>Mixin</h3> <p>The code for <code>@Mixin</code> looks like this:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.expr.ClassExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.ListExpression currentType(mixins: annotatedBy(Mixin)).accept { provider = "Mixin AST Transform" for (AnnotationNode mixin in mixins) { if (mixin instanceof AnnotationNode) { Expression expr = mixin.getMember("value") if (expr instanceof ClassExpression) { delegatesTo expr } else if (expr instanceof ListExpression) { for (Expression ex in expr?.expressions) { delegatesTo ex } } } } } </pre></td></tr></table> <h3>Newify</h3> <p>Here is the <code>@Newify</code> DSLD. This matches whenever an enclosing field, method, or class is annotated by <code>groovy.lang.Newify</code>. We add both the Python-style constructors and the Ruby style cosntructors.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.ConstructorNode; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.ListExpression; (enclosingMethod(newify: annotatedBy(Newify)) | enclosingClass(newify: annotatedBy(Newify)) | enclosingField(newify: annotatedBy(Newify))).accept { provider = "Newify AST Transform" for (AnnotationNode a : newify) { def classes = findClasses(a) println "CurrentType: " + currentType // when there are no classes in the list, then applies to all classes if (classes.isEmpty() || classes.contains(currentType)) { // no arg constructor // Python style method name: "new", type: currentType, declaringType: currentType, isStatic: true // Ruby style method name: currentType.nameWithoutPackage, type: currentType, isStstic: true for (cons in (currentType.declaredConstructors?: [])) { def extractedParams = extractParams(cons) // Python style method name: "new", type: currentType, declaringType: currentType, params: extractedParams, isStatic: true // Ruby style method name: currentType.nameWithoutPackage, type: currentType, params: extractedParams, isStatic: true } } } } // helpers // convert to a list of class nodes List<ClassNode> findClasses(AnnotationNode a) { def value = a.getMember("value") if (value instanceof ListExpression) { return value.expressions.collect{ it.type } } else if (value instanceof Expression) { return [value.type] } else { return [] } } // Convert Parameters to a map if String -> ClassNode def extractParams(ConstructorNode cons) { def params = [ : ] for (param in (cons.parameters ?: [] )) { params."${param.name}" = param.type } params } </pre></td></tr></table> <h3>SwingBuilder</h3> <p>Although this next example is quite long, it is fairly straight forward. We are just adding lots and lots and lots of methods to the <code>SwingBuilder</code> class. This script is only partially complete since we don't include documentation for all contributed methods. It might be possible to use <code>BeanInfo</code> to generate this script automatically.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> import groovy.model.DefaultTableColumn import groovy.swing.SwingBuilder import groovy.swing.impl.* import javax.swing.* import javax.swing.border.CompoundBorder; import org.codehaus.groovy.binding.* import java.awt.* currentType(SwingBuilder).accept { provider = "SwingBuilder DSL" method name: "action", type: Action, useNamedArgs: true, params: [name: String, shortDescription: String, smallIcon: String, accelerator:String, closure: Closure], doc: """ Actions are the lifeblood of a full fledged swing application. Other sources can expound on their usefullness. <br/> see <a href="http://groovy.codehaus.org/SwingBuilder.action">http://groovy.codehaus.org/SwingBuilder.action</a> """ method name: "frame", type: JFrame, useNamedArgs: true, params: [contentPane:Container, defaultCloseOperation:int, title:String, glassPane:Component, layeredPane:JLayeredPane, contentPane:Container], doc: """ Generates a JFrame. <br/> see <a href="http://groovy.codehaus.org/SwingBuilder.frame">http://groovy.codehaus.org/SwingBuilder.frame</a> """ // and so on... method name: "actions", type: List, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "bean", useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "bind", type: FullBinding, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "borderLayout", type: BorderLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "boundedRangeModel", type: DefaultBoundedRangeModel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "box", type: Box, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "boxLayout", type: BoxLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "button", type: JButton, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "buttonGroup", type: ButtonGroup, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "cardLayout", type: CardLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "checkBox", type: JCheckBox, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "checkBoxMenuItem", type: JCheckBoxMenuItem, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "closureColumn", type: DefaultTableColumn, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "compoundBorder", type: CompoundBorder, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "colorChooser", type: JColorChooser, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "comboBox", type: JComboBox, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "container", type: Container, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "desktopPane", type: JDesktopPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "dialog", type: JDialog, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "editorPane", type: JEditorPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "emptyBorder", type: border.EmptyBorder, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "etchedBorder", type: border.EtchedBorder, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "fileChooser", type: JFileChooser, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "flowLayout", type: FlowLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "formattedTextField", type: JFormattedTextField, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "gbc", type: GridBagConstraints, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "gridBagConstraints", type: GridBagConstraints, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "glue", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "gridBagConstraints", type: GridBagConstraints, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "gridBagLayout", type: GridBagLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "gridLayout", type: GridLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "hbox", type: Box, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "hglue", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "hstrut", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "internalFrame", type: JInternalFrame, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "label", type: JLabel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "layeredPane", type: JLayeredPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "list", type: JList, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "loweredBevelBorder", type: border.BevelBorder, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "loweredEtchedBorder", type: border.EtchedBorder, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "map", type: Map, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "matteBorder", type: border.MatteBorder, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "menu", type: JMenu, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "menuBar", type: JMenuBar, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "menuItem", type: JMenuItem, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "optionPane", type: JOptionPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "overlayLayout", type: OverlayLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "panel", type: JPanel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "passwordField", type: JPasswordField, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "popupMenum", type: JPopupMenu, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "progressBar", type: JProgressBar, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "propertyColumn", type: table.TableColumn, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "radioButton", type: JRadioButton, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "radioButtonMenuItem", type: JRadioButtonMenuItem, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "rigidArea", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "scrollBar", type: JScrollBar, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "scrollPane", type: JScrollPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "separator", type: JSeparator, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "slider", type: JSlider, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "spinner", type: JSpinner, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "spinnerDateModel", type: SpinnerDateModel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "spinnerListModel", type: SpinnerListModel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "spinnerNumberModel", type: SpinnerNumberModel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "splitPane", type: JSplitPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "springLayout", type: SpringLayout, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "tabbedPane", type: JTabbedPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "table", type: JTable, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "tableColumn", type: table.TableColumn, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "tableLayout", type: TableLayoutRow, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "tableModel", type: table.TableModel, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "td", type: TableLayoutCell, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "textArea", type: JTextArea, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "textField", type: JTextField, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "textPane", type: JTextPane, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "toggleButton", type: JToggleButton, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "toolbar", type: JToolBar, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "tr", type: TableLayoutRow, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "tree", type: JTree, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "vbox", type: Box, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "vglue", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "viewport", type: JViewport, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "vstrut", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "widget", type: Component, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" method name: "window", type: JWindow, useNamedArgs: true, doc: "See <a href=\"http://groovy.codehaus.org/Swing+Builder\">http://groovy.codehaus.org/Swing+Builder</a>" } </pre></td></tr></table> <h3>DSLD Meta Script</h3> <p>Finally, here is the script that defines editing support for DSLDs themselves. A few comments:</p> <ul> <li>Notice the use of <code>wormhole</code> to store the declaration of binding names so that they can appear in content assist later.</li> <li>We are accessing the <code>org.codehaus.groovy.eclipse.dsl.script.PointcutFactory</code>, which is a class defined inside of Groovy-Eclipse where all of the pointcuts are registered. Doing this ensures thatthe list of pointcuts available for content assist is always synchronized with what is available in Groovy-Eclipse.</li> <li>There is a mock interface <code>IPointcut</code> that is defined. It is based on an internal interface of the same name, but in a different package. <code>IPointcut</code> only exists in the script so that the <code>accept</code> method will not be underlined.</li> <li>This script is long and complicated, but it shows many of the features available in the DSLD language.</li> </ul> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.MapEntryExpression /** * This is the meta DSL descriptor for *.dsld files. */ // first thing to do is to check that versions are correct // for this script to be evaluated any further, all conditions must be met // also supports grailsTooling and sts, which are synonyms and correspond to the STS version eg- 2.6.0 // we can add more version checking on request supportsVersion(groovy:"1.7.8",groovyEclipse:"2.1.3") interface IPointcut { /** * Accepts a contribution group to this Pointcut. What this means * is that whenever this pointcut evaluates to a match, then the * contribution group is evaluated with the bindings that have * been generated from the pointcut match * * @param c the contribution group to accept */ def accept(Closure c); } // You can store shared pointcuts in a variable // This particular pointcut matches all join points that are inside of a // groovy project and inside a file with a *.dsld extension and are scripts def dsldFile = nature("org.eclipse.jdt.groovy.core.groovyNature") & fileExtension("dsld") & isScript() // You can also create a closure around pointcuts and assign them to // a variable. Note that when using these variables, you must include parens. def insideContribution = { enclosingCallName("accept") & inClosure() } // Ensure that the 'accept' method is available for all closures and variables that correspond to pointcuts (dsldFile & ( ~ insideContribution() ) & ( ~currentType(subType(Script)) )).accept { delegatesTo IPointcut } // here we store all bound names inside of the wormhole so that they can be available later (dsldFile & enclosingCallDeclaringType(subType(Script)) & (~ enclosingCallName("supportsVersion")) & ( ~ inClosure() ) & bind(var : currentIdentifier())).accept { if (enclosingNode instanceof MapEntryExpression && var.contains(((MapEntryExpression) enclosingNode).keyExpression)) { def bindings = wormhole.bindings if (!bindings) { bindings = [ ] wormhole.bindings = bindings } var.each { bindings << it.text } } } // Define the kinds of pointcuts // note the different ways of calling the two composite pointcuts // Also, be careful to use parens around negation '~' since operator precedence may make the '~' apply to the call to 'accept' (dsldFile & ( ~ insideContribution() ) & currentType(subType(Script)) & (~enclosingCallName("registerPointcut")) & currentTypeIsEnclosingType()).accept { provider = "the meta-DSLD script" // in here, we can list all pointcuts explicitly, or we can access the internal PointcutFactory object // A little bit naughty, but this is the easiest way to maintain consistency with all possible pointcuts // ...the PointcutFactory class is a secret class that is declared by groovy-eclipse // Yes, you can use many Eclipse classes here. The editor won't like them, so they must be fully qualified // and you cannot import them or use them as types for variables Map<String, String> pointcutNames = org.codehaus.groovy.eclipse.dsl.script.PointcutFactory.docRegistry for (pointcutName in pointcutNames.entrySet()) { method name : pointcutName.key, type: IPointcut, params : [pointcutArg : Object], doc : pointcutName.value } method name : "supportsVersion", type : void, params : [versionKindToName : Map.class ], doc : '''Specifies that this script is only active when the specified version constraints are met. Currently, only 3 constraints are available: groovy, groovyEclipse, sts, and grailsTooling.<br><br> Use like this: <pre>supportsVersion(groovy:"1.7.10",groovyEclipse:"2.1.3")</pre> This means that the current scipt requires <b>both</b> Groovy 1.7.10 or later and Groovy-Eclipse 2.1.3 or later''' method name : "registerPointcut", type : void, params : [name : String, pointcutBody : Closure], doc : ''' Registers a custom pointcut. This pointcut is only available from within the current script. You must specify a name for the pointcut as well as a closure that evaluates whether or not there is a match''' } // Here, specify everything that can be used inside of an accept block (also called a Contribution Group) (dsldFile & insideContribution()).accept { provider = "the meta-DSLD script" property name : "provider", type : String, doc : """Specifies a <em>Provider</em> for the current contribution. This provider is displayed during content assist and in other places to give a quick hint as to where this contribution elementcomes from.""" method name : "property", useNamedArgs : true, params : [name : String, type : Object, isStatic : boolean, declaringType : Object, provider: String, doc : String], doc : """ Specifies a new property contribution. <b>name</b> is mandatory, but all other parameters are optional. """ method name : "method", useNamedArgs : true, params : [name : String, type : Object, params : Map, useNamedArgs : boolean, isStatic : boolean, declaringType : Object, provider: String, doc : String], doc : """ Specifies a new method contribution. <b>name</b> is mandatory, but all other parameters are optional. """ method name : "delegatesTo", params : [ type : Object ], doc : """ Specify that the currentType delegates tp the given type. The currentType is the type being analyzed. And the given type is specified as a parameter (either a String, Class, or ClassNode). All fields and methods of the given type will be available from the currentType. """ method name : "delegatesToUseNamedArgs", params : [ type : Object ], doc : """ Specify that the currentType delegates tp the given type. The currentType is the type being analyzed. And the given type is specified as a parameter (either a String, Class, or ClassNode). All fields and methods of the given type will be available from the currentType.<br/><br/> Named arguments will be used for all methods. """ property name : "wormhole", type : Map, doc : """Use the wormhole to stuff in values calculated in one contribution group to make it available later in another contribution group""" property name : "currentType", type : ClassNode, doc : "This is the declaring type of the current expression being evaluated." property name : "currentNode", type : ASTNode, doc : "This is the ASTNode being evaluated" property name : "enclosingNode", type : ASTNode, doc : "This is the ASTNode enclosing the ASTNode being evaluated" // Now, extract all bindings from the wormhole and add them as contributions for (binding in wormhole.bindings) { property name : binding, doc : "Binding created from pointcut" } } // Add the contributions for inside a "registerPointcut" call. User-registered pointcuts are // not fully fleshed out yet, so best not to use them yet. (dsldFile & inClosure() & enclosingCallName("registerPointcut")).accept { property name : "currentScope", type : org.eclipse.jdt.groovy.search.VariableScope property name : "currenType", type : ClassNode } </pre></td></tr></table>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced