Auto Java Syntax checking in XCode

I don’t use XCode if I can help it (no sir, don’t like it) so I spend most of my time in Eclipse. I find it a superior Java IDE for a number of reasons (build on the fly, code completion, no index, etc) and one of the biggest reasons for me is syntax checking. I find it saves me a ton of time, no need to build and wait for the syntax error before realizing I’ve missed a ";"

Kieren has posted an interesting tip that gives you access to some of this yumminess in XCode. Granted, it’s not as nice as Eclipse, but next time I’m forced to use XCode it’ll come in handy.

WebObjects thoughts.

  1. Don’t fight the tool – WebObjects and EOF are very flexible and rich in capablilites. Get to know the way they work and work with them. Don’t fight them – they will win. Read the sample code from Apple and the source for Project WONDER. When you write your code emulate their style. The really good stuff is just below the surface (Key Value Coding for example). That’s where the power lives, dig a little, you will be rewarded.
  2. Follow the commandments – A few simple rules that will prevent a world of hurt.
  3. Let someone else write the code – I’ve mentioned a number of sources of WebObjects frameworks in my posts (Project WONDER, SwitchableStrings, WOCode ). They provide an amazing amount of functionality that you don’t need to implement yourself, that’s the entire point of OO design isn’t it? Also, when you build something useful, factor it out into your own reusable framework – why would you want to write something twice? Finally, use EOGenerator – no really – use it. There is no excuse not to.
  4. Model it right the first time – Every time I’ve been tempted to cut corners on my model, it’s come back to bite me. A strong Model will allow your App to almost write itself. My general rule of thumb: If I can’t get from one object to a “related” one via KVC, I’m going to be grumpy.
  5. If it is getting complicated, you’re probably doing it wrong
    • You’re fighting the tool aren’t you?
    • Maybe WebObjects is the wrong tool.

    Please, don’t try to hack around the WebObjects architecture. i.e. If you really need multiple concurrent access to your database everywhere in your application – use something other than EOF.

Using EOGenerator with WOLips/Eclipse 3.0

I use EOGenerator extensively when working with WebObjects. In WOLips/Eclipse 2.0 I had a GenerateEOs task in my build.xml file (I copied it from a post by Chuck Hill to the WOProject mail list). Unfortunately, it no longer works in WOLips/Eclipse 3.0. There is a WOGen Ant task that should be able to duplicate what EOGenerator does, but well, I’m just stuck in my ways.

As suggested on the WOProject list, I configured EOGenerator to run as a Builder for my project using the following steps:

  1. Select the appropriate Project/Framework in the Eclipse Package Explorer
  2. Select Properties from the Project menu and then select Builders
  3. Click the New button
  4. Configure the fields in the the window as follows:
    • Name: EOGenerator
    • Location: /Developer/Applications/eogenerator/eogenerator
    • Arguments: (shown on separate lines for clarity only)
      • -model ${project_loc}/superduperproject.eomodeld
      • -destination ${project_loc}/src/ca/codebase/substrate/
      • -subclassDestination ${project_loc}/src/ca/codebase/substrate/
      • -templatedir /Developer/Applications/eogenerator/
      • -javaTemplate CBJavaSourceEOF5.eotemplate
      • -subclassJavaTemplate CBJavaSubclassSourceEOF5.eotemplate
      • -define-copyrightYear “2003 – 2004”
      • -define-copyrightBy “Codebase Software Systems”
      • -verbose
      • -java
  5. Click Apply

Notes:

  1. ${project_loc} is an Eclipse variable (it contains the path to the project).
  2. I keep eogenerator and it’s templates in a folder in /Developer/Applications/ and my EO’s are in the ca.codebase.substrate package, change the paths above to reflect your environment.
  3. In Build Options for the Builder, select when you want to Run the builder. I find the defaults (After a “Clean” and During Manual Builds) are fine for my needs.

Programatically creating a WODisplayGroup

I like WODisplayGroups. OK, call me crazy – or lazy – but I like them alot. However, I do find that I often need more control over them than the drag and drop creation gives me. So here is how I like to set up WODisplayGroups programatcially:

Just to prevent any potential confusion: This example demonstrates creating a WODisplayGroup from scratch, and will not work if you’ve created one by dragging an Entity from EOModeler into WebObjects Builder. – Thanks Alex!

Using this pattern setup the _displayGroup object

protected WODisplayGroup _displayGroup;
 
public WODisplayGroup displayGroup() {
	if (_displayGroup == null) {
		prepDisplayGroup();
		find();
	}
	return _displayGroup;
}
public void setDisplayGroup(WODisplayGroup dg) {
	_displayGroup = dg;
}

Add the prepDisplayGroup() method:

public void prepDisplayGroup() {
	_displayGroup = new WODisplayGroup();
	_displayGroup.setNumberOfObjectsPerBatch(10); 
	EOSortOrdering asc = EOSortOrdering.sortOrderingWithKey(
			"keyToSortOn", 
			EOSortOrdering.CompareAscending);
	NSArray ordering = new NSArray(new Object[] {asc});
	_displayGroup.setSortOrderings(ordering);
}

The WODisplayGroup API is here

Finally add the find() method:

public void find() {
	NSArray foundObjects = //fetch your objects here
	displayGroup().setObjectArray(foundObjects);
}

In my find() method I usually take advantage of the objectsFor... methods that can be generated by EOGenerator. These wrap your EOModel’s fetchSpecs in static methods in your EO’s, very cool. Take a look at the EOGenerator EOGJavaSource.eotemplate for more details. Update: I’ve blogged more details about my EOGenerator templates here

I often base my search pages on a common super class that includes a displayGroup along with variables for setting objects per batch and a search string amongst other things.

Lazy WOComponent ivar initialization

How do you setup instance variables if they need to be initialized after their WOComponent is fully formed?

Overiding the awake() method happens too early, so you’re usually left overriding later in the request-response loop *. Here is a nice simple alternative pattern that I use all the time.

  1. Create your instance variables (I like to make them protected at least)
    protected NSArray _myThings;
  2. Give your ivars public accessor methods
    public NSArray myThings() {
    	return _myThings;
    }
     
    public void setMyThings(NSArray array) {
    	_myThings = array;
    }
  3. Modify the getter method so it follows this pattern:
    public NSArray myThings() {
    	if (_myThings == null) {
    		//initialize _myThings here
    	}
    	return _myThings;
    }

This pattern works really well for setting up things like display groups or arrays of fetched objects. If you bind to the accessor method in your WOComponent, the first time the method is hit, the values will be initialized. Very clean and easily understood. I like it a lot 🙂

* You do know the stages of the request-response loop don’t you? If you don’t buy Chuck’s book. Do it now. I’ll wait…