Isopaleocopria
Gregory Murphy's Blogorrhea

20070514 lundi mai 14, 2007

A rack up with sketchup

A few months ago, I started to play with the free version of Google Sketchup. After mastering the basics, I was able to produce a few, prototypical architectural features, such as cornices and fluted columns. Last week I put the tool to a more practical use. My wife wanted a small wine rack in our kitchen. Counter space is scarce, so we decided to try something under the cupboards. I used Sketchup to design the rack. Being able to visualize it from any angle was helpful, and we eliminated some early designs when we realized they would look funny from certain angles, or prove impractical in the small space.

Here is the final "sketchup":

I downloaded the wine bottle from the Google Sketchup 3D Warehouse, and dropped it in the model.

And here is the actual rack:

I probably spent about six hours on the design, including the two that I discarded. With practice I'll become faster, I'm sure. The rack itself took only a few hours - including ten minutes to sand the initial coat of primer that my three-year old applied.

(2007-05-14 07:09:50.0) Permalink

20070426 jeudi avril 26, 2007

Ruby script to toggle CVS root in a workspace

Sandip Chitale posted a Java program that toggles the CVS root setting of a workspace that is already checked out (see A simple program to toggle CVSROOT of existing checked out workspace). At the end of his post, Sandip solicits alternative solutions. I have been playing around with Ruby, and was curious as to how much more compactly the same logic could be expressed in Ruby.

Stripped of empty lines and comments, Sandip's Java solution weighs in at 83 lines. That's roughly four times the 16 lines required for a roughly equivalent program in Ruby, which I give below.

The Java program has explicit exception handlers, which I chose to leave out, since both programs will leave the repository in a corrupted state if IO fails midway.

# A simple program to fix the CVSROOT.  
# 
# One may check out a cvs workspace using a CVSROOT e.g.
# :pserver:username@extranet.foo.com:/cvs. This value of CVSROOT 
# is recorded in the CVS/Root file in the checkedout directories.
# At some later time, depending on the network connectivity, it may be faster
# to use an alternate (aliased) CVSROOT e.g. 
# :pserver:username@intranet.foo.com:/cvs.
#
# This simple program provides the functionality to fix the CVSROOT settings
# in each CVS/Root file. It skips entries found in .cvsignore.
#
# CAUTION: Care must be taken to make sure that both cvs servers are really the
# same servers, or mirrors that are in sync.
#
# DISCLAIMER: This is an experimental program. Use at your own risk.

require 'find'
abort 'No server name specified' unless $*[0]

roots = []
ignore_patterns = []


# Use the find module to traverse the source code repository, collecting all CVS root
# files found, and patterns of directories to ignore

Find.find('./') do |path|
  if path =~ /CVS\/Root$/
    roots << path
  elsif path =~ /.cvsignore$/
    ignores = IO.readlines(path).collect{ |line| line.chop }
    ignore_patterns << File.dirname(path) + '/(' + ignores.join('|') + ')'
  end
end


# Construct a regexp of all directories to ignore, use it to prune the array of root
# files, then, update each root file with the new pserver name

ignore_expr = Regexp.new('^(' + ignore_patterns.join('|') + ')')
roots.reject { |root| ignore_expr.match(root) ? true : false }.each do |root|
  (pserver = File.open(root, 'r').gets)[/@[^:]+:/] = ('@' + $*[0] + ':')
  File.open(root, 'w').puts pserver
end 
(2007-04-26 16:49:13.0) Permalink Comments [2]

20070306 mardi mars 06, 2007

"Neutered Theme" for Java Studio Creator

The basic components that ship with Java Studio Creator (and with its successor, Visual Web Pack> for NetBeans) derive their look and feel from a theme. If you need to apply your corporate colors to an entire application, themes make the job easier. But if you want to adjust the appearance of just one component, or make a set of components play nicely with other styles, themes can get in the way.

Unfortunately, you can't just unplug the theme from an application. In addition to things like fonts and colors that affect only the look of an application, the theme defines things that are critical to component behavior, like messages and client-side scripts.

To help in these situations, I put together a "neutered theme." This is a theme from which everything extraneous has been excised. With the neutered them, most of the components end up looking pretty much like their standard JSF counterparts. For example, here is a basic button rendered with the default theme:

Notice the border, gradient color, and text font, all of which are derived from the default theme. Switch to the neutered theme, and the button looks pretty much like a plain HTML input button:

What if you want one button on your page to be yellow? If your application relies on the default theme, and you set a button's style property so that it's background is yellow, the component remains colored a gradient blue. That's because your CSS settings in the component property are conflicting with CSS settings in the theme. But if you use the neutered theme, you'll get what you want:

Neutered themes are also useful when developing portlets, as it reduces the likelihood of conflict between portlet theme styles and styles assigned to a whole portal page.

How to use the Neutured Theme

  1. This theme will work in Java Studio Creator, and in Visual Web Pack for Java EE 1.4 project types (the theme format for Java EE 5 projects is different).
  2. Download the theme JAR: NeuteredTheme.jar
  3. From the tools menu, choose "library manager", then "import new library". Add the them JAR to the library class path, calling it "Neutered Theme" or whatever else suits your fancy.
  4. Open up the "themes" node in your project's logic view, right click on the new theme, and choose to make it the project's theme.
(2007-03-06 09:38:24.0) Permalink Comments [2]

20061213 mercredi décembre 13, 2006

Update to PropertyResourceProvider There was a bug in the first version of the PropertyResourceProvider that I made available from this blog a few months ago (see DataProvider component for internationalizing Creator applications), which manifested itself in the glassfish application server. The order of two elements in the library's faces-config file was incorrect. I have fixed the bug and updated the complib available for download.

You can download the updated PropertyResourceProvider Component Library here. (2006-12-13 15:07:06.0) Permalink

20061204 lundi décembre 04, 2006

NetBeans Free-Form Projects as Library Wrappers

When the developer defines a library in NetBeans 5.x, the library definition is stored locally, in the user directory. This makes it difficult to share library definitions among more than one workspace. While library definitions are stored locally, references to them, in the form of entries in a project's properties file, are typically stored along with all other project files, in a remote code repository. When a user first fetches the project from the repository and opens it in NetBeans, a missing references error will occur. All missing local library definitions must be created anew in each local workspace.

One solution to this problem is to store shared libraries in the remote workspace, and to make projects depend directly on the libraries' constituent JAR files. Such dependencies are stored in the project's properties file as relative paths to the JAR files, so assuming that the directory structure that includes both project and library remains the same in all users' workspaces, no local definitions are needed.

There are however drawbacks to this solution. Under the Libraries node of the project logical view, only the JAR file name is displayed. If your project depends on a large number of libraries, it can be difficult to distinguish among them by file name alone. The names may by cryptic, or worse, there may be files in different directories that share the same name. There is also no way of determining from the project logical view that a group of JAR files form a logical unit, unless they share a common infix.

As an example, consider the following project, in which one library provided JAR files aaa and bbb, and another library provided another JAR file, also named aaa:

There is a hack that I have used to improve the quality of the information available about JAR files in the project logical view, which does not require use of the local storage. Instead of grouping them into library definitions, I add them to free-form projects. Projects may then be declared to depend on the library wrapper projects.

Here is the same example, with the JAR files from the two libraries exported from two free-form library projects:

How to create a free-form library wrapper project

To create a free-form library wrapper project, start by putting all JAR files that belong together into a directory, which will serve as the project root directory. For this example, I will define two libraries, 01 and 02, the first containing two JAR files, aaa.jar and bbb.jar, and the second containing just one, aaa.jar:

    lib01/aaa.jar
    lib01/bbb.jar
    lib02/aaa.jar
Each directory will server as one logical library, represented by one free-form project. To create the project skeleton, in each directory create an empty source directory, e.g. ./src. You will also need a stub ant build script. Add the following contents to the file build.xml in the project directory:
  <project name="01_Library_Wrapper" default="build" basedir=".">
    <target name="build"/>
    <target name="clean"/>
  </project>

To create the project, from within NetBeans, choose File->New Project, and choose a "Java Project with Existing Ant Script" within the General category. In the next wizard panel, select as location the project's directory, e.g. ./lib01. NetBeans will fill in the build file information. You'll want to choose a short, but descriptive, project name, as this will be the name that appears under the Libraries node once you have declared a dependency on this library wrapper project. I chose the names "01 Library Wrapper Project" and "02 Library Wrapper Project". In the next, penultimate wizard panel, NetBeans will fill in the ant targets found, and in the final panel it will prompt you for a source directory. Choose the source directory that you created earlier.

[It may seem superfluous to create an empty source directory and empty build targets, but I discovered that without these, some actions in the IDE can have the side effect of removing the exported JAR definintions.]

After the project is created, bring up the project's properties window, and choose Output. Here you will declare the JARs that this free-form project exports. Select all the JARs that you put into the library wrapper project directory. When later you declare a dependency on this project, these are the JARs that will be added to the class path. Here is what this step looks like for my first library, 01:

And that's it! Now you are ready to declare project dependencies on your new library wrapper projects. Right-click on the Libraries node in the project logical view, and choose "Add Project...". Select the project directory. All JARs in the project will be added as dependencies. (2006-12-04 22:47:43.0) Permalink Comments [3]

20060823 mercredi août 23, 2006

DataProvider component for internationalizing Creator applications

The JavaServer Faces standard JSP tag library includes the loadBundle tag, which allows the developer to bind component values to keys in a Java properties resource bundle. While Java Studio Creator includes this tag on the component palette, there is a lack of good design-time support for binding to keys in the resource bundle, and bound values cannot be displayed at design-time. There have been a lot of complaints in the developer forum about this, and it is something that the Creator development team intends to address in an upcoming release.

In the meantime, I have put together a simple DataProvider component, PropertyResourceProvider, which plays the same role, but has much better design-time support.

How to install the PropertyResourceProvider

Download the PropertyResourceProvider complib to a local directory. From within Creator, open up Tools -> Component Library Manager, and click on "Import". Use the browse feature to locate the downloaded component library, and select it. The library contains a single component, PropertyResourceProvider, which you can import into its own category, or into a pre-existing category.

How to use the PropertyResourceProvider

A PropertyResourceProvider wraps a Java resource bundle file, and makes the keys in the bundle file appear as data fields. In general, you should use one PropertyResourceProvider per resource bundle file. The component has a single property, baseName, which should contain the qualified base name of the resource bundle file. The property editor for the baseName property will show a list of all resource bundles available in the current scope, so you can just choose one from the list. If you aren't familiar with Java resource bundles, there is an SDN technical article that provides a good overview.

The overhead involved in creating a PropertyResourceProvider is minimal, so it is probably easiest to add them to each page on which they are needed.

Localizable component values will need to be added to a resource bundle, instead of being set directly on the component. There are a number of ways of adding new keys to a resource bundle file. You can click on the file in the project view to edit it directly (look under the Source Packages node), or you open the file node and right click on a locale node to add key and value pairs, one by one.

To bind a component to a localizable value, right-click on the component and choose "Bind to Data". Select the appropriate PropertyResourceProvider, and the keys currently defined in the resource file will appear as fields. Select a field, and Creator will set the property's value to an expression that binds to the selected field. Close the binding window, and you will see the property value appear in the designer. PropertyResourceProvide is just like any other DataProvider, so you can also edit property values in the component's properites sheet, or by choosing the "Property Bindings..." context menu item.

The PropertyResourceProvider will automatically choose the correct bundle file to load based on the locale of the Faces context for each request. This locale is determined by examining the client locale of the incoming HTTP request, and the list of supported locales given in the application's faces-config file. Typically, adding a locale to a project involves two steps:

  • You add a locale-specific version of each bundle file. See the SDN technical article referenced above for more information about naming conventions for bundle files.
  • You add the locale to the list of supported locales, in our project's faces-config file. You will find this file in the Files window, under your application's web/WEB-INF directory. For an application that supports two locales, French and Spanish, in addition to the default locale of English, the relevant fragment of the faces-config file would look like this:
      <application>
        <locale-config>
          <default-locale>en</default-locale>
          <supported-locale>fr</supported-locale>
          <supported-locale>es</supported-locale>
        </locale-config>
      </application>
    

Hope this helps! (2006-08-23 15:36:49.0) Permalink Comments [4]

20060208 mercredi février 08, 2006

Rough Guide: Editing Themes for Creator 2.0

The components that ship with Java Studio Creator 2.0 derive their look and feel, and in some cases, their behavior, from a theme. At the most basic level, a theme is simply a JAR file that contains resources such as CSS stylesheets and graphical icons.

An easy way to create your own look and feel is to edit the contents of the default Creator theme. The following guidelines explain how to do it.

A theme JAR file has three main types of content:

  • manifest file: information about the theme's name, version, prefix, and locations of properties and resources
  • properties files: a map of theme keywords to theme resources, used by the theme manager to location theme resources
  • resource files: the images, Javascript files, CSS stylesheets, and messages that constitute the theme itself

You'll find a copy of the default theme jar (defaulttheme.jar) in the Creator install directory, under rave2.0/modules/ext. Or, after you have deployed an application, in the application directory build/web/WEB-INF/lib.

Expand the file into a new directory. Users of M$ Windows may find it more convenient to rename defaultheme.jar to defaulttheme.zip, so that they can expand its contents using the Explorer.

Step One: Updating the manifest

The first thing to do is to give your theme a name, and to edit the manifest accordingly. I'll start by renaming the Creator default theme, from defaulttheme to isopaleocopria. The theme name is given in the manifest entry X-SJWUIC-Theme-Name. At the same time, I'll modify the package names for the various resources so that they are based on a namespace that I own.

Here's the new manifest:

    Manifest-Version: 1.0
    Ant-Version: Apache Ant 1.6.2
    Created-By: 1.4.2_07-b05 (Sun Microsystems Inc.)

    Name: com/sun/rave/web/ui/theme/
    X-SJWUIC-SWAED-Version: 3.0
    X-SJWUIC-Theme-Version: 1.0
    X-SJWUIC-Theme-Name: isopaleocopria
    X-SJWUIC-Theme-Prefix: /theme
    X-SJWUIC-Theme-Messages: org.isopaleocopria.themes.messages.messages
    X-SJWUIC-Theme-Images: org.isopaleocopria.themes.properties.images
    X-SJWUIC-Theme-JavaScript: org.isopaleocopria.themes.properties.javascript
    X-SJWUIC-Theme-Stylesheets: org.isopaleocopria.themes.properties.stylesheets

A few important points about the manifest:

  • To be a valid theme JAR, the manifest must contain an attributes section named "com/sun/rave/web/ui/theme/"
  • The attibute X-SJWUIC-Theme-Name must be present, and it must contain a unique name (a name not used by any themes already loaded into Creator).
  • The last four entries are package names that must correspond to property files in the theme JAR. For example, org.isopaleocopria.themes.properties.images should correspond to the file org/isopaleocopria/themes/properties/images.properties. Do not edit the keys in these property files!

If the above conditions are not met, Creator will reject the theme.

Nota Bene: According to the spec, lines in a JAR manifest file are limited to a maximum length of 72 bytes. When you extract and first open the manifest for editing, you may notice that some lines longer than 72 bytes have been wrapped, and the enjambed portion has been indented with a single space character. You'll need to patch these lines back together again before reconstituting the JAR or ZIP file.

Step Two: Editing theme content

Before editing the content, you'll want to move it to your own package. In order for the theme manager to find the content in its new location, you'll need to update the path values in the various property files listed above. For example, as part of developing my new theme I would move the Javascript file /com/sun/rave/web/ui/defaulttheme/javascript/table.js to org/isopaleocopria/themes/javascript/table.js, and update the corresponding value in the javascript.properties file.

After updating the theme name and the locations of the property files, it's time to edit the theme content. In some cases, the key names in the property files will help you to identify which theme artifact belongs to which component. The CSS stylesheets also generally use a truncated version of the name of the component as the prefix of style class names that apply to the component.

Step Three: Importing the edited theme into Creator

When you are finished modifying the theme content, you will need to repackage the contents as a JAR or ZIP file which can then be imported into Creator.

To import the theme file, start Creator and open or create a project. From the menu, open Tools -> Library Manager. Select the Theme Libraries section, and click on "New Library". Give the library a name, e.g. IsoPaleoCopria (note that spaces are not accepted, probably a bug), and add the theme JAR or ZIP file to the library's classpath and to its runtime, using the appropriate tabs.

Finally, to apply the theme to the current project, select it in the project hierarchy, right-click, and choose "Apply Theme".

Have fun! (2006-02-08 15:36:48.0) Permalink

20041110 mercredi novembre 10, 2004

Fraters Libertas (sic)

What, I wonder, were the deep thinkers at Fraters Libertas thinking? That a Latin motto is cool? Perhaps they are under the spell of their beloved leader's English malapropisms. If they are what I suspect they want to be - the brothers of liberty - their devise should read Fratri Libertatis. On the other hand, I think the pidgeon Latin better suits the general tenor of their political commentary. (2004-11-10 11:00:04.0) Permalink

20041028 jeudi octobre 28, 2004

Craving crack

This is an actual piece of spam that was waiting for me in my inbox this morning. The English is priceless. I wish I knew the redactor's native language; "crave to feel crack" seems like a direct translation of some foreign idiom.


    From:       Candida Rebux 
    Date:       28 Oct 21:33 (PDT)
    Subject:    Do you crave to feel crack following morning?

    Our recent view shows that it takes usual of just 1.2
    boozings to effect a hangover. But this pills
    services you evade hangovers and waken sensitive great from head
    to stomach and all over else.

(2004-10-28 17:00:45.0) Permalink

20041012 mardi octobre 12, 2004

NetBeans sex exception?

NetBeans 3.6 threw an IllegalStateException today while I was creating a new project. The exception was announced in a pop-up window, and also on the command line, with the message:

    gris-118% sex exception: java.lang.IllegalStateException: 
              can't declare any more prefixes in this context
Perhaps it should try whispering them softly in my ear? (2004-10-12 12:05:16.0) Permalink Comments [2]

20041001 vendredi octobre 01, 2004

New meta-blog about XML

There is a new website that aggregates RSS feeds from several bloggers well-known in the XML community, dubbed "Planet XMLhack": http://planet.xmlhack.com. (2004-10-01 10:22:48.0) Permalink

20040926 dimanche septembre 26, 2004

Markup as protest

Michael Sperberg-McQueen used to say that all markup is interpretation. And some markup is demonstration: </Bush>. I suppose I don't need to point out that the Bush element isn't well formed. Or that maybe it should be empty. (2004-09-26 18:46:45.0) Permalink

Actually

Thanks to Gary Trudeau, I now know what "actually" means: Doonesbury. (2004-09-26 18:21:19.0) Permalink

20040920 lundi septembre 20, 2004

Twice baked

Sometimes a word describing a technique can take on localized forms, which effectively describe local variations in the technique. Take biscuit. The word comes to us from Latin via French, and means, literally, "twice baked". Baked goods were passed a second time through the oven to ensure their longevity. At the English table, it refers generally to savories; at the French, to sweets. Italy has given us a sweet variant, often with anise, that we have imported along with the Italian name for the technique: biscotto. And from Germany, that ultimate in crackers for teething babies, zwieback. These are baked once as bread, and then toasted. (2004-09-20 16:52:26.0) Permalink

20040917 vendredi septembre 17, 2004

A list of things to do

If you're like me - a busy tech worker with more commitments than time - you probably keep a list of things to do. Back in the day, a "to do" list, like all important scientific discoveries, had the terse prestige of a Latin sobriquet. The word agenda comes from the gerund of agere, the Latin verb meaning "to do". It's an ellipsis, of sorts. Used in an expression such as mihi agenda sunt ("things which are to be done by me"), the gerund is used to express need or obligation. There are others still kicking around. Our memo is a truncation of memorandum, that which must be remembered. A referendum is a decision which a government must refer to the people for their consideration.

Technically, agenda is a plural. If you are lucky enough to have only a lunch date with Cicero on your schedule, then you have an agendum. I can't find any references to the singular in the OED, except as agend, which doesn't seem to have survived the Age of Napoleon. In modern English we rely on the expression agenda items to evoke the individual components of a meeting's schedule. I like that expression, because "item" reinforces the notion that a meeting ought to progress, from start to finish, in an iterative manner. Too many meetings seem more like hallucinanda.

I suspect that the more recent action item was motivated by similarity of form to agenda item (and not by their common etymology, "action" deriving from the past participle of agere). We use agenda item to refer to the points we cover in discussion at a meeting, and action item to refer to the things that we have agreed to do after the meeting has ended. I'm not sure why we can't just call them actions. After all, we want to do things, and not just talk about them at meetings.

If anyone hasn't seen it yet, action item has inspired a singleton comic strip, chock full of ludicrous corporate jargon. (2004-09-17 21:12:40.0) Permalink


archives
links
referers