|
|||
|
|
Developing With OddjobUnder the covers Oddjob is a big rip off of Apache Ant, so please read their documentation Developing With Ant which is much better than this. Oddjob does have some difference which I'll come to later, but If you understand Ant then understanding Oddjob will be easy. Contents:
ComponentsOddjob, like many application frameworks, uses the idea of a component. There are many definitions of a component, but in Oddjob it is simply something which can be dynamically created and added to other components. In oddjob a component is anyjava.lang.Object with a no argument constructor.
Writing your Own component
package learn.oddjob;
public class FirstComponent {
}
Which isn't to hard. You can fire this up with oddjob using the following configuration:
<oddjob>
<anything class="learn.oddjob.FirstComponent"/>
</oddjob>
Oddjob will instantiate your component and then
attempt to do a lot of things which won't have
any affect. Most noteably it hasn't run anything
because our component isn't a Job, which means it
doesn't implement the Jobs really come later but as you want to see some stuff happen we'll now extend our first component to be our first job.
package learn.oddjob;
public class FirstJob implements Runnable {
public void run() {
System.out.println("Hello World!");
}
}
Change the configuration to:
<oddjob>
<anything class="learn.oddjob.FirstJob"/>
</oddjob>
And now when you run oddjob we get the expected "Hello World!" displayed on the console. Enough about jobs until later because we still haven't finished with components... The Lifecycle of a component.At parse time:
At run time:
At termination:
Changing the LifecycleYour own component can change
the default configuration for all it's child elements by implementing a
method with the signature
Alternatively providing a method with the signature
As an example, the ForEach job provides it's own hander which records the child job definition so that it can be used to create a new child job for each of it's values later, when it is executed. Elements, Components and PropertiesElements are Objects created for nested XML elements which your component uses to do it's stuff. The Ant manual is very good on this subject and Oddjob behaves exactly like Ant with regard to nested elements so I won't ellaberate more here. A nested component is also a nested XML element, except that it's created by the framework and registered so that others can get and set it's properties and even execute and stop it. And when it does execute you have very little idea about what it's doing. In the analogy of the family home the nested element is like your power tools - you have complete control. Your nested component is like your own child. You have responsibilities (see below) but very little control! A nested property allows complicated types to set using a
Properties in DetailAs an example - here's the code for a simple component with a slightly complicated property.
package learn.oddjob;
public class ShoopingComponent {
private String[] shopping;
public void setShopping(String[] shopping) {
this.shopping = shopping;
}
public String[] getShopping() {
return shopping;
}
}
And this would configure the ShoppingComponent:
<oddjob>
<anything class="learn.oddjob.ShoppingComponent">
<shopping>
<value value="beer"/>
<value value="wine"/>
<value value="piza"/>
</shopping>
<anything/>
</oddjob>
Oddjob has a list of types and the Objects to create to interpret the XML. These are known as property proxies. For String[] it creates a ListType which takes care of the value elements. The type can be any object just like an element
but it can optionally also supply a Values are of two overlapping sorts. The types that act as property proxies for an attribute type are defined in proxies.properties. The types that are created via a factory from their tag name such as <value> (which is ValueType) are declared in types.properties. Property ConversionsWhen a property gets resolved using ${x.y.z} notation Oddjob uses BeanUtils to do this. It also uses the BeanUtils converters which enable string to be converted to number etc. Please see the BeanUtils documentation for more information. XML to Java Object SummaryWhich method gets called for which bit of XML is slightly confusing so here is a summary. <comp1 stuff="thing"/>
<comp1> <moreStuff stuff="thing"/> </comp1>
If your component has more than one of the above then which is called is undefined.
<comp1>
<moreStuff>
<stuff name="fred" stuff="thin"/>
</moreStuff>
</comp1>
The Differences with AntValues not References - Ant allows you to declare a type which you then refer to by a reference. Oddjob uses Values to achieve this. Properties - In Ant properties are something in their own right. In Oddjob properties are only ever properties of a Component. Task vs Components - Ant has addTask, Oddjob has addComponent. Conceptually they are very similar. Briefly - here are some of the reasons for there being differences.
But the main reason for the difference is Oddjob and Ant are aimed at very different problem domains. Ant is a build tool. Oddjob is a scheduler. Writing Your Own JobWe already mentioned a job is a component
which implements While this is the simplest definition of a job, a job can be so much more by implementing certain interfaces, listed below, which provide great flexibility to how your job behaves. Nine time out ten, however you would like you job to behave like any other job and to help you do this quickly there is SimpleJob. SimpleJobA job can be so much more, very quickly by extending
package learn.oddjob;
import org.oddjob.jobs.AbstractJob;
public class BetterJob extends SimpleJob {
protected int execute() {
System.out.println("Hello World!");
return 0;
}
}
The main advantage to extending From The Ground UpIf SimpleJob doesn't suit your needs for whatever reason then the other approach is to build a Job using any combination of these interfaces: The Responsibilities of Being a ParentIf your job provides a addComponent() or an addComponentXXX() then a child or children may have been created and will have been handed over for your sole care. As such:
As an aside this responsibility issue is why there is no support for an
inline attrribute child. This would be a child which is set
using a ThreadingAn Oddjob job should be designed so that a job is only run by one
thread at a time. If you extend A job can be run from a thread which was not the thread which set it's properties. Because of this and the java memory model you need to take precautions to ensure a consisitent state. Options include
The last option is the easiest if extending SimpleJob. This also protects against properties changing when the job is executing. What We've MissedPersistance, Using Oddjob jobs in your own code, coming soon... |
||