June, 28, 2008

Lunch Bag Letdown…

Rogers announced their voice/data plans for the iPhone last week and to say I am disappointed is an understatement.

I will need to get an iPhone in the near future, my business and clients will demand it, but these plans are completely insane.

I have no idea what the folks at Rogers were thinking, but obviously none of it was good. You can find plenty of analysis of the plans on the web so I won’t go into that here, but for me the plans make no sense.

They are bundles of voice and data at arbitrary points without any of the flexibility that I require. What happens if I want more than the base level of voice minutes (150 minutes?!?) but without increasing my data? Where is the network calling? Where is the long-distance options?

The only thing that I can think of is that these plans are intentionally simplified to reduce the load on the CSRs for the initial launch of the phone. No options equals less questions and less time activating the phone. I’d like to think there is a reason beyond pure stupidity and greed, but maybe I’m being too generous…

Anyways, I am now left with this decision:

Do I buy the phone, lock in at the lowest plan, because I’m going to need to start developing on it soon anyway, and hope for things to get better?

Or do I say FU Rogers and wait. The spectrum auction is coming, maybe we’ll get a new GSM carrier without their collective heads wedged up one of Ted Rogers’ orifices. Maybe voting with my dollars will join the others that are feeling the same way and give Rogers a wake up call.

Regardless, I am conflicted and saddened…

— david @ 10:59 am
June, 14, 2008

WOWODC - debts must be repaid

I am recovering from the red-eye flight home from San Francisco, but thought I should take a minute to say something about WOWODC.

Pascal Robert went "above and beyond" to organize an exceptional gathering for the WebObjects community. I think that it is safe to say that everyone in attendance had a great time and learned an incredible amount.

Pascal did an insane amount of work and shouldered an insane amount of responsibility putting this year’s show together.

I just want to say how much I appreciate it.

— david @ 3:16 pm

WOWODC & WWDC 08

In no particular order, some of my favorite things:

— david @ 3:05 pm
May, 28, 2008

overflow:hidden

Google caching my brain, please disregard.

When using overflow:hidden to clear floats, IE 6 may need you to give the element a width or height (often 100% works fine).

— david @ 11:11 am
May, 15, 2008

WO Movies Example DB

I am slowly creeping towards the completion of the third WebObjects screencast. In preparation, I’ve created a tweaked version of the Apple Movies database tuned for MySQL and Wonder. You can grab the db dump and EO Model here. The model uses the MySQL protopypes from Project Wonder and the db dump matches it.

— david @ 12:14 pm
May, 14, 2008

WWDC08 Sold Out

The news that WWDC has sold out is causing some consternation in the Apple Dev community. The unexpected news (due to the rising popularity of the platform and the introduction of the new iPhone track at WWDC?) has caught a number of developers off guard. Accustom in past years of being able to register right up to the last minute, many are now scrambling to find tickets.

I’ve read several posts to various dev lists in the past hour containing plaintive pleas for anyone offering WWDC tickets to sell.

— david @ 5:52 pm
May, 09, 2008

Advanced WOComponent API Validation

WebObjects WOComponents are comprised of two files and a bundle. For example a WOComponent named "MyComponent" would have a bundle called MyComponent.wo, a Java file called MyComponent.java, and an API file called MyComponent.api.

Usually the majority of your time is spent editing the content of the .wo bundle and adding logic to the .java file. But when you create a reusable WOComponent it is also important to specify it’s bindings requirements so that the WOLips Component Editor (or WOBuilder if you are so inclined) knows what bindings the component accepts. This is the job of the API file.

WOLips Component Edtior - The API Tab

If you were to create a component named "MyReusableComponent" and in the API tab of the WOLips Component editor you added three bindings the editor window would look something like this:

api_window_1.png

Now if you were to open the MyReusableComponent.api file in a text editor instead of the API editor you’d find a chunk of xml that looked like this:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wodefinitions>
  <wo class="MyReusableComponent" wocomponentcontent = "false">
    <binding name="myBinding1" />
    <binding name="myBinding2" />
    <binding name="myBinding3" />
</wo></wodefinitions>

Back in the API editor if you selected the first binding and checked the "Required" checkbox you’d see the API change to this:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wodefinitions>
  <wo class="MyReusableComponent" wocomponentcontent = "false">
    <binding name="myBinding1" />
    <binding name="myBinding2" />
    <binding name="myBinding3" />
    <validation message="'myBinding1' is a required binding.">
       <unbound name="myBinding1"/>
    </validation>
</wo></wodefinitions>

The additional xml defines a validation message that will be triggered if it’s contents evaluate to true. In this case: if "myBinding1" is not bound.

Unfortunately, this is about as far as the validation rules currently go in the WOLips Component Editor. If you need validation that is any more complicated than “Required” or “Will Set” you are on your own…

On Your Own

Lets say our reusable component has an "action" and "href" binding. Either action or href needs to be bound but not both. Let’s start with the API xml that the Component Editor gives us:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wodefinitions>
  <wo class="MyReusableComponent" wocomponentcontent = "false">
    <binding name="action" />
    <binding name="href" />
    <validation message="'action' is a required">
        <unbound name="action"/>
    </validation>
</wo></wodefinitions>

I told the Component Editor to mark the "action" binding as being required to get the boilerplate validation message. Now lets extend the API to handle the "href" binding.

The validation message block supports <and> and <or> tags, so lets try with that:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wodefinitions>
  <wo class="MyReusableComponent" wocomponentcontent = "false">
    <binding name="action" />
    <binding name="href" />
    <validation message="Either 'action' or 'href' must be bound">
      <and>
        <unbound name="action"/>
        <unbound name="href"/>
      </and>
    </validation>
</wo></wodefinitions>

If we test this by embedding our component in a page we’ll see that it works for one potential case. We get a validation warning if we neglect to bind "action" or "href", however it fails to flag us if we bind both. So lets extend the validation rule to handle that case:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wodefinitions>
  <wo class="MyReusableComponent" wocomponentcontent = "false">
    <binding name="action" />
    <binding name="href" />
    <validation message="Either 'action' or 'href' must be bound">
      <or>
        <and>
          <unbound name="action"/>
          <unbound name="href"/>
        </and>
        <and>
          <bound name="action"/>
          <bound name="href"/>
        </and>
      </or>
    </validation>
</wo></wodefinitions>

Not Done Yet

Alternately we could use the "count" directive and write our validation like this:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wodefinitions>
  <wo class="MyReusableComponent" wocomponentcontent = "false">
    <binding name="action" />
    <binding name="href" />
    <validation message="Either 'action' or 'href' must be bound">
      <count test="!=1">
          <bound name="action"/>
          <bound name="href"/>
      </count>
    </validation>
</wo></wodefinitions>

Now We’re Done

The easiest way to learn the different options available for the API validation rules is to browse some existing examples - ERExtensions from Project Wonder or WO’s JavaWOExtensions are two good places to start. Simply open the Framework/Resources folder and browse through the various component API files you find there.

— david @ 11:45 am
May, 07, 2008

WOLips Cheat Sheet

Download it here. I’ve updated it a couple of times with suggestions, but if its still missing anything obvious let me know in the comments.

— david @ 10:12 am
April, 29, 2008

iPhone coming to Canada… soon…

From 680News Radio (yeah radio how quaint):

“We’re thrilled to announce that we have a deal with Apple to bring the iPhone to Canada later this year. We can’t tell you any more about it right now, but stay tuned,” said Ted Rogers, president and CEO of Rogers Communications Inc., in a statement issued today.

That’s just great. Potentially 8 more months to wait…

— david @ 8:32 am
April, 13, 2008

WOWODC 2008 Update

The WOWODC website has been updated with a speakers list and menu for the conference. For first time attendees there is also a travel tips page (which is applicable to WWDC attendees as well).

If you haven’t booked a hotel, I’d do so soon. Things are filling up quickly and it’s getting hard to find affordable accommodation.

— david @ 7:45 pm
April, 05, 2008

Connection Dictionary Twiddling - Part 2

I wrote about using Project Wonder’s ERXConfigurationManager to ‘twiddle’ your model connection dictionary settings here.

I only listed the global properties, but there are per model properties as well. Unfortunately the JDBC settings are not very well documented. So, to google index my brain, here are my notes: Most of the heavy lifting is done by the fixJDBCDictionary method in ERXModelGroup - you can read the source if you want to know all the values - here is a (MySQL) example with the most common ones:

  • MyModelName.URL=jdbc:mysql://localhost/my_dbname?capitalize…etc
  • MyModelName.DBUser=db_user
  • MyModelName.DBPassword=db_password
  • MyModelName.DBDriver=com.mysql.jdbc.Driver
— david @ 8:12 pm
April, 02, 2008

WOWODC 2008 Press

Pascal sent out the WOWODC press release earlier this week and we’ve seen the notice popping up on various sites all week. The best so far has got to be the post on ars technica:

"You think it’s hard being a Mac IT guy? Try being a WebObjects developer. Despite its ease of use, elegance, ridiculously low price, and variety of supported runtime environments, Apple’s web application framework gets next to no respect…"

— david @ 5:11 pm
March, 31, 2008

WOWODC 2008

Mark your calendar! WOWODC 2008 WOCommunity.org’s second annual WebObjects developers conference is taking place the weekend before WWDC at the Parc 55 Hotel in San Francisco.

Pascal Robert (who has done an amazing job pulling this all together) tells me we have an incredible roster of presenters and sessions lined up for the this year. If last years conference is anything to go by, it should be a rip-roaring good time.

Tickets are available here

Disclaimer: I am a member of the WOCommunity.org steering committee.

— david @ 8:39 am
March, 25, 2008

New Screencast

WO/ProjectWonder/WOLips - Part 2

I just completed part 2 of the WO/Wonder/WOLips series. This episode introduces:

  • Reusable components
  • Importing files into your project
  • DirectActions
  • Modeling relationships
  • Updating a db schema with Migrations

It should be in available in WebObjects Podcasts on iTunes, from the WOCommunity site, or direct from my .mac account here.

Resources

Source of the completed project.

As always, comments and suggestions welcome.

— david @ 9:36 pm
March, 21, 2008

Screencasts

I’ve been playing with the very cool ScreenFlow from vara software this week… Did I mention that it was very cool?

Anyway, I put together a couple of introductory screencasts on using WebObjects and WOLips. They can both be found in the WebObjects Podcasts on iTMS or from the WOCommunity site.

HelloWorld

The first is a short HelloWorld tutorial that introduces:

  • Launching Eclipse/WOLips for the first time
  • Creating a new WebObjects project
  • Project folder structure
  • Running the application
  • Modifying the application run settings
  • Editing components

Direct link from my .mac account here.

WO/ProjectWonder/WOLips

The second is a more advanced WO/Wonder/WOLips tutorial that introduces:

  • Database setup using Wonder’s Migrations (NOTE: I use WO 5.3 on Leopard - Migrations are broken in WO 5.4)
  • Inline bindings
  • WOLips’ Add Action, and Add Key dialogs
  • EOGeneration using the Wonder Velocity Template
  • ERXKey and chainable qualifiers

Direct link from my .mac account here.

Resources

Login form mockup.

Source of the completed project.

Notes:

The response from the WO lists has been very positive, so thank you everyone.

Lachlan Deck asked:

Probably helpful to explain why you’re making the ivars public (i.e., in the absence of getter/setters)

My general thoughts on this are:

If -

  • The ivars are only used by the component’s bindings (ie WORepetition item bindings)
  • Are used by bindings and are set in only one action or method in the component
  • Are never exposed by the api

Then I usually feel OK accessing them directly. If I need to expose the variable via the components API or I need to set the ivars value multiple places in the component then I will make the ivar private and wrap it with accessors.

Comments and suggestions welcome.

— david @ 2:02 pm
February, 27, 2008

WO Wideos

Seems like video is the new black in the WO community this week with the Ajax.framework from Project Wonder taking front billing.

Mike Schrag has posted a short video showing how to create and Ajaxify a new WebObjects app demonstrating some of the new features coming to WOLips.

John Larson has posted a YouTube video of some of the stuff he’s done leveraging the Ajax.framework.

— david @ 12:05 pm

WOLips Blog

Mike has created a WOLips blog, making it easier to track it’s meteoric progress.

Subscribed and into the links it goes.

— david @ 11:52 am
February, 22, 2008

La, la, la, I can’t hear you…

Recent reports of our brave and fearless leader sacking (and eliminating the post of) Canada’s National Science Advisor have got me very concerned.

In a time when the human race is facing what may arguably be some of the most complex and important scientific questions in our existence (global climate change, bioengineering, nanotechnology, etc) it is distressing to see the disregard for science shown by our current government.

Following in the footsteps of our southern neighbours, the current Conservative government appears to have set out to systematically dismantled the scientific advisory and oversight system and muzzle scientists for political purposes. This is dangerous and wrong.

Regardless of where you stand on the scientific issues, wouldn’t you want your leaders to be open to learned advice and the most up-to-date information on the topics? I would. Obviously Steven Harper and his crew don’t.

— david @ 11:28 am
February, 04, 2008

SuperDuper! tomorrow?

It looks like Shirt Pocket is planning on releasing a Leopard compatible version of SuperDuper! tomorrow.

— david @ 1:15 pm
January, 29, 2008

Migration to Velocity EOGenerator Complete

With the release of Leopard, I was saddened to learn that we’d lost the use of EOGenerator in the resulting tools deprecations. Thankfully, a couple of major competitors filling that role quickly arose.

I’d mentioned JavaEOGenerator before but after working with it for a bit I decided to go with the Velocity based EOGenerator (veogen) built into WOLips.

I’m happy to report that as of WOLips build 3.3.4778 all of the pieces are in place in the veogen engine to duplicate my existing EOGenerator templates (the last missing bit was the named and typed bindings for fetch specs).

Veogen works very well. It is a lot faster than the old EOGenerator and I didn’t find the template language difficult to figure out.

For those moving to veogen, the built in templates are pretty comprehensive but if you feel the need to customize, there are a number of templates on the wiki to help get you started. The wiki also contains a fairly comprehensive list of the available bindings here.

Go forth and generate.

— david @ 6:37 pm
January, 23, 2008

Cheese and Crackers!

I loves me the internets!

— david @ 6:26 pm
January, 16, 2008

The Mystery Box

J.J. Abrams (Lost, MI 3, Cloverfield) rifs on his creative origins and motivations in this highly entertaining TED talk. It’s a lot of fun, he’s a great speaker.

He also makes some interesting comments about what makes movies compelling. In doing so he says something to the effect that: "When people make sequels … they rip of the wrong thing."

I couldn’t agree more. Pretty much every time I’ve been disappointed by a sequel (Pirates of the Caribbean 2 and 3 anyone?) is because they made a sequel to the wrong parts of a movie I loved.

— david @ 12:05 pm

Winning the Oil End Game

I am not a climate scientist or engineer, I also don’t believe we can consume our way out of the climate crisis, but Amory Lovins makes a compelling case in this TED talk* that modern engineering can go a long way to ease our dependency on fossil fuels for transportation (one of the key contributors of CO2 emissions).

If you are interested in his full reasoning I suggest you read his book "Winning the Oil Endgame" which is available as a PDF download here.

*Is it obvious where I’ve been spending a lot of my free time?

— david @ 11:53 am
January, 15, 2008

The Manpollo Project

How might you go about convincing sceptics that global climate change is something to be worried about?

  • Step 1: Create a short (say 10 minute) video outlining the basic science behind the subject and then use risk management techniques to identify the relative risks of doing something vs doing nothing.
  • Step 2: Release it to the world and wait for the deluge…
  • Step 3: Create a comprehensive set of add-on videos that expand on the subjects and counter every conceivable argument to the science, math, and logic in the original (ie: No, it’s not Pascal’s wager and here’s why…)

This is exactly what wonderingmind42 (a US high school science teacher) has done. The result is a multi-hour youtube tour de force that extensively (yet accessibly) covers the basic science of global climate change along with the fundaments of risk management, the scientific method, information source assessment, and more. All the while keeping it civil and funnily hatted.

Once I started, I couldn’t stop. I watched (and enjoyed) the entire thing.

If you’re not sure about this whole "global warming thing", this is a good place to start. If you’re already convinced, but are looking for ways of explaining the risks to the more skeptical around you without degenerating into pitching horror scenarios, these videos are a great source of information and technique.

The Manpollo Project page has links to all of the videos here.

— david @ 3:28 pm

Nothing for me.

The Macworld 2008 keynote just completed and there is nothing there for me. I’m not disappointed (to be disappointed you need to have expectations) but there is just nothing there.

Time Capsule - Not a problem I needed a solution for.

AppleTV 2.0 - I’ve got a Mac Mini thanks.

Movie Rentals - Uh, no thanks.

iPhone Update - I live in CANADA remember?

MacBook Air - Cute, but I don’t need an unexpandable, fixed battery, non wired, paper think laptop - even if it is super portable. My MBP is my primary computer and I think it’ll stay that way for a while.

— david @ 3:27 pm
December, 04, 2007

Carina Round

We went to see Annie Lennox when she played here in October and I was absolutely blown away by her opening act. Carina Round played a solo accoustic set that gave me shivers. It was one of those tightrope, on the edge, balls out performances that you just don’t forget.

You can hear her stuff here, on her myspace page, and a good minimalist performance video here (Check out Ready to Confess for a glimpse of what we saw live).

Unfortunately none of her albums are available on iTunes in Canada so I had to order actual CDs from Amazon (shudder).

— david @ 1:18 pm
November, 26, 2007

Four!

November 25th marks the date.

— david @ 9:16 am
November, 16, 2007

SuperDuper! update

Dave Nanian from Shirt Pocket Software blogs about the trials and tribulations of getting SuperDuper! updated for Leopard. The post includes some interesting details, for instance: The funky new directory hard links that Time Machine uses are available to other applications (I did not know that!)

  1. I’m glad they are taking this much care to get SD! right.
  2. I’m glad I don’t have anything that relies on the OS X internals to that degree.
— david @ 4:58 pm
November, 11, 2007

Rule Modeler 1.4

Stéphane Corthésy has posted details about Rule Modeler 1.4 here. If you use WebObjects D2W (Direct to Web) then you will want to use this tool.

— david @ 7:53 pm
November, 09, 2007

Time Machine and a new motherboard

It looks like its backup week here at rebelog headquarters…

Apparently TimeMachine uses the MAC (MAC as in "Media Access Control" not Mac as in "Macintosh") address of your ethernet port to identify its backups. If you change your motherboard (like I just did with my MBP) then your MAC address changes and Time Machine will no longer associate your backup with your machine (because as far as TM is concerned it’s a new machine).

You can browse the backup, but if you wish to continue backing up, TM will tell you it cannot find the volume. Opening the TM preferences and pointing at the backup drive will fix that, but TM will create a new backup set from scratch.

Annoying.

— david @ 11:19 am

Mea Culpa… again.

I’ve been using Super Duper! for, like, ever (and therein lies the root of my problem.)

I’ve been using SD! to backup my laptop to an external LaCie drive every night. I’ve been doing this since said laptop was an Aluminum G4. I’ve been doing this since the default partition scheme was "Apple Partition Map". I’ve been doing this since before I got my MacBook Pro…

I’m sure you can see where this is going.

I took my MBP in for repair yesterday (finally got fed up with the thermal shutdown problem it’s always had). No problem I thought - the warm and fuzzy feeling that having a recent SD! backup gives you in full effect. I’ll just boot the new Mac Mini (Core 2 Duo) I bought for the living room off my backup and keep working until the MBP is back.

Uh, no.

Of course the Mac Mini wouldn’t boot from the backup drive (remember that old partition scheme?) OK, time to clone it to another drive… 3 hrs later and 96% of the way through the clone the destination drive dies. OK, try again, different drive, 2 1/2 hours later, the clone is complete (Yay!) but the clone is un-bootable (Boo!).

So, I re-installed Leopard on the destination drive and started to migrate from the backup… Estimated time to completion? ~5 hrs (at which point I gave up).

In case your are keeping track, that equates to an entire day wasted.

2 hrs later while shopping at the mall (and just around the corner from the Apple Store) my cell phone rings. It’s the Apple Store technician, my MBP is ready (Hooray for Pro Care!)

Lesson learned? Always. Test. Your. Backups. Warm and fuzzy feelings don’t actually mean your are safe. Trust, but verify.

— david @ 10:15 am
November, 06, 2007

D’oh!

After installing Leopard on my MBP I noticed that Mail wouldn’t allow me to do "Entire Message" searches. The "Entire Message" button was greyed out.

I tried rebuilding all of my mailboxes in Mail and forcing an index by calling:

    mdimport ~/Library/Mail

Neither helped.

It turns out the MBP’s boot drive had somehow been added to the Spotlight Privacy list…

D’oh!

— david @ 9:41 am
October, 31, 2007

Leopard: WebObjects Notes

Leopard is out and with it comes a slew of WebObjects changes. The release of WO 5.4, the official deprecation of the tool chain (which we’ve known was coming for some time), Apache 2 support, etc.

There’ve been some posts to the webobjects-dev list which I consider required reading. I don’t know if this stuff has made it into the wiki yet, so here are some links:

So, lots going on, and it all looks good IMHO. Should be a good year for WO.

Notes:

  • The permissions on /Library/WebObjects/Configuration needed to be fixed otherwise wotaskd and javamonitor barf.
  • /System/Library/WebObjects/Executables/WOOpenURL seems to be missing. I copied it from the WO53 install and that works. Upate: It turns out that it’s not needed for WO54, it just uses the open command.
— david @ 9:31 am

Leopard: Bug Fix!

nano/pico now refreshes correctly when you resize the terminal window! WOO. HOO.

— david @ 8:56 am
October, 16, 2007

Leopard

It’s official:

leopard_ship.gif

— david @ 9:02 am
October, 09, 2007

Just a few of my favorite things…

Project Wonder is chocked so full of WebObjects goodness that it is hard to envision developing a project without it. Here are three bits that I use all the time.

Autolocking EditingContexts

Step one: Learn WebObjects

Step two: Realize that using the session().defaultEditingContext() exclusively is bad.

Step three: Start using multiple EOEditingContexts.

Step four: Read, re-read, then read again the documentation on EC locking.

Step five: Encounter production deadlocks.

Step six: Cry.

Thankfully Project Wonder provides an amazing solution in the form of autolocking EditingContexts. Enabling them is simple. Set some properties for your project:

er.extensions.ERXApplication.useEditingContextUnlocker=true
er.extensions.ERXEC.defaultAutomaticLockUnlock=true
er.extensions.ERXEC.useSharedEditingContext=false
er.extensions.ERXEC.defaultCoalesceAutoLocks=true

There is an email from Mike Schrag with some juicy details here.

Change your code so that you never call new EOEditingContext(); instead use the ERXEC.newEditingContext() factory method.

ERXThreadStorage

Problem: You need access to an object in your session from an EO. Maybe you want to set a "createdBy" value to the current user in awakeFromInsertion

Adding a reference to the Session in your EOs would be bad so what are you going to do?

Solution: Use ERXThreadStorage to store a reference to the current user and access that from your EO.

In your Session.java:

public User currentUser; // assume exists

public void awake() {
    super.awake();
    ERXThreadStorage.takeValueForKey(currentUser, "currentUser");
}

In your EO.java:

public void awakeFromInsertion(EOEditingContext ec) {
    super.awakeFromInsertion(ec);
    User user = ERXThreadStorage.valueForKey("currentUser"));
    if (user != null) {
        setCreatedBy(user.userName);
    }
}

ERXGenericRecord

ERXGenericRecord is another Project Wonder class that is full of yumminess. Please read the API docs for the full details, but here are a few of my favorites:

willUpdate(); // called after saveChanges() but before validation
              // so it is safe to make changes. See the rest of
              // will* and did* methods for more

primaryKey(); // returns the primary key (null if the EO hasn't
              // been saved yet)

primaryKeyInTransaction(); // returns the primary key as above,
              // but if the EO hasn't beens saved yet, it'll
              // figure out what the pk should be, return it,
              // cache it, and use it later when the EO does get
              // saved. Very cool.

There is much, much more: ERXLocalizer, ERJavaMail, ERExcelLook… Dive into the docs and I’m sure you’ll find something usefull.

— david @ 10:11 am

WOLips: New .woo editor

There are five files assosiated with a WebObjects component (.html, .wod, .woo, .api, and .java). In WOBuilder you could add and configure a WODisplayGroup in your component and it’s configuration would get stored in the .woo file.

The only way to edit the .woo file in WOLips’ component editor was to use a text editor…

Up until now that is. There is a new “Display Group” addition to the Component editor tabs:

display_group_tab.gif

Which reveals a Display Group manager window (similar to the API manager). Adding a Display Group gives you a nifty Details editor:

display_group_dialog.gif

I don’t use component configured WODisplayGroups much, but I know a lot of people do and this is a welcome addition.

— david @ 8:52 am
October, 08, 2007

WOLips nightly builds are back on!

It looks like there is good reason to risk the move to Eclipse 3.3.1 and the WOLips nightly builds. Mike Schrag has unleashed a much enhanced outline view that is wickedly cool. I’ve linked to a little movie that demonstrates it here.

— david @ 10:31 pm
September, 15, 2007

WebObjects Deployment Notes

Deployment is a big hairy subject, and I don’t pretend to be an expert, but these are some notes of things that help me.

Some caveats: I only develop on Mac OS X Client with Eclipse+WOLips and install on Mac OS X Server, so these notes probably won’t make any sense for anyone else… sorry.

WARNING !AOOGA HORN SOUND! Not a tutorial, just a little list of tips, if you’ve got any tips of your own to add, leave a comment.

1. Use Project Wonder:

No justification, just do it.

2. Use split Properties:

Create multiple sets of Properties to minimize the amount of tweaking.

For example: Configure the one in your project (I dub thee "Project") and the other in the root of your home directory (I’ll call you "Local") with different values.

Set the Project properties to those that make sense for deployment, they will be overridden by the values in the Local properties which you configure for development.

Additionally, use this suggestion from Mike Schrag:

… and also Properties.yourusername. For instance, I have a Properties.mschrag that lets me set per-project-per-user properties overrides. Very handy.

If you need to access a property in your code use ERXProperties to do so, you’ll get the same property searching and caching behaviour that ERXConfigurationManager uses:

    String admin = ERXProperties.stringForKey("cs.project.adminname")

This means there are far fewer "little tweaks" to be made when deploying.

3. Build locally with embedded frameworks:

Modify your build.xml file to embed your frameworks:

   <frameworks root="${xxx.xxxx}" embed="true"></frameworks>

This will make your application bundle a lot bigger, but it also means that you’ve completely eliminated any possibility of a version conflict between your new app deployment and any existing applications.

To build the app, just select something in the Eclipse Package Explorer view and ctrl+click -> WOLips Ant Tools -> Install… Select the apps to install and click "OK".

The resulting app bundle(s) will be installed in /Library/WebObjects/Applications/

4. Copy the app to the server:

I usually zip my app bundle and copy it to the server via ssh where I have a script that extracts the archive into /Library/WebObjects/Applications/. Though rsync is looking more and more attractive… when I get the time. :-)

5. Prep the virtual doc root:

I’m going to assume that most apps are deployed behind an Apache virtual domain configured to point at a subdirectory of the main doc root (i.e. /Library/WebServer/Documents/_site).

The app’s resource manager is going to expect to find web server resources in the following places:

Application:

 _site/
  WebObjects/
    AppName.woa/
      Contents/
        WebServerResources/

Frameworks:

 _site/
  WebObjects/
    Frameworks/
      FrameworkName.framework/
        WebServerResources/

Because we are embedding all of the frameworks, the framework’s WebServerResources will actually be in your app’s bundle. So, you could copy the WebServerResources directories from the apps and frameworks to those paths, or your could create sym-links, which is what I do.

I use a little script (prepWebObjectsDeploy.sh) to help me do that.

Because I use sym-links, this only has to be done the first time I install the app (unless subsequent releases add Frameworks to the build).

James Brook offers this tasty tip in the comments: Instead you can specify a property in the woapplication task of your ant build. If you set ‘frameworksBaseURL="/WebObjects/MyApp.woa/Contents/ Frameworks/Library /Frameworks"’ the application will link to the resources in the embedded directories.

6. Test the installed app:

After copying the app, it’s usually a good idea to test the app via the command line to catch any weirdities:

   root# /Library/WebObjects/Applications/AppName.woa/AppName

7. Configure Monitor

I’m not going to talk about Monitor much, there are lots of other places that cover that in detail. The only thing I always make sure to do is to create a directory for the app’s logs (usually in /Library/Logs/WebObjects/AppName/) and set the Output path accordingly.

Profit!

— david @ 2:48 pm
September, 14, 2007

Connector/J Null Dates Behaviour

To get MySQL Connector/J versions > 3.0 to gracefully handle null dates, append zeroDateTimeBehavior=convertToNull to your jdbc url.

Example:

jdbc:mysql://host/dbname?capitalizeTypenames=true&zeroDateTimeBehavior=convertToNull

— david @ 6:28 pm

Connection Dictionary Twiddling

Another "so I don’t have to look it up" post:

Connection dictionaries are the collection of information in your eomodel that configures your access through jdbc to your database.

It is possible to set/modify this information through code and I, along with many others, have built classes that read these settings from your Properties file on app launch. Project Wonder has ERXConfigurationManager that will do this for you as well.

Example:

  • dbConnectURLGLOBAL=jdbc:mysql://host/dbname
  • dbConnectUserGLOBAL=dbuser
  • dbConnectPasswordGLOBAL=dbpassword

Just drop those entries into your Properties file and away you go. Also, because the ERXConfigurationManager reads all your Properties files, you can override the settings in your project with personal ones in your ~/WebObjects.properties resulting in fewer changes to make when deploying. In fact that little trick works great for er.javamail and log4j settings as well.

— david @ 6:23 pm
September, 10, 2007

KnoppMyth R5F27

Zap2It pulled the plug on their free tv listings service earlier this month (my listings run out on the 17 th), luckily Schedules Direct (SD for those in the know) stepped up to the plate with a replacement service (not free but cheap enough).

Cecil from KnoppMyth posted instructions on getting SD to work on KnoppMyth R5F1 by installing XMLTV and the latest MythTV fixes but I’m too lazy.

Anyway, the KnoppMyth R5F27 .iso was just released with SD support and more, Xtorrent is downloading it now.

— david @ 5:16 pm
September, 09, 2007

Note to self…

Don’t call session.terminate() unless you are really sure you’re done with it…

Hilarity will ensue.

— david @ 11:40 pm

Suppressing the wosid in a DirectAction

Two common means of generating DirectAction URLs in WebObjects are by using the directActionName bindings available in WOHyperLink (and it’s brethren) and by using the WOContext method: directActionURLForActionNamed(String name, NSDictionary).

Kol. Panic offered a tip on suppressing the Session ID (wosid) in DirectAction urls generated from a WOHyperLink in the comments of this post.

It turns out that there is a similar method if you are generating the URL in your code from a WOContext:

  public String loginUrl() {
    NSDictionary dict = new NSDictionary(
        new Object[] {Boolean.FALSE},
        new String[] {"wosid"});
    return context().directActionURLForActionNamed("login", dict);
  }

September, 01, 2007

D2W: Wildcards beware!

Don’t you just hate it when you outsmart yourself (and make your self feel stupid in the process)?

In Direct To Web it is possible to have wildcards in the rules and these are often used to automatically determine pageConfiguration values. For instance you might have a set of rules that look like this:

50 pageConfiguration like *Applicant* --> entity = "Applicant"
50 pageConfiguration like *Contact* --> entity = "Contact"
50 pageConfiguration like *Division* --> entity = "Division"

And another set of rules that looks like this:

50 pageConfiguration like Edit* --> task = "edit"
50 pageConfiguration like Inspect* --> task = "inspect"
50 pageConfiguration like List* --> task = "list"

So far so good. You get some nice pageConfigurations that kinda configure themselves wrapping your common tasks and model objects (ie: pageConfiguration EditApplicant -> task = ‘edit’ and entity = ‘Applicant’). But…

Add one more rule:

50 pageConfiguration like EditRelationship* -->
					task = "editRelationship"

And things get icky, now there is a conflict between Edit* or EditRelationship* so the rule engine goes with the first match… but not always, once in a blue moon it will do what you wanted it to do. Just enough to keep you thinking there’s something broken in your templates or EOModel. It can’t be the rules… "’Cause, heck it worked a minute ago!"

I knew about this! I did! I ran into it with compound names in my EOs (ie: Contact, BigContact) but that didn’t stop me from wasting a ton of time on it anyway.

Oh, the fix is easy. Just take the second rule and give it a higher precedence:

55 pageConfiguration like EditRelationship* -->
					task = "editRelationship"

It’s the beating your head against a wall of your own making that is hard.

— david @ 1:33 am
August, 30, 2007

D2W: Grouping fields in edit form

To group your edit form fields use sectionsContents instead of displayPropertyKeys. A rule for a User for might look like this:

LH: pageConfiguration = 'EditUser'
RH: sectionsContents =
(
  (
    "Personal Info",
    "salutation",
    "firstName",
    "lastName",
    "emailAddress",
    "phone",
    "phoneExtension",
    "mobile"),
  (
    "Address",
    "address.address1",
    "address.address2",
    "address.city",
    "address.province",
    "address.postalCode"),
  (
    "Details",
    "organization",
    "role",
    "loginCredential.password",
    "loginCredential.isActive",
    "loginCredential.role"
  )
)

This will result in a form that looks something like this:

d2w_segmented_form.gif

Standard assumptions apply: Wonder’s D2W classes are being used.

— david @ 5:27 pm

D2W: List default sort order

Assumptions: Your D2WList page inherits from ERD2WListPage in Wonder (and if it doesn’t it should).

Apply a default sort order on the list with a rule that looks like this:

LH: task = 'list' and entity.name = 'User'
RH: defaultSortOrdering = ( "name",
"compareAscending" )

Class: com.webobjects.directtoweb.Assignment

Also available are:

compareAscending
compareCaseInsensitiveAscending
compareCaseInsensitiveDescending
compareDescending.

— david @ 4:53 pm
August, 05, 2007

Interesting stuff post

A couple of interesting bits and pieces today:

Blueprint is a CSS frameworks for making grid based web page layout much easier. It incorporates a decent reset.css (to clear all of the default rules set by the various browsers giving you a clean slate) then adds a grid.css and typography.css to give you a consistent base to start with.

I’m not much of a designer, and hacking CSS is fun, but only until it stops being fun (if that makes any sense). Anyway, this looks like a very promising start at making the fun bit last longer.

Via the Daring Fireball linked list.

ERAttachment is an addition to Project Wonder that provides a consistent mechanism for handling file attachments to web apps built in WebObjects. From the javadoc:

The framework provide a single unified set of components and models that can allow the storage of attachments on your local filesystem, served through your webserver; on your local filesystem served through a custom request handler; in your database, served through a custom request handler; and on Amazon’s S3 service, served directly from S3.

I’ve had to handle this kind of thing in a number of apps, allowing users to upload files and serve them back again. Very cool to see this make it into Wonder.

Via an email from Mike Schrag to the Wonder-disc email list.

— david @ 10:58 pm
July, 25, 2007

Kol. I salute you!

Kol. Panic over at Voodoo Ergonomics just launched the project he’s been mumbling about for years.

All that R&D finally paid off in a slick little app called Mojotones. Mojotones makes it easy to create ringtones from any track in your iTunes library and (just as easy) to move them to your bluetooth equipped cell phone.

You can read the details here.

— david @ 11:01 pm
July, 04, 2007

Colloquy - blank chat window

If you use Colloquy.

And, You get a persistent blank window when you join an IRC channel.

Then type /reload style while in the channel.

— david @ 8:43 am