I reduced all the code shown yesterday, by Oliver Schmitt, who works on NetBeans at the French Ministry of Agriculture, to this:
Wait a minute, what happened to all of Oliver's code? How can the code completion for the "lang" attribute in text/xhtml work if there's no code in the module at all?
Well, the answer is found in the "package-info.java" class above:
@HTMLAttributeCompletionRegistration( id="jee-architect-cookbook-netbeans-iso6391-LanguageAttributeCompletionProvider", attribute="lang", iconBase="jee/architect/cookbook/netbeans/iso6391/bubble.png", content="jee/architect/cookbook/netbeans/iso6391/ISO6391.csv") package jee.architect.cookbook.netbeans.iso6391; import org.netbeans.cra.api.HTMLAttributeCompletionRegistration;
That's the only code in that Java class. And, also, that's the only code in the entire module.
When the module is compiled, the annotations shown above are converted to this in the generated-layer.xml file:
<folder name="Editors"> <folder name="text"> <folder name="xhtml"> <folder name="CompletionProviders"> <file name="jee-architect-cookbook-netbeans-iso6391-LanguageAttributeCompletionProvider.instance"> <attr name="iconBase" stringvalue="jee/architect/cookbook/netbeans/iso6391/bubble.png"/> <attr name="attribute" stringvalue="lang"/> <attr name="content" stringvalue="jee/architect/cookbook/netbeans/iso6391/ISO6391.csv"/> <attr methodvalue="org.netbeans.cra.spi.HTMLAttributeCompletionProvider.create" name="instanceCreate"/> </file> </folder> </folder> </folder></folder>
The most important part of the above is the "methodvalue" attribute, which is where the map of attributes is magically passed. The "HTMLAttributeCompletionProvider" is taken directly from Oliver's code yesterday, as well as all the other classes from his module, which I've simply made more generic so that any attribute can be passed in:
This is only a proof of concept. The next steps would be to let you provide multiple different attributes, so that the provided code completion words can be made available to multiple attributes simultaneously, as well as multiple different annotations within the same package-info.java class:
@HTMLAttributeCompletionRegistrations({ @HTMLAttributeCompletionRegistration( id = "jee-architect-cookbook-netbeans-iso6391-LanguageAttributeCompletionProvider", attribute = "lang", iconBase = "jee/architect/cookbook/netbeans/iso6391/bubble.png", content = "jee/architect/cookbook/netbeans/iso6391/ISO6391.csv", contentType="csv"), @HTMLAttributeCompletionRegistration( id = "jee-architect-cookbook-netbeans-iso6391-BlaAttributeCompletionProvider", attribute = "bla", iconBase = "jee/architect/cookbook/netbeans/iso6391/bla.png", content = "tom,dick,harry", contentType="basic") }) package jee.architect.cookbook.netbeans.iso6391; import org.netbeans.cra.api.HTMLAttributeCompletionRegistration; import org.netbeans.cra.api.HTMLAttributeCompletionRegistrations;
In the annotations above, I have defined that the "lang" attribute and the "bla" attribute will have code completion defined by the "content" attribute (notice that there are now different types of content, distinguished via the "contentType" attribute, e.g., imagine another one one for "json", for example, and then you have a starting point for accessing code completion words online, maybe exposed via a RESTful web service) and the "iconBase" attribute.
Ultimately this could be made even more generic, e.g., instead of assuming text/xhtml, require the user of the annotation to provide a MIME type and then process the content accordingly. Also, consider the possibilities in other areas, e.g., you could create annotations for the NetBeans HyperlinkProvider and register your implementations in the package-info class, consisting of annotation attributes for MIME type, a matcher pattern, and instructions for what should happen when the hyperlink is selected and clicked.
All the code you see above is freely available here:
You would need to install both modules, i.e., the module providing the annotation and the module that makes use of it, into NetBeans IDE and then the code completion will be available as defined by the @HTMLAttributeCompletionRegistration annotation.
Note: If you're not amazed yet, consider how easily this solution lets you create multiple HTML attribute code completions. The process is now a trivial question of registering lists of words, attributes, and the related icons!
Another interesting thing to explore would be to let the CSV files be loaded externally, i.e., the user would create on disk a CSV file, somehow map that CSV file to an attribute, e.g., in the netbeans.conf file there'd be a "key/value" pairing of "attribute/file.csv", which a NetBeans module would parse and then map the content of the file to the associated attribute. That way, the NetBeans IDE user, without needing to have available or create a new NetBeans module that uses the annotations above, would have control over the code completion for whichever attribute is of interest to them.
Happy new year everyone and have fun with NetBeans IDE in 2013!