tags:

views:

189

answers:

1

I had an idea and I wanted to run it by you to get some feedback. Please look the following over and let me know what you think, whether it's positive or negative.

I've always wished that there was a way to embed certain pieces of data in Java code without having to follow Java's rules all the time. I've heard a lot of talk about Domain Specific Languages lately (DSLs) and how it would be great if we could utilize them more on a daily basis. I think I have an idea of how to do this in a reasonably elegant way.

Here are some examples of things that I know of that are a pain to represent in Java code (and other C-like languages) that I want this to solve:

List of short strings as string array

String[] ar = { "Item1", "Item2", "Item3", "Item4" };

List of long strings as string array

String[] ar = { "The quick brown\n fox jumped over\n the lazy dog.",
"The quick brown\n fox jumped over\n the lazy dog.",
"The quick brown\n fox jumped over\n the lazy dog.",
"The quick brown\n fox jumped over\n the lazy dog.",  };

Table of strings as multi-dimensional string array:

String[][] ar = { { "InvoiceID", "Date", "SubTotal", "Tax", "Total" },
{ "1", "1/2/2009", "300, "21", "321" },
{ "2", "1/4/2008", "100", "7", "107" },
{ "3", "1/6/2008", "200", "14", "214" } };

List of key-value pairs

Map states = new HashMap();
states.add("FL", "Florida");
states.add("OH", "Ohio");
states.add("GA", "Georgia");
states.add("NY", "New York");
states.add("SC", "South Carolina");

HTML code single string

String html = "<a href=\"www.somesite.com\">Some site</a>";

HTML text block with decent text formatting

String html = "Hi, John,\r\n<br>\r\n<br>Thank you for writing to us. We do not currently carry that specific product.\r\n<br>\r\n<br>Regards,\r\n<br>";

I've investigated the following described solution a bit and I believe it's possible to create a usable library that would allow you to achieve this elegantly. In Java 5 and 6 there is something called the Annotation Processor Tool (APT) (not the same as Debian APT). You create your own source code processor, which will be called as the code is being compiled to give you the opportunity to rewrite the source code. After rewriting the code it is compiled as usual.

The following must be done to make use of APT: 1. Put this library's jar on the ANT classpath. 2. Put this library's jar on the project classpath. 3. Call the apt task instead of javac and add the preprocessdir parameter to specify where the generated files must be placed.

The DSL code can be placed inside a comment right after the variable where the result of the code will be placed. When the processor runs it can look forward in the code for the next comment, extract the code, run it through the processor, generate the code and do the compile.

Here is the list again, this time with what it could look like:

List of short strings as string array

@DslTextArray
String[] ar = null; /* Item1, Item2, Item3, Item4 */

List of long strings as string array

@DslMultilineTextArray
String[] ar = null;
/*
The quick brown
fox jumped over
the lazy dog.

The quick brown
fox jumped over
the lazy dog.

The quick brown
fox jumped over
the lazy dog.

The quick brown
fox jumped over
the lazy dog.
*/

Table of strings as multi-dimensional string array or JTable:

@DslTextTable
String[][] ar = null;
/*
InvoiceID,Date,SubTotal,Tax,Total
1,1/2/2009,300,21,321
2,1/4/2008,100,7,107
3,1/6/2008,200,14,214
*/

List of key-value pairs

@DslMap
Map states = null; /* FL=Florida, OH=Ohio, GA=Georgia, NY=New York, SC=South Carolina */
// Could also put each pair on a new line

HTML code single string

@DslText
String html = null; /* <a href="www.somesite.com">Some site</a> */

HTML text block with decent text formatting

@DslText
String html = null;
/*
Hi, John,

Thank you for writing to us. We do not currently carry that specific product.

Regards,
Mike
*/

Some requirements/features I can think of for this solution:

You must declare the variable to hold the data that the script will generate in the Java source code. This allows the rest of the source code to know about the resulting data even though the compiler doesn't know where it's coming from.

  • Must not violate the Java language so that the IDE and javac do not show errors.
  • Work with all the existing Java code you have. No need to replace any existing code. Just add these snippets wherever you like.
  • Must be easily extensible with additional types.
  • Must be able to later make extensions to IDE's that allow for source-code highlighting and auto-completion.
  • Translations occur at compile-time so valid Java code must be generated.
  • Convert to String and String[] for things like lists, multi-line text blocks such as CSS, SQL
  • Convert and encode XML, HTML
  • When code is rewritten retain the same line numbers. Do not add any lines so that debugging and reading errors does not become a pain.
  • Run code written in any BSF language at runtime. Allow it to pass any parameter to the script and return any Java class or primitive back to Java.
  • Run code written in any BSF language at compile-time to generate Java source code. Similar to how M4 is used on Linux.
  • Later: Allow you to chain together the String results from many calls to build a long string. Some if it may be compile-time, some of it run-time.

Again, I would really appreciate getting some feedback on this. Is this a stupid idea? Is there something like this out there already? Would you bother using something like this or should I just keep it to myself?

+1  A: 

This is feasible for sure, but I must say I don't like it to much.

It makes initialization of datastructures a little more easy,

BUT

  • I extremley rarely need to initialize datastructures like this with compile time constants. So a separate file nexht to the class/java file would be more usefull

  • This is not at all transparent for developers. Nobody expects comments to transform into data. Actually if a came across such a comment, I'd probably consider it commented old code and delete it immediately

  • ATP is a powerfull and interesting tool, yet the IDE integration is lacking. So you would have to build and run your application using ANT all the time, which is just not as nice and fast as hitten F11 or whatever shortcut your IDE offers for that purpose

So basically you take a huge hit in development infrastructure complexity for a minimal gain in typing speed.

Still the idea is interesting. I actually would apreciate a variation, where one could define a annotation of type "DSL" allowing to put code into that annotation in an arbitrary language defined by the annotation declaration. Of course that would be a major language change and won't happen anytime soon, and probably not at all.

Jens Schauder
Code that gets executed in comments can definitely cause problems for developers, but I do think this can be controlled by mentioning this to new contributors. My examples don't actually include any BSF scripts, which is what most people would probably use this for. I'll see about adding that.
sjbotha
Netbeans does use ant and build.xml so you can modify it and replace javac with apt. Doesn't Eclipse use ant for its building? Are you talking about a different IDE? Agreed, I doubt they'll support a feature like this natively in the language.
sjbotha
No Eclipse does not use ANT for building. It does it's own incremental build thing. It has a builder for APT (I think), but it didn't integrate well with the incremental building. At least that is the information I gathered about a year ago
Jens Schauder