Monday, August 29, 2005

Copyright Folding

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Most source files have copyrights on them. When opening a file you have to scroll
past the copyright, and the import statements, before you get to the interesting part -
the class javadoc comment. Most IDEs now have a way to have the import section automatically
folded. But what about the copyright section? It's often quite large - in Apache
source code for example the copyright is 50 lines long - that's more than a full
editor page. Code folding to the rescue!



NetBeans has support for user-defined folds. In Creator, we use this to hide
the bean getters and setters, since that segment of code is never interesting
to a user, but nevertheless should be part of the source file and discoverable and
editable by expert users.



You can use this facility yourself to create arbitrary folds around code.
One obviously place to do this is around your copyright sections. These are ideally
suited because a copyright is a piece of static text which is replicated in each and every
source file. Just change your copyright template once, and from now on all new files
will have folded copyrights. In the Creator source base we have marker tokens in the
copyrights such that we can update the copyright sections in an automated yet safe way.



(Note: In NetBeans 4.2 you can set an option to have the first comment in the
document automatically folded. This will also achieve copyright folding if it's
the first comment in the document. Of course, you can apply folding to other logical
portions in your document too - there's nothing comment-specific about user folds.)



Here's how user-defined folds work: Simply add two Java line comments (//), one
to indicate the start of the fold, and one to indicate the end. The comment
itself has an XML-like syntax:



// <editor-fold defaultstate="collapsed" desc="Your Fold Comment">


You can leave out the defaultstate attribute if you don't want the
fold to default to a folded state when the file is opened. Obviously the
desc field is used to supply a description which is shown when
the section is folded. Note that the comment isn't truly in XML format in the
sense that you cannot reorder these attributes.



Let's see how this works in practice. Here's one of my source files, using
the short copyright version. Most other file licenses I've seen have a much
larger copyright than this, so the folding payoff is higher.





First I simply add the begin and end folding comments as described above around
the code I want folded.






Now, when I open the file (or collapse the file by clicking on the - in the margin),
the copyright takes up just a single line, and the fold description is displayed instead:






Finally, note that you don't have to expand a fold to see what's inside - simply
hover the mouse over the folding box and the contents are displayed as shown here:





Coding Style - The Rest Of It

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


There are several coding style documents. The primary one is probably the JDK style,
documented here. The problem with that document, and others like it,
is that they leave a lot out.



I found some other useful coding style
documents, but I disagree vehemently with some of their rules (like open braces on a separate line,
and underscore suffixes and fields, and indentation level 2) so instead I will present
my own delta from the "official" JDK style:



So, with the following I'd like to put a stake in the ground, and describe my own
style preferences as additional rules to be added to the JDK style.
I should point out that these aren't rules I've invented - they are rules I've
learned from either discussing with, or reading code written by, developers I admire.



So, without further ado, here are my additional rules:



  • Never use Tabs. Some people like tab characters because it's easy to
    jump back and forth full indentation levels by just pressing arrow left and right over
    these. However, this benefit does not nearly make up for the disadvantages: different
    tools assume different tab sizes, and things get really messy when you have files with
    spaces in some places and tabs in others. Just don't do it.
    This issue has been around for a long time, and I figured the style guide would
    discuss it, but they left it an open issue. Cowards! :-)





  • Never capitalize Acronyms. Yes, unlearn everything your English teacher told you
    about acronyms. Remember, camel cased program identifiers aren't English words anyway!
    For example, HTMLDocument should be named HtmlDocument.
    CSSParser should be CssParser. This makes the code easier to
    read and easier to visually scan. Plus it's prettier.





  • Don't use underscores in variable names. I didn't say Never, since there's one
    exception: for constants, the constant should be fully upper cased, and words separated
    with an underscore, e.g. MAX_VALUE or INITIAL_VELOCITY. But never ever create variable
    names like "max_count" or worse yet, "_count".





  • Don't use Hungarian Notation. This is where you prefix variable names
    to tell you whether these methods are locals or class fields, etc. This makes the
    code less readable (even if you can infer more state from studying the code).
    And uglier. Ugly is bad.





  • Don't put in obvious initialization. This is not a big deal, but again
    in the interest of readable code: don't state the obvious. When you're declaring
    class fields, there's no need to assign booleans to false, references to null, etc.
    Use

    private boolean foo;
    private Bar bar;

    instead of

    private boolean foo = false;
    private Bar bar = null;





  • Don't add your initials in comments. Some developers like to leave
    their initials next to comments, e.g. // TN Handle abnormal exit here. People
    from Borland seem especially fond of this. I don't think this is a good habit.
    The comment should be self-descriptive, regardless of who added it. If it represents
    an action that needs to be taken, then add the token "reserved" for this: TODO.




  • Don't use recursion where simple iteration would work. I recently
    came across a code fragment that was simply walking up the parent chain to look
    for a particular ancestor. This was done using recursion! This should be done
    with simple iteration. Iteration in this case is clearer than the "mathematical"
    approach.




  • Use this.foo = foo; for construction field initialization. If your class
    has a property foo, then name your constructor parameter name the same thing, and
    initialize it using the this-pattern shown. Don't use other variations like naming the
    parameter newFoo or worse yet, something involving an underscore in the parameter name!




  • Write debuggable code!. I've seen many people argue that you should use the ternary
    operator (a ? b : c) instead of if-then-else constructs. While the ? operator certainly makes
    for more compact code, this code is often hard to debug, because you cannot easily set breakpoints
    on one condition and not the other, and you cannot easily step to see which condition is taken.
    This is an "issue to consider" more than a "rule to follow" since there are tradeoffs, and
    I use both forms, depending on the context.









Friday, August 26, 2005

Say Hi To Marco

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Say hello to Marco "Deployment" Walther - another developer on the Creator team.
He has just started blogging.



In addition to being in charge of all the deployment
machinery in Creator, he's also the guy to go to if you have any Linux questions. Which should be obvious from his second post!


Fly your own airplanes!

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


I was just going through my buglist for the webform designer in Creator, and came across this request:



Synopsis: way to turn off GIF animation in designer

Description: Maybe this is simply an IDE option for Visual Editor.
I'm inclined to think the default should be off.
They can be pretty distracting...




In case you didn't realize it, if you insert animated gifs in your web page, the designer will preview
the animation at designtime too. Here a user is asking for the ability to turn this off, since animated gifs
are distracting.



My first thought was: You are about to inflict annoying
animation on your users, so shouldn't you have to put up with this yourself? It's a bit like the reverse
dog food test.

Or, more recently at Sun we like to say we "fly our own airplanes" - e.g. use our own products.
I'm not sure where the saying comes from, but clearly as a customer you have more confidence flying in a
plane knowing that the people who built the plane also fly it. The reverse situation is that if you don't want to fly your
own airplanes, you shouldn't force your customers to either. And that's what asking for distracting images
to be hidden at designtime sounds like to me.







By that line of reasoning I guess I should implement designtime support for the
<blink> tag as well!
And it raises the question of what I would do if users requested a new JSF component which creates a pop up ad
in user browsers, one smart enough to defeat most popup blockers.



Making it easy for people to create annoying web apps feels a bit like making weapons... on the other hand
I'm probably getting way out of hand here. Simple banner ads are used to pay for web sites that are free for use,
many of which I use. And of course, even Creator has been
advertized using banner ads.


Monday, August 22, 2005

Portlet Demo

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Navaneeth Krishnan has created a portlet demo
using Creator 2 EA, showing how the basic Creator WYSIWYG design of web apps applies to portlets as well. Check it out.



By the way.... Creator 2 EA Refresh, coming soon to a download center near you... (sorry, can't be more specific with dates)


Sunday, August 21, 2005

Submit Query? What Query?

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


You've just built a web form. Users type in a message in a text area, then
click on a Submit button to send the message. You run the application, and
.... what? The browser has changed your Submit button into "Submit Query"!
What Query? There's no query here!


We've had some bugs filed against Creator on this. In some browsers
(notably Mozilla and Firefox), submit buttons change their labels into
"Submit Query".










Form built in CreatorForm deployed and shown in Firefox







This is a symptom of a much deeper problem, which I'd like to discuss in this
blog entry.



Let's say you drop a button. This will create a button, but no label has
been set on the button - look at its text property in the property sheet.
A button component with no label set will render to this HTML:



<input type="submit" />


This will not display a blank button (which you can achieve by adding value="") -
all browsers will pick a default label! Internet Explorer, Safari, and most other browsers use the label
"Submit". Mozilla/Firefox on the other hand, uses "Submit Query" - which I think is an odd choice.
Creator has to choose something - it cannot show the "right" thing since
that will depend on which browser the application is viewed with - and
there could be a different browser for each user accessing the same web page!



There is an easy fix to this - go and set the value of the button to
a specific string, like "Submit" (or Send or Order or Lookup or whatever
makes sense on the current page.) In recent dev-builds of Creator, we've
made some changes such that you don't end up in the scenario of an unset
button as easily.



But this raises the question of why we don't set the text to some default
value automatically. For a button, we probably could (and have - see above).
But for components like Static Text, we can't. The reason for that is that
it would make it very hard to set the text value from code!



Let's say you've dropped a Static Text component on the page, and you've
set its text attribute to "Hello World", so your JSP contains this:



<ui:staticText text="Hello World" binding="#{Page1.staticText1}" />


Now you're trying to do something clever in your Java code, for example
setting the text to include the name of the logged in user:



// In Page1's constructor
staticText1.setText("Hello " + getUserName());


This won't work! Note that there is a conflict of definitions here - the
JSP says that the text should be "Hello World", and the page constructor
says that the text should be "Hello Tor". And the JSF spec says:


The JSP attribute wins.


You might try to move the above code into the new init()
method, or even the prerender() method, but that won't help -
the JSP attribute setting will still win the first time the page is displayed.



The only way to get your Java code to be able to set the static text, is
to remove the attribute setting from the JSP.



And this is precisely why, when you drop a Static Text component on a page,
we don't automatically set it to some "default" value. We could (and in
early devepment versions did), but most users are not aware of
the JSP vs Java conflict, and did not understand why their Java code which
set labels didn't work. Granted, in most cases you don't want to set the
label from code - you'll use value binding expressions instead. But it's
an important enough scenario that we don't want to get people too frustrated
when they run into this.



So, the solution we've settled on is using what we call shadow text*.
When a component is rendered at designtime, and it's missing a value that's
vital (but one we don't want to set to avoid conflicts), we render the component text in
bold italics instead, using a default label such as the type of the component.
This shows you that there is a component here (since otherwise a
static text with no actual text is rather hard to read...) and allows you manipulate
it. But it's also obvious, or at least we hope so, that the component is not
configured with normal text. As soon as you set a specific value for the property,
it's rendered in the usual way.



Here's how this looks for buttons, static texts and hyperlinks - the first row
shows components with shadow text:






*: I don't think this is "official" terminology - it was simply called that
in a recent bug report, and once I realized what they were describing I figured
it's as good a name as any. Before that I had called it "uninitialized/bold/italic text"
which is a mouthful...


Tuesday, August 16, 2005

In Prague

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.





I'm in Prague this week, visiting the NetBeans team. NetBeans of course is the foundation
Creator is built on top of. We're working closely together to make sure that we get everything
we need, and to align work and vision such that we're heading in the same direction.



I've seen some of the new stuff coming in the next release of NetBeans - 4.2. It's documented
in the
this document, which is
similar to the "New and Noteworthy" documents Eclipse publishes for their milestones. If you're
wondering what "Q-Build" refers to in that document, a "Q-Build" is a "quality-build". It's a
promoted build (roughly weekly) from the nightly builds, that has had some QA analysis applied
to it and showstoppers fixed. There's a separate document for
new and noteworthy
features in the mobility pack.



...and of course, I saw some cool new stuff that hasn't been integrated (and therefore listed) yet!



Prague is a beautiful city. I have been here many times before (I think this is my eighth trip)
but it never ceases to impress. I haven't done any sightseeing on the last trips so I think
I'll go back and visit the castle if I get some time Friday morning. The best way to get around
is to use the underground. The metro runs deep below the ground, so to get down to the tracks
they have these really really long escalataors -- see the picture on the right (and note that
it continues up above the lighting fixture). On my first trips here I was amazed at how fast
the escalators were running! They don't seem as fast anymore and I was just told yesterday
they have deliberately tuned back the speed...






Saturday, August 13, 2005

Dynamic Titles

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Craig has resumed blogging. In his first new blog entry
he's talking about the new Data Provider APIs in Creator 2 - which allow you to drag & drop
not only database tables, but EJB methods, and web services to automatically data bind to visual
components.



The Data Providers also allow you to map the components to your own data structures - or connect
the components to other persistence technologies or frameworks. One of
my earlier blog entries talked about
how to do this with the standard JSF data table in Creator 1.0. With the new data providers it should be a lot easier.
However, we have some EA bugs which makes it a bit tricky at the moment. Perhaps Craig's next blog
will show how to do it specifically - if not, I'll take a stab at it.



It's been a really great week in Creator engineering. We've been doing memory profiling and have found
some major culprits. We're not done with the performance work though.



I'll finish this entry with a tip: How to generate dynamic titles for your pages. Page titles of course are typically
shown by browsers in their window titlebars - and they usually also become the default bookmark label.



This used to be tricky (in Creator 1.0). In Creator 2, all you need to do is locate the Head component
in the Outline. Notice that it has a Title property. All you need to do is set this property
to a value binding expression, for example #{Page1.title}, and then add this method to Page1's java file:



public String getTitle() {
return "Dynamic Title " + new java.util.Date().toString();
}


Title bar screenshot



For those of you who are using Creator 1.0, the way you need to do it is to add the same method to the
page bean, but then switch to the JSP file, and locate the <title> tag. Remove the
text which is in there, and add this:



<h:outputText value="#{Page1.title}"/>


Note that this output text doesn't have an id, and doesn't have a binding attribute. That's important,
because this means that the output text will emit the text returned by the value binding expression
as a simple text string, rather than wrapping it in a <span> inside the title element as it
would otherwise do.


Thursday, August 11, 2005

"To Die For" Style Editing

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


When we shipped "Reef" - a big update to Creator 1.0 last December,
one of the new features was a CSS property editor.
In the "What's New In Reef"
feature overview
posted on the web site,
the CSS support was described as a "To Die For" Style Editor.



That was jumping the gun a little. We had in development really
good CSS support, but only one minor part of that was actually
added into Reef. Of course, it's now available in Creator 2 EA.
I was just asked by a user how to edit full stylesheets, not just
the style attributes of components. And this is
precisely what the new CSS editing support is for: full
fledged CSS file editing.



So without further ado, let me introduce a screenshot of what
happens when you open a CSS file in Creator today (click
for full image):




CSS Editing Screenshot



There are many things to notice here (not all are shown):


  • Code completion on properties and property values. For example,
    here the caret (right under the mouse pointer) is in the value
    are for a border-style property, so the completion popup
    is showing the possible values for that property (solid, double, etc.)
    along with a visualization of these values.

  • There's a live preview of the style declaration near the bottom right.
    Let's say you had a style declaration only defining the text color to
    be orange. In that case, you'd only see sample text, in orange.
    Here we have a more complex style declaration, setting borders,
    font weight and size, etc. These rules are all reflected immediately
    while you're tying in the style declaration.

  • There's also a customizer area on the bottom where you can easily
    choose fonts, background colors or images, margins, etc. etc. These
    automatically update the current style declaration with new properties
    or value updates. Also, as you're tying in the text area, the right
    values are selected in the customizer.

  • Notice the property sheet on the right - it's showing the properties
    set for the current style declaration. This is also kept in sync with
    the other views. (The customizer and preview area, which takes up a lot
    of space here, can be toggled on and off with a toolbar button, and when
    it's off the property sheet is pretty useful.)

  • You can navigate styleclasses with the combobox in the editor toolbar.

  • There is Syntax highlighting and Code Folding of style rules

  • There's a Reformat action which reformats the stylerules such that
    all property declarations are on their own lines; indentation is uniform, etc.

  • There's a style builder dialog which lets you construct new style declarations
    with more complicated selectors.

  • There's background error checking too.




Something fun to try is to use this facility to explore the stylesheet that's built
into the theme you see applied to the new Creator components -- gradients on buttons,
etc.



Go into the Project Navigator, look under Libraries,
locate the Default Theme item, expand it, then expand the css package, and open
the css_master.css stylesheet. As you can see it's not a trivial stylesheet,
clocking in at over a thousand lines!


Monday, August 8, 2005

Creator 2 Review

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


eWEEK Labs has reviewed Creator 2 Early Access.
My favorite quote has to be this:



What will lose that audience in moments, though, after 14 years of conditioning by Microsoft Corp.'s Visual Basic and its many imitators, is anything less than full drag-and-drop convenience. Having reviewed a decade's worth of Java tools that have tried to do this with varying success, we feel as if JSC2 is finally there. Not only is it easy to do things correctly in JSC2, but it's also - and this is at least as important - difficult to mess things up. We're used to finding ways to break the multilateral links among visual and code-focused tools, but JSC2 proved immune to our deliberate attempts to confuse it.




We do know about the bugs and performance issues in the EA bits though. Believe me, we know intimately: we're in a bug fix phase now so every day each developer starts by looking over the personal bug list and attacking it in priority order!



I don't have the bugids memorized - but at one point I actually did! Early on in Creator development, when we were just a small
skunkworks project named Rave, we were using Scarab for bug tracking.
One of the nice things about Scarab is that the bug ids were easy to remember; they had the subsystem name plus a 3 digit number after it.
Thus, you'd have bugs like WEBFORM152, or WINSYS250. These bugs, particularly the notorious ones, were easy enough to remember by id.



Every week towards the end before our first public demo, we'd do a team run-through with that mornings bits, testing the scenario we were planning to show. On several occasions we'd hit a glitch that I recognized as a duplicate of one particularly nasty window system bug, so I'd call out "That's just good old WINSYS106!".



I don't have the bug ids memorized anymore. Not only because we're using Sun's enterprise bug database where bug ids are seven digits long, but I'm only looking at my own bugs these days, and I don't want to get familiar with them, I want to squish them before we get acquainted...



In other news, I saw
this article
on news.com: Sun funding Derby database development. So hopefully the database 5Mb limit days are not here to stay...


Friday, August 5, 2005

NetBeans versus Eclipse!!

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


There's no better way to get attention than with a subject like that!
There's a new JavaCast podcast out. This is a new "weekly radio program" on
Java and what's happening in the Java world. If you have iTunes, or other podcasting software, it's trivial to subscribe
to the weekly feek - just follow the links from
the JavaCast page.
Of course, you can just listen to the MP3 file directly.



So why did I use such a controversial subject for this blog entry?



In this week's JavaCast, I'm the interview subject. One of the things I talk about is the "IDE war" - addressing
why I don't think NetBeans should give up just because Eclipse have signed up so many partner companies.
Other things I address is Class Library Development versus Component Based Development, I talk about my observation
that many server-side framework pundits seem to have tools phobia, and of course I talk a bit about AJAX and about Creator.









Wednesday, August 3, 2005

Authorization servlet filter for JavaServer Faces

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Alexis has written a blog entry on
how to add an
authorization servlet filter for JSF
. This will allow you to prevent users from accessing your web app
pages directly via URLs, bypassing your navigation logic. Check it out! Alexis works at Sun France and was our host
during the trip
to Paris last fall. He's
been a really great tools evangelist!



In other news, some of you have asked when Creator 2, now in
Early Access,
will ship. David Folk from marketing responded.


Tuesday, August 2, 2005

Centering - Finally Finally

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


I finally implemented support for the HTML <center> tag last night.
I had resisted doing that since none of the components are using it,
and besides, <center> is a deprecated tag.
However, some users have been asking for it - and I discovered that
the new Alert component -does- rely on <center>'s evil twin:
the

align="center"
attribute on <table> tags. So I decided to implement
it. But don't take this as encouragement to ask for support for the <blink> tag!



If you've read this blog for a while you might remember that I made
a quick attempt at implementing center before. The

"correct" way to
center in CSS
is to set the horizontal margin properties to
auto. However, simply aliasing <center> to
auto margins has other side effects, so I backed that change out.



The solution I settled on is what Mozilla seems to be using: a new
internal-only value for the text-align property. In
Mozilla's case it's "-moz-center", and you can see it if you use their
DOM inspector to look at elements inside a <center> tag.
Now, the <center> tag, as well as the align="center"
attribute, will set text-align to -rave-layout,
and the box dimension code looks for this property and handles centering
as you'd expect.



It seems to work - here's my Google test page finally properly
centered (click for full size):








You can see how it used to look in
this old blog entry.
Quite a bit already centers simply through use of text-align: center, but notice how
the menu above the textfield is wrong.


Monday, August 1, 2005

Remove duplicate and unused entries from your property files

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Three years ago or so I realized the code I was working on had lots of "stale" Bundle.properties entries. These are bad because not only do they create more work for localizers who translate these files to other languages, but unused keys also incur more runtime overhead.



It's easy to end up with unused key entries. Perhaps you first comment out some code which is referencing a bundle key - but you don't comment out the bundle key. Later the commented out code is removed, but the key in the property file is still there.



To find these I
wrote a really hairy Unix command; something like this:



find . -name Bundle.properties -exec cat {} \; | /bin/grep "=" | sed
'/^#/d' | sed '/^OpenIDE-Module-/d' | nawk 'BEGIN { FS="=" } {print $1}'
| sort | uniq | nawk '{system("/bin/fgrep " $0 " `find . -name
\"*.class\" -o -name \"*.xml\"` \| nawk \"BEGIN \{i=0\} \{ i++ \} END \{
if \(i==0\) print key \}\" key=" $0)}' | /bin/xargs -n 1 -I @ grep @
`find . -name Bundle.properties`


I recently figured it was time to check my Bundle files in my current code - so I used a tool I had seen
Tim Boudreau commit into NetBeans CVS. It's a standalone tool, not
integrated as part of the IDE. But it's quite useful.



The tool is called "Bundlizer", and is found in NetBeans CVS under contrib/bundlizer.
Just load it as a project in NetBeans and run it and you'll get the GUI (see screenshot below).
Or, use the executable jar I just uploaded here. Use at your own risk.



The program does a couple of useful things:


  • It looks for duplicates: the same key used more than once. You are alerted to this specifically since you'll need
    to decide which value to keep.

  • It looks for unused keys. These are removed from the file.

  • It cleans up formatting in the file, removing empty lines etc.


When you're done it saves the resulting file.



You'll definitely want to check its results. Discovering if a key is unused is not something which can be done
accurately. Obviously, if your code is doing something fancy, like computing keys rather than looking them
up directly, the program will not figure that out and will think the keys are unused. One common case of that in my
own code had to do with keys that are referenced from XML files. For example, NetBeans plugin code declares menu items
in an XML file, and these pull keys out from a bundle. There are other ways the program can be tricked too.



Consider yourself warned. However, the program is extremely useful at identifying candidates for removal. You'll
probably see some keys in your own files and go "oooooh yeah.... that's still there? Guess I forgot to remove it!".



Here's a screenshot of the utility in action (click on it for full size):








I suspect the reason the utility has not been "finished" and moved into the IDE as part of the Resource Bundle support,
is precisely because discovering unused keys is such an inaccurate science. If anyone would like to take a closer
look at the code and try to make it smarter, please do!
I made a couple of tweaks for my own purposes before running the tool. Here's the patch I applied -
the first diff makes it look in XML files for key references; the second makes the tool less unhappy
when it encounters non-comment lines that don't contain and = sign:


Index: contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java
===================================================================
RCS file: /cvs/contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java,v
retrieving revision 1.3
diff -u -r1.3 BundlizerPanel.java
--- contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java 7 May 2004 23:48:40 -0000 1.3
+++ contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java 2 Aug 2005 05:45:46 -0000
@@ -449,7 +449,7 @@

private class JavaFilenameFilter implements java.io.FilenameFilter {
public boolean accept(java.io.File file, String str) {
- return str.endsWith ("java");
+ return str.endsWith ("java") || str.endsWith("xml");
}
}

Index: contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java
===================================================================
RCS file: /cvs/contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java,v
retrieving revision 1.2
diff -u -r1.2 Properties.java
--- contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java 1 May 2004 13:52:24 -0000 1.2
+++ contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java 2 Aug 2005 05:45:46 -0000
@@ -115,6 +115,10 @@
}
String keyValuePair = line;
int equals = keyValuePair.indexOf ("=");
+ if (equals == -1) {
+ continue;
+ }
assert equals != -1;

String key = keyValuePair.substring (0, equals).trim();
@@ -203,6 +207,9 @@

private boolean isKeyValuePair (String line) {
int equals = line.indexOf("=");
+ if (equals == -1) {
+ return false;
+ }
int cmt = line.indexOf ("#");
return (cmt > 0 && equals < cmt) || (cmt < 0 && equals >= 0);
}