java hosting


JavaRanch Newsletter Articles in this issue :
Announcement - New Forum in the SaloonJason Menard
Printable Version
Programming Diversions PuzzleJason Menard
Printable Version
Small and Simple Web Applications - the Friki Way (Part 3)Frank Carver
Printable Version
The Coffee HouseSolveig Haugland
Printable Version
Top 10 Ways You Can Get to Know and Love OpenOffice.orgSolveig Haugland
Printable Version
JavaRanch at JavaOne 2003 Jessica Sant
Printable Version
Jenny - The Code Generator Paul Wheaton and Marilyn de Queiroz
Printable Version
Movin' them Doggies on the Cattle Drive Dirk Schreckmann
Printable Version
Book Review of the MonthJason Menard
Printable Version
Book Promotions For JuneThomas Paul
Printable Version

Announcement - New Forum in the Saloon

by Jason Menard - Programming Diversions Bartender

JavaRanch has a brand new forum, Programming Diversions!. This is a place to come to in order to have some fun and to flex a bit of the ol' grey matter. In this forum you will find progamming challenges and puzzles of various difficulty that you can solve, or better yet, post your own! You will benefit not only by attempting these yourself, but also by seeing how your fellow programmer attacks these problems. So mosy on over, put on your ten-gallon thinking cap, and let's have some fun!

Return to Top

Programming Diversions Puzzle

by Jason Menard

As a new feature of the JavaRanch Newsletter, and to go along with our new Programming Diversions forum, we will be offering a monthly programming puzzle. Here we now present to you the first of hopefully many such puzzles. Enjoy!

WordSearch

Given any N X N grid of letters (where N > 0, N <= 100), and any set of words which may be found in the grid, write a program to find and display the starting and ending grid coordinates for each word. The top left corner of the grid is [0,0] (row 0, col 0), and the bottom right corner of the grid is [N,N].

You may input the grid of letters and the words in the manner of your own choosing. Words in the grid may be found oriented in any direction within the grid (vertical, horizontal, reverse-horizontal, reverse-diagonal-up, diagonal down, etc...).

Use the following grid and list of words to test your code.

xbcbdjwgpmpcfsh
avijureeroltfha
bdsheriffnamnev
lsuraibvoikoist
iakpffrsngtoshr
zhdanosourzsrea
eicnuludnexerwn
rednetrabvasbec
mldoarahcdwyvrh
auyjvroosendetl
pkypuiaciornede
sitemapvitralsv
rafnopekaminiui
umlksreyejmlpir
pgetwdmpevitood


javaranch
moose
bartender
sheriff
drivel
reviews
uml
threads
jdbc
roundup
You can discuss this puzzle and post your results in the Programming Diversions forum here.

Return to Top

Small and Simple Web Applications - the Friki Way (Part 3)

by Frank Carver

Abstract

This article is the third of a series which laments the bloated and unmaintainable state of so many J2EE web applications and looks at ways to keep web applications small, simple and flexible. The series uses the author's Friki software as a case study, and discusses ways to design and build a powerful, flexible and usable web application in less space than a typical gif image.

This article continues the coding process begun last time, and finally starts working on real user requirements. On the way it helps take the effort out of rebuilding and re-running tests whenever anything changes.

Introduction

If you've read the first and second articles, you should be aware that the aim of this project is to develop a small, simple and understandable "Wiki" (editable web site) application. We've considered and decided to defer the relatively heavy decision of how to store and retrieve pages by introducing a Java interface, decided on and implemented a simple "template" system to display pages, and are building a supporting test suite as we go along.

Before we continue, I'd like to remind everyone of what our "customer" wants. For the purposes of this article, our customer says we will be "done" when we have a Java web application in which:

  1. each page may be viewed using it's own unique URL
  2. page content may contain links to other pages by name
  3. links to nonexistent pages will be marked with a "?"
  4. page content may be created and edited using just a browser
  5. at least 100 different pages can be stored

What do we write next?

By now, you should know that we start each new feature by writing a test for it, so the questions should perhaps rather be "what do we test next?". Whichever way you look at it, this is still a tough choice. If we want to make real progress toward our customer's goals, we need to start delivering software which meets those goals. So far, all we have is a repository interface and a template engine, neither of which is mentioned in the list.

There are lots of ways of deciding what to do next. Perhaps simply do them in the order they are written in. Maybe do the hardest first so we learn the most. Maybe ask the customer which is most important. I'm sure you can think of many more. In this case I'm going to recommend that we start by choosing the easiest to test. The idea behind starting with the easiest is that the customer goals are all tangled together. The more we can remove from the tangle, the simpler the rest will become. With any luck, by the time we get to the hard tasks, so much will already have been removed that they will be easier, too. The idea behind starting with the easiest to test is that until we have written a test, we can't start writing code, and I want to start writing real code as soon as possible.

Using this approach (often known informally as "pick the low-hanging fruit") can be suitable at the start of a new project or large single change, where there are several inter-related requirements which all need to be met for anything to work at all. Beware, though! This approach can become dangerous as soon as something has been delivered which the customers/users can try themselves. At that point it is usually better to pick whichever the customer wants the most, and see how that affects the remaining ones. It is also important to resist the temptation to keep adding more "vital" features which delay this first delivery. The sooner we can get real priority decisions from the customer, the better.

We have decided to go for the easiest to test. Which one is it?

Goals one and four look like we would need to set up a web server of some sort. To make it work would in turn mean building our software into something which can be deployed to the web server. The tests would maybe try to fetch pages from different URLs and see what they get. Sounds a lot of work before we see any results. Goal five looks like it would need us to build that repository we keep putting off. Goals two and three look as if they can be tested in a similar way to the way we tested the template engine, which seemed pretty easy. I think I'll choose to do goal two first, as completing it might help make goal three easier.

First task: "page content may contain links to other pages by name"

Let's start with a nice simple, "empty" test to make sure we have everything working. Even with this, we still need to think about how we would use the code we are going to write. One of the simpler ways is to think of it in terms of a formatting process. Some "raw" text from a stored Page will be "formatted" into "processed" text containing links where neccesary.

AllTests.java

package tests;

import junit.framework.*;

public class AllTests extends TestCase
{
    public static TestSuite suite()
    {
        TestSuite ret = new TestSuite();

        ret.addTest(new TestSuite(EmptyTest.class));
        ret.addTest(new TestSuite(TemplateTest.class));
        ret.addTest(new TestSuite(LinkTest.class));

        return ret;
    }
}

LinkTest.java

package tests;

import junit.framework.*;

import friki.PageFormatter;

public class LinkTest extends TestCase
{
    public void testEmpty()
    {
    	PageFormatter formatter = new PageFormatter();
    	assertEquals("", formatter.format(""));
    }
}

PageFormatter.java

package friki;

public class PageFormatter
{
    public String format(String input)
    {
        return input;
    }
}

Just as with the TemplateEngine, the first test and the first implementation can feel a bit like cheating. But remember, all of this is part of the design process -- we have already designed how to use the formatting code, now we have to make it work for more cases.

Next, though, a major design turning point. We know that "processed" page names will need to appear as HTML links, but how should we represent the names of pages in the "raw" text? This is an important decision, users of the system will have to type one of these names in to the browser every time they want to link to another page. The answer is not obvious, either. There are Wikis which use patterns of upper-case and lower-case letters, and automatically recognize things like FrankCarver and FrikiServlet. There are Wikis which use any group of characters wrapped in end characters like [[Frank Carver]] or {:Friki}. There are Wikis which use any alphabetic or alphanumeric word which starts with a special symbol, like @FrankCarver or ~Friki. There are even Wikis which check every word in the text, in case it might be the name of a page, and need no special delimiters at all.

This decision is so important, it needs the involvement of the customer. The job of the developers is to explain the options and answer questions to help the customer choose the right compromise between desired features and cost. In this case, our customer grumbles a bit, and settles for the word-starting-with-symbol approach, using '@' as the symbol. He says he may change his mind later, but we knew that already!

With this knowledge we can add some more tests to our LinkTest class:

    public void testNonLink()
    {
    	PageFormatter formatter = new PageFormatter();
    	assertEquals("hello", formatter.format("hello"));
    }

    public void testEmbeddedLinkSymbol()
    {
    	PageFormatter formatter = new PageFormatter();
    	assertEquals("friki@javaranch.com", formatter.format("friki@javaranch.com"));
    }

Both these tests pass with no extra code. Excellent. However, just as with the TemplateEngine test case, we now have the same setup code appearing in three places. It's time to remove the duplication and create a setUp fixture.

LinkTest.java

package tests;

import junit.framework.*;

import friki.PageFormatter;

public class LinkTest extends TestCase
{
    PageFormatter formatter;

    public void setUp()
    {
    	formatter = new PageFormatter();
    }

    public void testEmpty()
    {
    	assertEquals("", formatter.format(""));
    }

    public void testNonLink()
    {
    	assertEquals("hello", formatter.format("hello"));
    }

    public void testEmbeddedLinkSymbol()
    {
    	assertEquals("friki@javaranch.com", formatter.format("friki@javaranch.com"));
    }
}

Now we get to add a test which fails:

    public void testLink()
    {
    	assertEquals("<a href='view?hello'>hello</a>", formatter.format("@hello"));
    }

As usual, the next step is to write the simplest solution. Maybe something like:

PageFormatter.java

package friki;

public class PageFormatter
{
    public String format(String input)
    {
    	if (input.startsWith("@"))
    	{
            return "<a href='view?" + input.substring(1) + "'>" + input.substring(1) + "</a>";
    	}

        return input;
    }
}

Good, That works. It's a bit messy, and I can see some duplicated code in there, so lets refactor it to tidy it up. Don't forget to re-run all the tests after every change to make sure nothing has broken.

PageFormatter.java

package friki;

public class PageFormatter
{
    private String symbol = "@";

    private String makeLink(String name)
    {
        return "<a href='view?" + name + "'>" + name + "</a>";
    }

    public String format(String input)
    {
        if (input.startsWith(symbol))
        {
            return makeLink(input.substring(symbol.length()));
        }

        return input;
    }
}

You can probably guess where we go next. We've done just enough testing to test that we can generate a link, but it's pretty obvious that a Wiki page with just one word is not very useful, even if it is a link to another page. So we need to test that the PageFormatter can find and convert page references wherever they appear in a page. So, we add another test:

    public void testLinkInPage()
    {
    	assertEquals("You say <a href='view?hello'>hello</a>, I say goodbye.",
    		formatter.format("You say @hello, I say goodbye."));
    }

After the last test passed, we refactored the code to be simpler and neater. Now is a chance for a second sort of refactoring, the kind you can do before a change, to make the change itself simpler. I'm pretty sure we'll still need to be able to convert a word to a link if it starts with the special symbol, so let's extract that code as a method, which we can call from the "smarter" code we are about to write.

PageFormatter.java

package friki;

public class PageFormatter
{
    private String symbol = "@";

    private String makeLink(String name)
    {
        return "<a href='view?" + name + "'>" + name + "</a>";
    }

    public String formatWord(String word)
    {
        if (word.startsWith(symbol))
        {
            return makeLink(word.substring(symbol.length()));
        }

        return word;
    }

    public String format(String input)
    {
        return formatWord(input);
    }
}

Our new test still fails, of course, but now we have a clean place to put the new code. Of course there will be other changes to this class, but it's often a good idea to "clear the decks" before adding anything major.

PageFormatter.java

package friki;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

public class PageFormatter
{
    private char symbol = '@';

    private String makeLink(String name)
    {
        return "<a href='view?" + name + "'>" + name + "</a>";
    }

    private boolean startsWith(String word, char symbol)
    {
    	return word.length() > 0 && word.charAt(0) == symbol;
    }

    public String formatWord(String word)
    {
        if (startsWith(word, symbol))
        {
            return makeLink(word.substring(1));
        }

        return word;
    }

    public String format(String input)
    {
        StringBuffer word = new StringBuffer();
        StringBuffer ret = new StringBuffer();

        CharacterIterator it = new StringCharacterIterator(input);
        for(char c = it.first(); c != CharacterIterator.DONE; c = it.next())
        {
            if (c == symbol || Character.isLetter(c))
            {
            	word.append(c);
            }
            else
            {
                ret.append(formatWord(word.toString()));
                word.setLength(0);
                ret.append(c);
            }
        }

        ret.append(formatWord(word.toString()));

        return ret.toString();
    }
}

It looks like we've finished one of the user's goals. Hooray!. There are, of course, a few things to note about this code:

First, although that "formatWord" method is still there, it has changed a little. The variable "symbol" is now a char rather than a String to make things easier in the "format" method. This restricts future expansion a tiny bit, but that doesn't matter. If anyone really ever wants to use a multi-character word prefix, there isn't much to change. The thing that irritates me most is that I can't use the built-in and nicely descriptive String.startsWith method any more, as there is no version for asking if a String starts with a char. Sigh.

Second, the structure of the "format" method looks strangely similar to the TemplateEngine.expand method we developed last time. Bear this in mind, and if we see an opportunity, we should consider refactoring the whole system to remove this duplication.

Making Rebuilding Simpler

Are you getting fed up with all that typing "javac ..." and "java ..." yet? I know I am. Even if you use an IDE or a command-line history mechanism which hides it, there's still a lot of repetition. We owe it to ourselves and to our customers to stamp this out. The solution I suggest for this is to use a "build tool".

A build tool is a program which reads a pre-defined set of instructions and relationships, and uses them to build software for you. A build tool is a kind of specialized scripting language, indeed you can get a long way using just the scripting abilities built in to your system (DOS .bat files, Unix shell-scripts etc.). In this case I recommend the Ant build tool from the Apache project. If you are not already familiar with Ant, you may want to look at Thomas Paul's March 2002 newsletter article, and install Ant as directed.

Ant is flexible and powerful, and we will be using some of its more interesting features in later articles. For now, though, we just want to get it to compile and test our code. Before we leap into scripting, we need to understand what we want Ant to do, and we also need to be able to test (even if only by inspection) that it has done it right.

The first step is to set up a sensible directory structure for our project, and copy our source files into it. The structure I recommend follows the common Ant pattern of separate directories for separate operations. In particular, note that source code and classes for the delivered application are kept completely separate from the test code. We will likely have more test code than application code by the time we have finished, and we want to keep the delivered application as lean as possible. So we keep test code separate to avoid the risk of delivering any of it.

                   friki
                     |
         +-----------+----------+
         |                      |
        src                   build
         |                      |
   +-----+------+           +---+---+
   |            |           |       |
delivery      tests      delivery tests
   |            |           |       |
 +-+---+      +-+--+        |       |
 |     |      |    |        |       |
java files  java files   classes classes
  1. Copy PageFormatter.java and TemplateEngine.java into friki/src/delivery/java/friki
  2. Copy AllTests.java, EmptyTest.java, LinkTest.java and TemplateTest.java into friki/src/tests/java/tests
  3. Create a new file friki/build.xml and put the following into it:

build.xml

<project name="friki" default="build" basedir=".">

 <path id="classpath">
   <pathelement location="build/delivery/classes"/>
   <pathelement path="${java.class.path}"/>
 </path>

 <path id="testclasspath">
   <pathelement location="build/delivery/classes"/>
   <pathelement location="build/tests/classes"/>
   <pathelement path="${java.class.path}"/>
 </path>

 <target name="clean">
   <mkdir dir="build"/><delete dir="build"/>
 </target>

 <target name="compile-delivery">
   <mkdir dir="build/delivery/classes/"/>

   <javac srcdir="src/delivery" destdir="build/delivery/classes" debug="on">
     <classpath refid="classpath"/>
   </javac>
 </target>

 <target name="compile-local-test">
   <mkdir dir="build/tests/classes"/>
   <javac srcdir="src/tests/java" destdir="build/tests/classes" debug="on">
     <classpath refid="testclasspath"/>
   </javac>
 </target>

 <target name="compile" depends="compile-delivery,compile-local-test"/>

 <target name="test">
   <junit fork="yes" haltonfailure="yes" printsummary="yes" dir="build/tests">
     <jvmarg value="-Djava.compiler=NONE"/>
     <test name="tests.AllTests"/>
     <classpath refid="testclasspath"/>
     <formatter type="plain"/>
   </junit>
 </target>

 <target name="build" depends="compile,test"/>
</project>

This may look complicated, but mostly it's just a way of configuring Ant to understand the directory structure we are using. Each target is equivalent to a public method or function definition, and the final "build" target brings them all together

Now, open a command-line, change to the top friki directory, and type ant. As specified on the first line of the build file, if no target name is specified it runs the default "build" target. You should now see a series of messages finishing with something like:

test:
    [junit] Running tests.AllTests
    [junit] Tests run: 9, Failures: 0, Errors: 0, Time elapsed: 0.156 sec

build:

BUILD SUCCESSFUL

If you get any complaints from Ant, double-check the directory structure and the build.xml file. If you see any failures or errors reported by junit, look in the file friki/TEST-tests.AllTests.txt for more details. If it all works, celebrate!

How are We Doing?

We still haven't made a Wiki yet! But we have met one of the five user goals. We have continued expanding our test suite to cover everything we have done so far, and have created a directory structure and build script to enable the whole project to be built and tested using a single, simple command. We are poised on the edge of producing a real web application.

Next session we'll add more customer features to our Wiki and extend our build script to automatically create a deployable "web application archive" (war) file. Why not try and guess which of the remaining customer goals will be next on the list...


Return to Top
Brenda and Lacey Explain Dating Design Patterns

Welcome to the Coffee House The Coffee House

by Solveig Haugland


Brenda and Lacey Explain Dating Design Patterns

Grumpy Sid Sid and Zeke and the whole town of Deadville were pretty excited last week. They learned all about patterns and how to apply them to their Java programming. It started to get out of hand, and they started coming up with Cattle Design Patterns, Coffee Design Patterns, Massage Parlor Design Patterns, and then it all started to get out of hand.

Here's how it all happened.

It all started because Zeke said that what he wished he had was some darned Dating Design Patterns. "Finding a woman, and then knowing what the heck to do with her once you've found her, is about as complicated a system as I've come across," he complained. "Why don't these fellers turn their four big brains on something really useful? I can just hack together a system and it'll run, at least, but my  server is getting absolutely no client requests for services, if you catch my meaning."

Lacey and Brenda, making lattes behind the counter, started laughing. "There are Dating Design Patterns, you ornery old cowpoke. You just need to ask us and we'll give you everything you need to know. We are women, after all, and we can deploy an EJB faster than the rest of you put together."

"Oh, stop rubbing it in. I was feeling poorly that day. Anyway, what do you mean? You got some design patterns that are composed of that there three-part rule, which expresses a relation between a certain context, a problem, and a solution?"

Sid looked at Zeke like he'd just given birth to a three-horned cow. "You're talkin' funny, mister. You sound like that there Christopher Alexander fella that they was quoting about ever other darned minute."

"Well, I just want to use the right terminology. This is important. C'mon, Brenda, Lacey, give us a pattern. We'll sit quiet like and listen to you."

"Well, all right." Brenda shut down the latte machine and she and Lacey perched on the counter in front of the big mirror, each with a bed red pencil. "Let's look at first things first. Y'all are moaning about not knowing what to say to a woman , right? You can't get yourself into a conversational state."

"Oh lord, yes. That's a tough one. I can't think of anything when I'm sitting there lookin' at a pretty girl," yelled someone in a big black hat in the back.

"Well, that's because your CPU is running at 99% and you ain't got no system resources free to think up something to say," replied Lacey.  "Even once you calm down a bit, it'd take you several minutes to come up with what you're going to say, package it up in a nice sentence, wait til she's free so you can create a connection, and then send that little conversation over with all the right arguments over to her. Why, she could be three days gone by then."

"All right, let's think about this. You want to think of something to say to a lady, but if you wait til you need it in order to come up with what to say, you don't have the system resources to do it, or it takes one heck of a long time. Right?" And Lacey wrote up on the mirror:

Problem
You want to send a request to a server, but cannot access sufficient system resources to create the request object. And then you feel stupid.
"Now, how would you solve this?"

Black hat in the back yelled out again, "Well, if I was codin' that problem it's easy. This is connection pooling, plain and simple."

"That's all there is to it," said Brenda. "You gotta create a pool of things to say to a gal ahead of time. Just make a whole bunch of'em, and then when it's time you just have to pick one that ain't gonna throw an exception. Always have an extra in mind, too, in case she don't like the first one." And she wrote on the mirror:

Solution

Use a Diving in the Conversation Pool to create multiple coarse-grained conversational objects that can be used to create connections with a variety of servers. Catch exceptions with a try-again block.


"That's an awful neat solution," admitted Zeke. "So what kinds of things could we talk about? I've been told that foaling ain't a proper topic to ask a lady."

"Yes, try to stay clear of the whole blood and guts thing," replied Lacey. "It's not that complicated. Just act like you're incredibly interested in her and you're getting paid two bits for every little thing you find out. What's her name, where's she from and why she's here,  what she's been doing in town, and at that point if you're on the ball you can offer to show her the hot spots or escort her to anything going on that a lady might like, like a concert or our county fair. It's just a nice classic straightforward gentlemanly approach." And she wrote on the board:

Strategies

SmallTalk Strategy

Ignorant Facade Strategy

"I love the  Ignorant Facade Strategy too," she went on. "You just pretend not to know stuff and ask. Women have been using this one for years and we call it Ol'Reliable. Because you can always count on people to be opinionated, even a nice well-bred lady from the east. If you ask her when she thinks we're going to invade Iran, or what she thinks you should buy for your sister's new baby since you're just an ignorant man and you need a woman's opinion, or to resolve a debate between you and your friend about whether women appreciate a good display of gunplay, she'll talk to you and make no mistake. This is a great one since men are known far and wide for knowing nothing' about women, and you can ask her about anything woman-oriented, like the right size for a man's belt buckle in proportion to his boots, or you could even ask her to take square-dancing lessons with you since you ain't allowed to sign up alone."

"Or there's another approach," said Brenda. "You can get one of us or another respectable lady to walk around with you and start conversations with ladies for you, and then introduce you to them."

"Oh, Brenda," exclaimed Lacey in righteous indignation. "That's not a strategy of Diving in the Conversation Pool. That' s a related pattern, and in a whole nother category. The Gang Of Outlaws came up that one, anyway."

"Don't get all structuralist on me," yelled Brenda. "I think that a strategy should be more loosely defined so as not to preclude a functionalist approach as appropriate."

This, of course, is where things really got out of hand. Yelling epithets like "Aristotelian!" and "Micro-architecture fascist!" the women fought long and hard, cheered on by the rather randy crowd of cowboys until Lacey managed to throw Brenda out the door and into the horsetrough, and started looking around for another challenge.

So the cowboys shuffled on home to check their livestock and their servers and their Amazon rankings, but with more knowledge than they'd woken up with, and they dreamed that night of common themes relating to the recurrence of a problem/solution pair, in a particular context (a king-sized bed with lots of baby oil).



Solveig Haugland is an independent writer and trainer based in Colorado. She has a lot of different projects going--outdoor sports footwear, OpenOffice.org and StarOffice, patterns, Java, and dating. And Java and dating.

Her projects are usually well behaved, sitting in their separate directories and waiting patiently to be brought up again, but occasionally they get bored and start checking each other out. Occasionally the projects even have rowdy parties in the middle of the night and wake up in the wrong directory in the wrong clothes, which is how dating design patterns thing happened. See additional results of this improper intermingling of patterns and dating logic at www.datingdesignpatterns.com.

You can contact her through her OpenOffice.org training and books Web site, www.getopenoffice.org, or via solveig@getopenoffice.org.




Return to Top
Untitled Document

Top 10 Ways You Can Get to Know and Love OpenOffice.org

by Solveig Haugland

So, you know you should be using OpenOffice.org, it's free, it's the Right Thing to Do, but like switching from Hostess Cupcakes to high-fiber cereal, it's hard to break the habit of MS Office and switch to OpenOffice.org. Here are a few things to help make the transition less traumatic and more fun.
 

  1. Get a book. Because Germans don't do usability. You can do a whole lot in OOo but easily find the options to do everything is not one of them. To create a background in OOo's Powerpoint equivalent, for example, you need to click on either Slide Design or choose View > Master > Drawing. Actually making the background is really easy and you have a lot of power and flexibility but getting there isn't obvious. The mantra of OOo users is "It's easy when you know how."

  2. "My "OpenOffice.org Resource Kit" has the CD in it, if you don't want to wait for the download. Michael Koch also has a book on StarOffice 6.0 which you can use for OOo.

    For a simple download page (the openoffice.org site is a bit labyrinthian), go to www.getopenoffice.org/download.html

  3. The datasource connection is pretty cool. Easier than last time and more useful, the premise is that you can connect to any database you want, including a bunch of open source databases. You just get to choose your means of connection: ADO, JDBC, ODBC, etc. You can also just create a plain delimited text file or spreadsheet and use that as your data source.
  4. Take a look at the Stylist. (Choose Format > Stylist.) You've got a bunch of built-in styles, and as you've probably been told by upstanding technical writers, using styles makes your life so much easier. The Stylist is one of the easiest and most effective tools in the program. Just format text how you want it and click the New Style From Selection to create a new style. Want to update the style? Just select that same text, change it, and click Update Style. It's pretty straightforward.
  5. Spend some time in Draw. Get to know the connector lines. It's like a mini-Visio. The lines stay connected to the objects no matter where you move them.
  6. Spend some time in Draw with the 3D features. You will probably be surprised. You get spheres, toruses, cubes, half spheres, etc. Rotate the shapes around and you'll see the frame rotating as you turn it.
  7. Spend some time in Draw with the text. AutoText has some pretty cool stuff for curving text to preset lines or your own line.
  8.  
  9. Check the conversion of your MS documents. Feed them through the converter (File > AutoPilot > Document Converter). The wizard makes an OOo copy of each of your MS documents, so you can see how they did. This is an easy way to tell how much work you'll need to do on the OOo end to tweak formatting, and what you'd have to do after switching to OOo to work with people who do straight MS files.
  10. Choose Tools > AutoCorrect/AutoFormat and turn off everything under every tab. This is how you turn off nearly everything annoying like word completion.
  11. Note that in the latest version of OOo, you can print straight to PDF, and you can also export Impress (Powerpoint equivalent) presentations to Flash as well as HTML.
  12. All files are compressed XML. Unzip any OOo file and you get styles.xml, content.xml, and so on. Open the XML file in Textpad or your favorite editor and you can change any of the source (providing you don't goof up the XML, of course). This is particularly useful for editing broken graphics links or getting rid of the 2000 extra styles you somehow got when you converted from Word.
Compressed XML also means the files are very very small.




Solveig Haugland is an independent writer and trainer based in Colorado. Among other things, she's the author of the "OpenOffice.org Resource Kit" and "StarOffice 6.0 Companion." She does training for both programs and sells her book/workbook learning kit, and as of September 8th will be an international trainer when she heads to Norway to do a week of training.

You can contact Solveig through her OpenOffice.org training and books Web site, www.getopenoffice.org, or via solveig@getopenoffice.org.
 
 
 
 
 
 


Return to Top

JavaRanch at JavaOne 2003

by Jessica Sant

If you're attending JavaOne, be sure to check out your fellow JavaRanchers!

BOF-3061: Certification Roundtable with Michael Ernest and Jessica Sant

This informal session offers help, advice, and guidelines for anybody who wishes to start or is following the Sun certification process. This session is not a technical Q&A forum, but rather an interactive forum where the panel answers questions and offers advice in the way of reading lists, tips for study, and tips for the exams.

The panel includes Sun certified JavaTM technology platform technologists at all levels, with the added bonus that they help run the JavaRanch Web site, one of the largest independent Java technology communities on the Internet with a strong focus on the certification programs.

BOF-2955:JavaTM Technology in the Classroom: Teaching Finance Using Java Technology with Mark Herschberg and Jon Gadzik

Finance is a field traditionally taught through books and lectures. However the application of the knowledge is often illustrated through executing actions through software. Harvard Business School has sought to revolutionize the teaching of finance by having a game-based lesson model. Software, written to mimic trading applications used on Wall Street, is used extensively to teach each lesson throughout the semester long course. This session discusses how we were able to employ JavaTM technologies to quickly and easily create a such a game, and how these Java technology-based games may enhance the educational experience.

BOF-1672: Design Patterns and Best Practices for JavaTM Technology-Based Mobile Applications with Michael Yuan and Ju Long

Mobile commerce requires sophisticated enterprise backends and pervasive user interfaces. Due to the limitations of mobile devices and wireless networks, some unique design and implementation issues must be addressed when developing end-to-end mobile commerce applications. In this presentation, we discuss design patterns and best practices in mobile application development. We focus on two crucial aspects: smart mobile client and seamless client-server integration. We use several concrete mobile JavaTM technology-based applications, including the Sun Smart Ticket blueprint, as examples.

Smart mobile client must take advantage of the performance, reliability, and rich UI benefits offered by thick client technology. At the same time, it must be light enough to fit into and run smoothly on small handhold devices. We discuss the benefits and implementation of MVC and variant patterns, background thread and gauges, cache for performance, reliability, and security.

On the integration front, the diversity of mobile applications calls for a variety of integration schemes. We discuss important integration techniques, including Remote method call, asynchronous messaging, binary-over-HTTP, XML, SOAP Web services, SyncML, and session tracking.

After this talk, you have a better understandings of the unique challenges facing mobile application development; get familiar with common approaches; be able to judge which pattern is the best based on application circumstances; learn other people's approaches from discussions. This is an intermediate to advanced level session. Prerequisites: Working knowledge on design patterns, client-server model, MIDP, XML, Java technology stream I/O, SOAP Web services, and HTTP.


Return to Top

Jenny the db code generator

This program reads a database and generates java source which provides strongly typed access to the database.

by Paul Wheaton and Marilyn de Queiroz

Why was Jenny created?

In my opinion, there are two major problems with JDBC:
    1) There are slight differences in SQL, drivers, app servers, database access, etc. that make it clear that a facade is needed. The facade would provide access to the database in plain java (not SQL). All of the implementation specific code is concentrated in one small area instead of spread out all over your application. The DBFacade class fixes this problem.

    2) For any database change, it takes a great deal of discipline to find all of the table names and column names used throughout your code that now functions differently. Even the slightest lack of discipline results in a bug that might not be discovered until run time. Strong typing eliminates this problem. This program (Jenny) provides the strong type checking.

For each table and view in a given database, Jenny will create a java source class file. Each of these classes will provide a collection of general purpose methods for working with the table/view. They will also provide a list of all the column names, the table/view name and an inner class called Row that can be used to manipulate a single row in the table.

Many tables have a primary key that is a non-nullable integer called "tablenameID" or sometimes "ID". If Jenny finds this, she will add extra methods to the generated source for working with the primary key.

Some of my goals:
  • Simplicity: Accessing the database needs to be as simple as possible. I decided that this meant using static methods for the table level methods. All connections, statements, result sets and all other objects that need closing are generally managed for you so you don't have to worry about it - thus eliminating about 70% of the code required for typical JDBC access.

  • Unit Testing: I want to auto-generate a Mock class for every table class to facilitate unit testing. This means that I need to have something I can override. Since static methods cannot be overridden, I need an inner class that the static methods use that I can override for my mock classes. This also means that I need to hide all of the Row constructors so a mock object can be returned. This allows unit testing without having to provide SQL in the unit tests or to have a database server running during the testing.

  • Flexibility:I want to be able to allow alternate connections, or to make several database calls with one connection, so every database access method allows me to pass in a connection object. I also want to allow multiple ways to get to the same database; support multiple databases on one database server; support the use of multiple servers being used from one application.

  • Functional Testing: I want to allow for functional testing (sometimes called integration testing - kinda like unit testing, but with more than one class and sometimes the actual database) so I allow all classes to replace the connection source at the facade level.

  • Clear Division of Labor: I want to work with the idea that the database is managed by a DBA and business logic is managed by software engineers. So fancy database stuff is done by the DBA in the database (i.e. joins are handled within views by the DBA). In most big software shops, the software engineer will be accessing data in an existing database that is managed by a DBA that has far more experience with the database than the engineer. Anything that cannot be done through the facade probably needs to be done on the database side.

  • Complexity Reduction: I want to avoid having complex relationships defined in an XML document or embedded in the code. Good engineering is making complicated business logic look SIMPLE! My experiences with object databases, object to relational mapping, CMP and similar tools is that they promise simplicity, but when you get right down to it, it becomes horribly complicated!

  • Self Discipline Not Required! Many solutions similar to Jenny require human engineers to have the discipline to make sure that any changes in one place are reflected in other places. If your table name in your database does not match the table name in your java code, you have a problem! With this solution, you don't need that discipline. Therefore you have more reliable code.

What does Jenny do?

Each generated class will provide some basic methods such as these:
      Row getRow()
      Row getRow( String column , String searchText )
      DBResults search( String column , String searchText , String[] dataColumns )
      Row[] getRows( String column , String searchText )
      Row[] getAllRows()
      DBResults search( String[] dataColumns )
      void update( String column , String searchText , Map data )
      void delete( String column , String searchText )
      void insert( Map data )
    
If an ID field is found, some methods like these will also be added:
      Row getRow( int id )
      void delete( int id )
    
Every class will have an inner class called Row that can provide strong type checking for every field (column) as well as methods like:
       void update()
       void delete()
       void insert()
    
The strong type checking for Row is provided by getters and setters. Suppose you have a table called Employee. Jenny will generate a class called EmployeeTable that will contain a Row class that might have the following methods:
       int getEmployeeID()
       void setEmployeeID( int employeeID )
       String getLastName()
       void setLastName( String lastName )
    
Here's a sample of a business logic method that uses a Jenny generated class:
       // pass in an employee ID and get back the number of tax exemptions that the employee claims
       private int getEmployeeExemptions( int employeeID )
       {
           return EmployeeTable.getRow( employeeID ).getExemptions();
       }
    
This same code using plain JDBC could be 10 to 40 lines long depending on how it would be implemented. You would need to get a connection, create a statement, build your sql string, execute your statement, wade through the result set, and each of these things need try/catch/finally blocks! Don't forget to close your connection, statement and result set!

How do I use Jenny?

From the command line:
    Make sure your classpath includes jr.jar and then at the command prompt type:
                    java com.javaranch.db.Jenny db.properties
          
    where db.properties is a properties file that describes how Jenny should find your database. There is a sample properties file complete with in-line documentation inside jr.jar at /src/com/javaranch/db/soup.properties.
From your IDE:

    Bring up the class in your ide and tell it to Run.

    Of course, you have to have jr.jar in your IDE's classpath; you have to define the "Main Class" (a.k.a "Target" or "command") as <path>/com.javaranch.db.Jenny; you have to define the "Program Parameters" as db.properties (where db.properties is a properties file that describes how Jenny should find your database. There is a sample properties file complete with in-line documentation inside jr.jar at /src/com/javaranch/db/soup.properties); and you have to tell it which is your "working directory" (a.k.a "Start in" or "initial folder")

She's still maturing

Note that development of Jenny is on-going and she's currently available as a beta release. Take 'er for a spin, and stop by the JDBC forum in the Big Moose Saloon to participate in her growth.


Return to Top
Movin' them doggies on the Cattle Drive

It's where you come to learn Java, and just like the cattle drivers of the old west, you're expected to pull your weight along the way.

The Cattle Drive forum is where the drivers get together to complain, uh rather, discuss their assignments and encourage each other. Thanks to the enthusiastic initiative of Johannes de Jong, you can keep track of your progress on the drive with the Assignment Log. If you're tough enough to get through the nitpicking, you'll start collecting moose heads at the Cattle Drive Hall of Fame.

Gettin' them doggies...
At the moment, folks is steerin' clear of the Classes and Objects trail. Must be somethin' in the wind. The other three trails are keepin' about a dozen Drivers busy a-kickin' up dust and a-chasin' them Moose.

Fresh riders on the Drive...
Got three new Cattle Drivers signed up on the assignment log, Chris Leeworthy, Nicholas Burgett and Sherry Cuenco, all jumpy and chompin' at the bit to push them nitpickers. The trail gets a might bit bumpy 'round these parts. Get ready...

Another moose on the wall for...
Yep, that's right, you make it through, you get yerself a nice little moose to hang on the wall. Well, OK, so it's a virtual moose on a virtual wall, but you can be right proud of 'em! Thanks to the efforts of Marilyn deQueiroz, you can now proudly admire your codin' accomplishments at the Cattle Drive Hall of Fame. Check it out, pardner, it's worth a wink.

This month, three Drivers bagged a moose on the Classes and Objects trail. A big congratulations to John Hembree, Donald Cossitt (his second this month), and Richard Hawkes, the third Driver to ever pass OOP-4 on the first try - not that it's a competition or anything...

Make room at the bar for ol' timer Carol Murphy who just bagged her fourth moose out on the JDBC trail. Can't wait to suck down some sasparilla with ya and hear some of them fish stories.

Back in the saddle
Cowboy Joseph Russell spent a spell out on the open range. But now's he's back in town, huntin' down that no-good varmint called "Say-4b."

Nearin' the end of the trail
Old-timer Barry Gaunt, as persistent as ever, is gettin' close to the last assignment. Folks will have to make up new assignments just to keep him going.

Nitpicking is hard work too...
We know they're workin' reeeeeally hard, after all, we've seen what those assignments look like once the nitpickers have combed through 'em. Hats off to Marilyn deQueiroz, Pauline McNamara, and Jason Adam for their dedication and patience with the pesky vermin that always manage to make their way into those assignments.

Those gentlemen behind the bar...
Notice the fellas wipin' the bar and shinin' up the sarsparila glasses? Updating that assignment log is tough work too. Big thanks to Michael Matola and Barry Gaunt. Mosey up and place yer orders. Rumor has it Michael keeps some special stuff under the bar, if you know what to ask fer.

Joinin' the Drive
You think ya got what it takes? You ready for some work and some good learnin'? Then pull up a stool and read up on Joinin' the Drive. Good luck!

Content and format adapted from Ol' Timer Pauline McNamara's original column. -Dirk Schreckmann.


Return to Top
Book Review of the Month

Java Number Cruncher: The Java Programmer's Guide to Numerical Computing
Ronald Mak
  
At one time or another, most of us will likely have to write code performing some amount of numerical computation beyond simple integer arithmetic. As many of us are neither mathematicians nor intimately familiar with the bit gymnastics our machines must perform in order to manipulate numbers, we can get ourselves into trouble if we're not careful. Luckily, "Java Number Cruncher" comes to the rescue.

This book is an introduction to numerical computing using Java providing "non-theoretical explanations of practical numerical algorithms." While this sounds like heady stuff, freshman level calculus should be sufficient to get the most out of this text.

The first three chapters are amazingly useful, and worth the price of admission alone. Mak does a fine job explaining in simple terms the pitfalls of even routine integer and floating-point calculations, and how to mitigate these problems. Along the way the reader learns the details of how Java represents numbers and why good math goes bad. The remainder of the book covers iterative computations, matrix operations, and several "fun" topics, including fractals and random number generation.

The author conveys his excitement for the subject in an easy-to-read, easy-to-understand manner. Examples in Java clearly demonstrate the topics covered. Some may not like that the complete source is in-line with the text, but this is subjective. Overall, I found this book educational, interesting, and quite enjoyable to read.

(Jason Menard - Bartender, May 2003)
  
   More info at Amazon.com || More info at Amazon.co.uk

  

  

Return to Top
June Scheduled Book Promotions :
Starting
Date
Book Author(s) Publisher JavaRanch Forum Status
June 3 Head First Java Kathy Sierra and Bert Bates O'Reilly Java in General (beginner) confirmed
June 10 No promotion - JavaOne
June 17 Java Data Objects David Jordan, Craig Russell O'Reilly JDBC confirmed
June 24 Wireless Java: Developing with J2ME, Second Edition Jonathan Knudsen APress Java 2 Micro Edition confirmed

Return to Top
Managing Editor: Dirk Schreckmann

Comments or suggestions for JavaRanch's NewsLetter can be sent to the Newsletter Staff.

For advertising opportunities contact the Newsletter Advertising Staff.