Monday, February 28, 2005

Privacy and Security

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.


James Gosling's latest blog entry points to John Gilmore's
fight for privacy, and in particular, airport rules. The requirement for all travellers to present IDs to fly helps security how exactly?



This story really struck a chord with me. A couple of months ago, I was going on a business trip from San Francisco airport. I had a million errands to get done before I left - so I brought my bills, envelopes and stamps to the airport. After checking in, I sat at the gate and filled out the payment slips. Then I figured I'd look for a mailbox. Surprise surprise - there are NO mailboxes ANYWHERE inside San Francisco airport. The only one is outside, on the curb! I thought this was unbelieavable - I have often mailed postcards to friends and family from airports while waiting for my flight. But when I talked to the security guards who were pointing me outside, they were telling me that this was for "security reasons".



That didn't make a lot of sense to me. I've brought the letters IN, THROUGH security. If there's a bomb, or anthrax or whatever in my letters, I've already got them with me, ready to take on board. How would having a mailbox for me to drop them in make for a security threat? What if I drop my letter in one of the thrashcans, or airport flower pots, instead?



Presented with this argument, the security guard just smiled and said knowingly "I wish I could tell you, sir, but this is classified and we don't want to give terrorists any ideas". So... I obviously don't have a mind made for terrorism because I can't figure it out.


Sunday, February 27, 2005

Mixed Table Columns

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.


Before I begin: Creator Update 7 is out. This is a pretty small patch (from update 6) containing just a handful of bugfixes - but some of them are important, so do update.



Anyway, I just browsed the Creator forum and saw a couple of questions I thought would make an interesting blog entry. Here's the
first question:


I would like to selectively have some items in the datatable be links and others not (e.g. some as simple outputtext, others as links). I need to make this decision at run time.


Is this possible to do? Is there an event to dynamically alter the table item output?



Yes, it's possible - with a little trick! You cannot change the types of components, but you -can- dynamically control whether a component is visible or not! Therefore, all you need to do is place BOTH types of components in the column, create a property which determines which type of output you want for the current row, and then cause exactly one of the two components to be made visible for this row. You control component visibility with the "rendered" property of a JSF component.



Let's take a specific example. I drop a Data Table component on the canvas, and then I drop the "PERSON" table from the Sample "Travel" database that ships with Creator. It has 4 columns: Id, Name, Jobtitle, and FrequentFlyer. I want to make the Name column use a hyperlink if that person is a Frequent Flyer. To do this, I drag a hyperlink and drop it in the Application Outline on top of "Column2" - this places the hyperlink in the second column in the table - the Name column.






Then I double click on the canvas to go to the Page bean for this file (the Java code) and add the following method to create a read-only boolean property:


public boolean isFrequentFlyer() {
Object o = getValue("#{currentRow['FREQUENTFLYER']}");
return o instanceof Boolean && ((Boolean)o).booleanValue();
}

Go back to the Page1.jsp file.



Finally, I go and update the value bindings:


  • I right click in the Application Outline on the new linkAction1 (make sure you don't select linkActionText, its child) and select Property Bindings.... In the dialog, choose the "Advanced" toggle button, and in the list on the left locate and select the "Rendered" property. In the list on the right, drill down to your page, and select the "frequentFlyer" property. Hit Apply, then Close.
  • Select the old output text component (this is the first output text in the table column in the application outline) and select Property Bindings. Again choose the frequentFlyer property for the advanced "Render" property. But before you hit Apply, edit it to be the logical opposite: change the binding expression from #{Page1.frequentFlyer} to #{not Page1.frequentFlyer}.
  • Select the text output inside the link, linkAction1Text, and bind its value property to the same as the original text - you want the link to say the same thing that the output text does, not "Link Action" as it does now. E.g. set its value to #{currentRow['NAME']}.

When you run, you should see this:






Notice how the hyperlinks are only showing up when the FrequentFlyer value is true. And of course there's no reason you need to show the frequent flyer column in the table - you can hide it with the Table Layout context menu item on the table. And furthermore, you can obviously make the logic for deciding which type to use as complex as you want - your isFrequentFlyer() method can do anything you want.


Tuesday, February 22, 2005

Hello from Shanghai

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.


Hi there,

here's just a little quick entry written from my hotel room in
Shanghai, China. I'm here for a very quick trip - I arrived last night,
I'm spending three days here and then flying home on Saturday.
I'm here to talk to some potential Creator partners and customers.
There won't be any time for sightseeing, which is too bad, given how
interesting this city is. I would especially like to go to the historical
museum. Perhaps I can cram it in before the flight on Saturday...



Now a couple of quick tips. I've written a couple of blog entries on
expression evaluation. I heard from two readers that they couldn't get
this to work when referencing their own beans - it only worked
with the "builtin" page and session beans. The reason for this is that
expression evaluation works with managed beans. These are beans
that are managed by JSF - which means they are created on demand by
the framework. You need to register your own beans in the
managed-beans.xml file, which you can find in the Project
Navigator.



Second, if you want to track the IDE's memory usage over time, you
can enable the "Memory Meter". Right click in the toolbar (not over
a toolbar button), and you'll see a list of available toolbar items.
One is the "Memory" item. Select it, and your toolbar will now display
a little graph showing you memory usage over time. Perhaps useful if
you're observing occasional sluggishness and you're wondering if your
project working set is using up your available heap space, or if you wonder if
occasional pauses are related to garbage collection.


Tuesday, February 15, 2005

Data, but not Database Data

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.


Some customers I met last week said that even though automatic databinding
is handy (this is when rowsets dropped on visual components are automatically
bound to these components),
they don't want a tight coupling to the database
in this way. They have their own middle tier, and they want to use it.



How can they use the Data Table component, with its paging features
etc., and display arbitrary data as opposed to data fetched automagically from
a databound rowset?



It's actually pretty straightforward. There is just one key concept
you need to know: the JSF Data Table interacts with its data
through the DataModel interface. You can supply your own data model,
and the Data Table will happily display your own data.



When you drop a Data Table component in Creator, you automatically
get a Data Model associated with the Data Table created. For
dataTable1 you get dataTable1Model. This
model is an instanceof javax.faces.model.ListDataModel,
which wraps a simple java.util.List. Each row in the
data table will come from a single item in this list.



How the row object is accessed depends on what you put in the table columns.
You may have noticed that when you drop a database table on the Data Table,
you by default get Output Text components with value bindings like these:


value="#{currentRow['FIRSTNAME']}

This lets each column in the table logically bind to different columns
of the row object. To achieve the same effect, put a Map in each
row of the data model, where the keys are keys to be used in the
value binding expressions (like "FIRSTNAME" above), and the values are
the actual values you want assigned as the value for the bound output
texts.



Let's get specific. You've dropped a JSF Data Table component on your
canvas, and you ended up with dataTable1, and its data model,
dataTable1Model. Go to your page bean (double click on the
canvas somewhere outside the Data Table), and modify the end of the
constructor to


  1. Create a List object
  2. Populate the List with Hashmaps, one for each row, where each
    hashmap contains key/value pairs for all columns in this row
  3. When done, set this list as the wrapped data for the data model
  4. Return to the Data Table in the design view, and modify the
    value bindings for the columns such that they point to the
    new keys



For example, your code might look something like this:


(Creator-managed Component Initialization here)
// Additional user provided initialization code
List rows = new ArrayList();

// You would probably have a loop here to fetch your
// data from your real storage or middle tier
HashMap row1 = new HashMap();
row1.put("FIRSTNAME", "Mickey");
row1.put("LASTNAME", "Mouse");
row1.put("FAVCOLOR", "Green");

HashMap row2 = new HashMap();
row2.put("FIRSTNAME", "Donald");
row2.put("LASTNAME", "Duck");
row2.put("FAVCOLOR", "Blue");

rows.add(row1);
rows.add(row2);

dataTable2Model.setWrappedData(rows);
}



Now return to the Design view, right click on the Data Table,
bring up the Table Layout customizer. Get rid of all the existing
columns that are there (using the << button), then use the New button
to create your own columns. In my example, we'll want three columns.
Choose the heading names, like "First", "Last", and "Favorite Color".
Choose the component types - for example, Output Texts. And finally,
set the value binding expressions. For example, for the first column,
you should set the Value to #{currentRow['FIRSTNAME']}.



Voila! When you run you should see your own data displayed in the
data table. If you enable Paging in the Table Layout customizer,
that should work too.



Using ArrayList and HashMap (and one for every row at that) may strike
you as wildly inefficient. But notice how you're supplying the List
and Map objects! You don't have to use the default implementations;
you can write your own class implementing java.util.List
which maps directly into your own data storage for the data to be
displayed, and similarly, the Map lookup from column name to column
value can be done through smart computation rather than pre-storing
all the row values in a series of HashMaps for the rows!



One final note - if the data being displayed can change as the page
is displayed repeatedly (for example due to failed validation or because
the user is interacting with other components on the page),
you probably don't want to construct your wrapped list
data in the constructor. Instead, make the List object a class member,
such as

    private ArrayList rows;

and add a method which first calls rows.clear() and then
updates the list to contain the current correct set of rows.
Then call this update method both from the constructor as well
as from beforeRenderResponse() (which is a method
you should add to your page bean; its parent class has an empty
implementation which is called.)



This (the need to call the update method from both places) is a bit ugly
and is something we'll fix. Happy coding!


Monday, February 14, 2005

Creator is Java Tool of the Year!

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.


Tool Of The Year
Creator was just
announced
as the winner of the Java Tool of The Year category from developer.com!
It was also a runner-up for the Tool of the Year award.
Here's the detailed writeup of the
candidates and winner of the Java tool category.


NetBeans also scored big, winning the Open Source Tool of the year award (its
competitor Eclipse won the Tool of the Year award). NetBeans supports the new language features in JDK 5.0, which
was the Technology of the Year winner.



Thanks to those who voted! And rest assured we're hard at work on the next release to have a great entry for next year's competition as well!


Wednesday, February 9, 2005

Finally Centering Blocks

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, and having a great time. We're discussing
architecture and the java model. It's really exciting, but too early to blog about...



I did find out about some cool new features in NetBeans 4.1 though.
For example, if you hold the control key (or on my mac, the Command key)
all method calls under the mouse turn into hyperlinks which when clicked
jump to the referenced source.





Now for the nerdy technical digression of the week....
I've been doing some debugging at night. After somebody

brought up the issue

of the <center>> tag (which I've

mentioned before
), I decided to look into it again.
A little debugging led me to the problem in the rendering code. Basically,
let's say you're trying to center a table like this:


<table style="margin-left: auto; margin-right: auto">
<tr><td>Hello World</td></tr>
</table>



I'm using horizontal margins as auto to cause centering, which is the
CSS way to center - the <center> tag has been deprecated a long
time.



In the above html, we have an element with
"width", "margin-left" and "margin-right" all set to "auto".
According to the width computation rules for

CSS 2.1, section 10.3.3,


If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.



If both 'margin-left' and 'margin-right' are 'auto', their used values are equal. This horizontally centers the element with respect to the edges of the containing block.

My code was doing these rules in the order listed. In the above scenario, yes,
width is auto, so the other auto values (margin-left and margin-right) become
0, and then it solves the equation

margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

This however means that the computed position is not centered. So instead I'm now
first computing the preferred minimum width of the component (using the shrink-to-fit
approach used for absolutely positioned elements), and then I split the remaining space
in the containing block evenly between the two margins. This seems to give exactly
the behavior needed.



After hooking this behavior up to the <center>
tag, using

page import

on the Google home page shows that the google text field area is now correctly centered!


Inheriting javadoc comments

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 just learned something new - which I thought I would share.



I always avoid having javadoc comments on methods which implement an interface method. I add a full comment in the interface, explaining the method, its parameters and its return value. However, in the implementation class, I leave out the javadoc completely. That ensures that javadoc will copy the description from the interface instead, which in turn ensures that the comment is accurate since I only have to maintain it in one place. (Had I copied it in when I first implemented the method, and then later changed the description, the implementation copy would go stale. And yes, I've made that mistake in the past...)



This scheme works fairly well, but there are times when I want to add additional comments to the implementing method. For example, adding additional notes useful to clients calling this specific implementation of the interface. When I've done this, I've only included the specific documentation for this method, and then I refer to the interface method itself for the full method description. This is clearly not a good solution either, because when you view the documentation in an IDE javadoc popup, for example, it doesn't include the basic comment which is often more important than the supplemental information.



Well, it turns out there's a way to get javadoc to include the parent documentation, and you can surround it with your own specific comments! Just use "{@inheritDoc} " inside the documentation somewhere, and it will include the super documentation:


/**
* {@inheritDoc}
* <p>
* For this specific implementation of the interface, you're better off
* calling the more efficient {@link foo} method, provided you have the
* additional arguments!
* </p>
*/


More information on this can be

found here
.



@inheritDoc is available as of JDK1.4. In JDK 5 there's another cool tag to use as well
(thanks to Peter von der Ahé, Mr. Javac,
who's sitting next to me here in the Prague office, for pointing this one out to me.)
Use the @code tag to include code samples inline in the javadoc. No more needing to
escape all < and > characters in the javadoc comment as &lt; and &gt; !
And there was much rejoicing...


Tuesday, February 1, 2005

Fun With Value Binding

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.


JSF supports Value Binding, which allows you to do some really
cool things, really easily. For example, lets say you have a Data Table,
and in one
of the columns you want to show a name. However, that name is really
two columns in the database: FIRSTNAME and LASTNAME. When you drop
the datasource on the Data Table, you end up with two columns - one
with the first name, and one with the last name.



How can you have the data table show "First Last" in a single column?
Just go to the
JSP and locate the section which looks something like this:


<h:outputText binding="#{MyPage.outputText1}" id="outputText1" value="#{currentRow['FIRSTNAME']}"/>

I've made the value binding expression in the above bold so it stands out.
You can change the value binding expression to this

value="#{currentRow['FIRSTNAME']} #{currentRow['LASTNAME']}"

or if you prefer a "Last, First" format,

value="#{currentRow['LASTNAME']}, #{currentRow['FIRSTNAME']}"

When you run the application, the full value binding expresison
(with multiple column lookups) will be computed and rendered into
your single column in the data table.
(Remember to delete the "other" column that we didn't modify - it's
still showing the last name.)



Let's say you want to do something more complicated - you don't just
want to concatenate these expressions with some text in between, you
want to make dynamic decisions about what to include. For that, use
property binding.



Let's say you have two columns in your rowset - "Location", and
"OverrideLocation" (probably from a join on a couple of different database
tables). Location is the default, but whenever OverrideLocation
is nonempty, you want to use that instead. In this case, open your page's Java
file (the so-called Page Bean), and add a method like this:


/** Produce a location based on the default location and the location override */
public String getLocation() {
String override = (String)getValue("#{currentRow['OVERRIDELOCATION']}");
if (override != null && override.length() > 0) {
return override;
}
return (String)getValue("#{currentRow['LOCATION']}");
}

Now, simply go and bind your database column to this property! That's easy
- click on the OutputText component in the data table, then right click,
choose Property Bindings..., and in the dialog, make sure the
"value" property is selected on the left, and on the right, drill to this
page's page bean, and locate the "location" property and select it. Hit
ok and you're done.



This technique allows you to really easily "massage"
your Data Table components (and obviously any other data bound components)
to display the information in the way you want, regardless of the actual
column layout in your database schema.