X

Geertjan's Blog

  • March 24, 2008

Hello Spring (Part 2)

Geertjan Wielenga
Product Manager
The cool thing about the new Spring support in NetBeans IDE 6.1 is the fact that you can extend it. A very simple entry point into the Spring support is its dedicated MIME type, x-springconfig+xml. Via this MIME type, you can add a new menu item, either to the editor or to the node in the explorer view, specifically for Spring configuration files. Using this technique, I added a menu item called "Generate Java from Beans":

What happens when the menu item is selected? You get some Java code generated at the bottom of the file, for accessing each bean, which you can then copy into your Java classes, wherever the code is needed. Maybe it would be nice if this were integrated into the Java classes, so that the beans would appear during code completion, but that's a couple of bridges too far for me at the moment, I'd need to do a bit of research for that. Currently I'm only supporting the util:list bean, but it would be simple to expand this to all other types. Here's the result for the above two beans, i.e., everything that is commented out below is generated when the menu item above is selected:

And here's the relevant performAction in my CookieAction. Take particular note of org.openide.xml.XMLUtil which, if you're not aware of it, is very useful indeed (even more so if you're aware of it):

protected void performAction(Node[] activatedNodes) {//Figure out the name of the configuration file,
//plus its packages, plus "src",
//which is what the org.springframework.core.io.FileSystemResource class needs:

DataObject dobj = activatedNodes[0].getLookup().lookup(DataObject.class);
FileObject fo = dobj.getPrimaryFile();
setFileName(fo.getPath().substring(fo.getPath().indexOf("src")));
try {//Figure out the document and parse it:
EditorCookie editorCookie = activatedNodes[0].getLookup().lookup(EditorCookie.class);
StyledDocument styledDoc = editorCookie.openDocument();
String allText = styledDoc.getText(0, styledDoc.getLength());
InputSource source = new InputSource(new StringReader(allText));//No validation, not namespace aware, no entity resolver, no error handler:
Document doc = XMLUtil.parse(source, false, false, null, null);//Figure out the list of elements:
NodeList list = doc.getElementsByTagName("\*");
int docLength = list.getLength();
for (int i = 0; i < docLength; i++) {
org.w3c.dom.Node node = list.item(i);//Figure out the list of attributes:
NamedNodeMap map = node.getAttributes();
int mapLength = map.getLength();
for (int j = 0; j < mapLength; j++) {
org.w3c.dom.Node attr = map.item(j);//Insert the template, with values filled in,
//if the attribute is "id":

if (attr.getNodeName().equals("id")) {
setBeanId(attr.getNodeValue());
styledDoc.insertString(styledDoc.getLength(),
"\\n<!-- How to access the \\"" + attr.getNodeValue() +
"\\" bean:\\n" + getTemplate(), null);
}
}
}
} catch (SAXException ex) {
Exceptions.printStackTrace(ex);
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}

And, FWIW, here's the template:

private String getTemplate() {
template =
"\\nBeanFactory factory = new XmlBeanFactory(new FileSystemResource(\\"" + getFileName() + "\\"));" +
"\\nArrayList list = (ArrayList) factory.getBean(\\""+getBeanId()+"\\");" +
"\\nIterator it = list.iterator();" +
"\\nint count = 0;" +
"\\nwhile (it.hasNext()) {" +
"\\n count = count + 1;" +
"\\n System.out.println(\\""+getBeanId()+" \\" + count + \\": \\" + it.next().toString());" +
"\\n}" +
"\\n-->\\n";
return template;
}

Join the discussion

Comments ( 7 )
  • Ramon Tuesday, March 25, 2008

    Hi Geertjan,

    maybe better than DOM for supporting other beans if you use Spring yourself to access the beans in the config file:

    ListableBeanFactory factory = new XmlBeanFactory(resource);

    //beansmap contains entries with mapping: name of bean -> instance of bean

    Map<String, Object> beansMap = factory.getBeansOfType(null);

    System.out.println("spring beans map: " + beansMap);

    Then you can query the class of the individual beans and decide what to output based on that.


  • Mark Ashworth Tuesday, March 25, 2008

    Hi Geertjan,

    I have two questions:-

    1. Is there a way to make the context window that pops up with XML (and Spring context) a bit more condensed by making some of the items not so large?

    2. Is there a way to add validators to the spring context file so that it can detect if a class is not in the class path?

    Regards,

    Mark P Ashworth


  • Geertjan Tuesday, March 25, 2008

    Thanks Ramon! Now the output is as follows:

    spring beans map: {names=[john, jack, peter, pavel], emails=[john@smith.org, jack@harry.org, peter@piper.org, pavel@prochazka.org]}

    And, like you said, now other beans are automatically supported, since there's no requirement for the result to be an ArrayList.


  • Ramon Tuesday, March 25, 2008

    Although the DOM approach is actually much safer, because you don't risk starting servers (like RMI, JMX) or accessing remote services and the like when the beans are created ...


  • Radhika Tuesday, May 27, 2008

    Hi I am not able to see the generate java feom beans option in netbeans ide.

    Kindly help.


  • Geertjan Tuesday, May 27, 2008

    That's because it doesn't exist. This blog entry is about how you would create it via a plugin.


  • guest Friday, June 6, 2008

    sdewe


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.