2009 is ending, time to look back at a productive and very interesting year.
As mentioned in earlier posts, I'm working on a software called Scodi which is currently released as version 3.4.x.
For the next version 4.0, we dumped all the old code and rebuild the whole software using new and "fancy" technologies.
Version 3.4 was a fat RCP client, version 4.0 will be a server-client application.
That said, I had the pleasure to integrate a lot of amazing frameworks and APIs into our new software.
EMF to model our business objects, Teneo and Hibernate to persist those objects.
The Spring framework to create our beans and register some of them as OSGi services, Riena to publish them for remote access.
Apache Jackrabbit to store and version some of our data.
jBPM to handle workflows (e.g. data that is being committed needs to be reviewed by certain users) and a Mylyn connector to handle those user tasks.
This November I took a look at GMF to build our Process Flow designer, the designer itself will be developed by another company.
Towards the end of this year I cleaned out our RCP client to make it RAP ready as we have a web part of our software.
The EMF based UI framework which I built last year, uses RCP and SWT per default. The framework works on the web now including databinding, field decorations and such. RAP is great and single sourcing a blessing :-).
Using all these technologies I reported about 30-40 bugs I hope to soon find more time to contribute back to the open source community. My project on sourceforge.net "workreporter" didn't get any commits this year, I was fully concentrating on Scodi.
It was a busy year and I'm looking forward to release version 4.0 in 2010.
Wednesday, December 30, 2009
Thursday, December 24, 2009
Override Eclipse Key Binding
A few weeks back is was struggling with an Eclipse key binding problem. I had to override the CTRL+S binding. Since I had my own "org.eclipse.ui.bindings" extension, I keept on getting conflict messages (no wonder).
So I thought I'll make a post as personal reference and maybe it helps some other developer.
This is what I did in ApplicationActionBarAdvisor.makeActions().
So I thought I'll make a post as personal reference and maybe it helps some other developer.
This is what I did in ApplicationActionBarAdvisor.makeActions().
IBindingService bindingService = (IBindingService) window.getService(IBindingService.class);
bindingService.addBindingManagerListener(new IBindingManagerListener() {
@Override
public void bindingManagerChanged(BindingManagerEvent event) {
BindingManager manager = event.getManager();
for (Binding binding : manager.getBindings()) {
ParameterizedCommand command = binding.getParameterizedCommand();
if (command != null && ActionFactory.SAVE.getCommandId().equals(command.getId())) {
manager.removeBinding(binding);
}
}
}
});
IWorkbenchAction saveDocumentAction = ActionFactory.SAVE.create(window);
saveDocumentAction.setId("saveDocument");
saveDocumentAction.setActionDefinitionId(SAVE_DOCUMENT_COMMAND);
register(saveDocumentAction);
Monday, December 21, 2009
SWT instead of AWT packages
Today I got annoyed using eclipse code completion to add a KeyAdapter on a SWT component. Instead of adding the SWT KeyAdapter (since it's a SWT widget), eclipse suggests the AWT KeyAdapter before the SWT KeyAdapter. The result of this is that I often choose the wrong one.
Same thing with other classes like KeyListener, MouseListener...
So I was looking for a solution, eclipse should ignore the java.awt package.
I have not found a way to handle this for the whole workspace using preferences.
I now exclude the java.awt package in all my UI bundles from their Java Build Path.
Maybe you have had the same "trouble" and never thought about getting rid of it :-)
Same thing with other classes like KeyListener, MouseListener...
So I was looking for a solution, eclipse should ignore the java.awt package.
I have not found a way to handle this for the whole workspace using preferences.
I now exclude the java.awt package in all my UI bundles from their Java Build Path.
Maybe you have had the same "trouble" and never thought about getting rid of it :-)

Saturday, September 12, 2009
Interview
At the beginning of this month, my employer (henzler informatik gmbh) sent out a newsletter to all our customers.
Part of it was an interview with myself, about the development I'm involved with and about my working day.
It's in German but if anybody is interested, here is the link:
SCODi 4P Newsletter September 2009: Interview mit Flavio Donzé
Haven't been blogging lately, I'm really busy working on this version 4 of SCODi 4P.
Part of it was an interview with myself, about the development I'm involved with and about my working day.
It's in German but if anybody is interested, here is the link:
SCODi 4P Newsletter September 2009: Interview mit Flavio Donzé
Haven't been blogging lately, I'm really busy working on this version 4 of SCODi 4P.

Sunday, July 12, 2009
jBPM 4.0 is Out!
jBPM 4.0 was released last Friday, more infos on that can be found here.
As read in the readme.html file, the two bugs I reported were fixed:
[JBPM-2319] - Finished executions are not changed to "ended" (they stay in the "active" state)
[JBPM-2340] - TaskService getTaskComments throws NullPointerException if the task is not found
Thanks guys great work!
As read in the readme.html file, the two bugs I reported were fixed:
[JBPM-2319] - Finished executions are not changed to "ended" (they stay in the "active" state)
[JBPM-2340] - TaskService getTaskComments throws NullPointerException if the task is not found
Thanks guys great work!
Wednesday, July 8, 2009
Migrate oAW projects to Eclipse Galileo
As we all know, oAW moved into the Eclipse Galileo release.
More information on that here.
The new projects can be found here:
Modeling Workflow (MWE)
Model to Text (M2T)
Textual Modeling Framework (TMF)
In the project I'm working on, we use EMF to generate the model objects and oAW to generate services for the generated objects, which then are published using Eclipse Riena.
After the Galileo release, I had to update my current oAW workflow using the new workflow components and dependencies.
First I downloaded the required bundles for my target platform and IDE, you can get them from the Galileo update site.
Galileo - http://download.eclipse.org/releases/galileo/
> Modeling
Bundles
Now finally the changes I made on the file itself:
old generator.oaw
new generator.mwe
Basically only the namespace of the component classes changed.
Ending the whole story I have to say that I launch the workflow in my application using the org.eclipse.emf.mwe.core.WorkflowRunner.run(...) which works fine.
If I launch the workflow by itself "Run As -> MWE Workflow" I get an strange
"java.lang.ClassNotFoundException: org.eclipse.jface.text.BadLocationException" Exception, strange because I don't get why there should be an dependency on jface.
More information on that here.
The new projects can be found here:
Modeling Workflow (MWE)
Model to Text (M2T)
Textual Modeling Framework (TMF)
In the project I'm working on, we use EMF to generate the model objects and oAW to generate services for the generated objects, which then are published using Eclipse Riena.
After the Galileo release, I had to update my current oAW workflow using the new workflow components and dependencies.
First I downloaded the required bundles for my target platform and IDE, you can get them from the Galileo update site.
Galileo - http://download.eclipse.org/releases/galileo/
> Modeling
- MWE SDK
- Xpand SDK
- Xtext SDK
Bundles
- org.eclipse.emf.mwe.core;bundle-version="0.7.0",
- org.eclipse.emf.mwe.utils;bundle-version="0.7.0",
- org.eclipse.xtend;bundle-version="0.7.0",
- org.eclipse.xpand;bundle-version="0.7.0"
- com.ibm.icu.text;version="4.0.1",
- org.antlr.runtime;version="3.0.0",
- org.eclipse.jdt.core,
- org.osgi.framework,
- org.slf4j;version="1.5.6"
Now finally the changes I made on the file itself:
old generator.oaw
<?xml version="1.0"?>
<workflow>
<property file="workflow/settings.properties"/>
<!-- properties set through the generator -->
<property name="ecoreFile" value=""/>
<property name="outputLocation" value=""/>
<!-- set up EMF for standalone execution -->
<bean class="org.eclipse.mwe.emf.StandaloneSetup" >
<platformUri value=".."/>
</bean>
<!-- load basic model and store it in slot 'model' -->
<component class="org.eclipse.mwe.emf.Reader">
<uri value="${ecoreFile}" />
<modelSlot value="model" />
</component>
<!-- Service Interfaces -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<expand value="template::Service::interface FOREACH model.eClassifiers" />
<globalVarDef name="productName" value="'${productName}'"/>
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<outlet path="${outputLocation}${serviceInterfaceSrc}" >
<postprocessor class="org.openarchitectureware.xpand2.output.JavaBeautifier" />
</outlet>
</component>
<!-- Service Objects -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<expand value="template::Service::javaClass FOREACH model.eClassifiers" />
<globalVarDef name="productName" value="'${productName}'"/>
<globalVarDef name="serviceInternalPackage" value="'${serviceInternalPackage}'"/>
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<outlet path="${outputLocation}${serviceInternalSrc}">
<postprocessor class="org.openarchitectureware.xpand2.output.JavaBeautifier" />
</outlet>
</component>
<!-- Service Properties File -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<expand value="template::Service::properties FOR model" />
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<globalVarDef name="serviceInternalPackage" value="'${serviceInternalPackage}'"/>
<outlet path="${outputLocation}${serviceInternal}/META-INF/spring/">
<postprocessor class="com.softmodeler.generator.postprocessor.XmlBeautifier" />
</outlet>
</component>
<!-- Test Cases -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<expand value="template::Test::javaClass FOREACH model.eClassifiers" />
<globalVarDef name="productName" value="'${productName}'"/>
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<globalVarDef name="testPackage" value="'${testPackage}'"/>
<outlet path="${outputLocation}${testSrc}">
<postprocessor class="org.openarchitectureware.xpand2.output.JavaBeautifier" />
</outlet>
</component>
<!-- All Tests Suite -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<expand value="template::Test::allTests FOR model" />
<globalVarDef name="testPackage" value="'${testPackage}'"/>
<globalVarDef name="productName" value="'${productName}'"/>
<outlet path="${outputLocation}${testSrc}">
<postprocessor class="org.openarchitectureware.xpand2.output.JavaBeautifier" />
</outlet>
</component>
</workflow>
new generator.mwe
<?xml version="1.0"?>
<workflow>
<property file="workflow/settings.properties"/>
<!-- properties set through the generator -->
<property name="ecoreFile" value=""/>
<property name="outputLocation" value=""/>
<!-- set up EMF for standalone execution -->
<bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" >
<platformUri value=".."/>
</bean>
<!-- load model and store it in slot 'model' -->
<component class="org.eclipse.emf.mwe.utils.Reader" uri="${ecoreFile}">
<modelSlot value="model" />
</component>
<!-- first do some cleanup -->
<component class="org.eclipse.emf.mwe.utils.DirectoryCleaner" directory="${outputLocation}${serviceInterfaceSrc}" />
<component class="org.eclipse.emf.mwe.utils.DirectoryCleaner" directory="${outputLocation}${serviceInternalSrc}" />
<component class="org.eclipse.emf.mwe.utils.DirectoryCleaner" directory="${outputLocation}${serviceInternal}" />
<component class="org.eclipse.emf.mwe.utils.DirectoryCleaner" directory="${outputLocation}${testSrc}" />
<!-- Service Interfaces -->
<component class="org.eclipse.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
<expand value="template::Service::interface FOREACH model.eClassifiers" />
<globalVarDef name="productName" value="'${productName}'"/>
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<outlet path="${outputLocation}${serviceInterfaceSrc}" >
<postprocessor class="org.eclipse.xpand2.output.JavaBeautifier" />
</outlet>
</component>
<!-- Service Objects -->
<component class="org.eclipse.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
<expand value="template::Service::javaClass FOREACH model.eClassifiers" />
<globalVarDef name="productName" value="'${productName}'"/>
<globalVarDef name="serviceInternalPackage" value="'${serviceInternalPackage}'"/>
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<outlet path="${outputLocation}${serviceInternalSrc}">
<postprocessor class="org.eclipse.xpand2.output.JavaBeautifier" />
</outlet>
</component>
<!-- Service Properties File -->
<component class="org.eclipse.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
<expand value="template::Service::properties FOR model" />
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<globalVarDef name="serviceInternalPackage" value="'${serviceInternalPackage}'"/>
<outlet path="${outputLocation}${serviceInternal}/META-INF/spring/">
<postprocessor class="com.softmodeler.generator.postprocessor.XmlBeautifier" />
</outlet>
</component>
<!-- Test Cases -->
<component class="org.eclipse.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
<expand value="template::Test::javaClass FOREACH model.eClassifiers" />
<globalVarDef name="productName" value="'${productName}'"/>
<globalVarDef name="serviceInterfacePackage" value="'${serviceInterfacePackage}'"/>
<globalVarDef name="testPackage" value="'${testPackage}'"/>
<outlet path="${outputLocation}${testSrc}">
<postprocessor class="org.eclipse.xpand2.output.JavaBeautifier" />
</outlet>
</component>
<!-- All Tests Suite -->
<component class="org.eclipse.xpand2.Generator">
<metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
<expand value="template::Test::allTests FOR model" />
<globalVarDef name="testPackage" value="'${testPackage}'"/>
<globalVarDef name="productName" value="'${productName}'"/>
<outlet path="${outputLocation}${testSrc}">
<postprocessor class="org.eclipse.xpand2.output.JavaBeautifier" />
</outlet>
</component>
</workflow>
Basically only the namespace of the component classes changed.
Ending the whole story I have to say that I launch the workflow in my application using the org.eclipse.emf.mwe.core.WorkflowRunner.run(...) which works fine.
If I launch the workflow by itself "Run As -> MWE Workflow" I get an strange
"java.lang.ClassNotFoundException: org.eclipse.jface.text.BadLocationException" Exception, strange because I don't get why there should be an dependency on jface.
Friday, May 22, 2009
Jackrabbit/JCR Versioning FAQ
There is not a lot of documentation about Jackrabbit/JCR versioning around. So I thought I could publish a little FAQ about JCR versioning.
How do I make a Node versionable?
How to get the current Version of a Node?
How do I increment the minor version of a Node?
How do I increment the major version of a Node?
You can't, simple as that.
http://osdir.com/ml/apache.jackrabbit.devel/2005-10/msg00417.html
How to restore a node?
The output will be:
CURRENT: test 3
RESTORED: test 2
How do I iterate over all versions of a Node?
Do I have to add JcrConstants.MIX_VERSIONABLE to my subnodes?
No, changed subnodes are correctly stored under the version of the versionable Node.
OUTPUT:
Version: 1.0
test 1
Description: this is a description
Version: 1.1
test 2
Description: this is a NEW description
How can I export a Node and all it's Versions?
That's not possible.
If I delete a Node will it's history be deleted as well?
No you have to iterate over the versions and call VersionHistory.removeVersion(String versionName);
Usefull links:
http://www.onjava.com/pub/a/onjava/2006/10/04/what-is-java-content-repository.html?page=1
http://jcp.org/en/jsr/detail?id=170
How do I make a Node versionable?
node.addMixin(JcrConstants.MIX_VERSIONABLE);
How to get the current Version of a Node?
node.getBaseVersion();
How do I increment the minor version of a Node?
node.checkout();
node.setProperty("title", new StringValue("test"));
getSession().save();
node.checkin();
How do I increment the major version of a Node?
You can't, simple as that.
http://osdir.com/ml/apache.jackrabbit.devel/2005-10/msg00417.html
How to restore a node?
node.checkout();
node.setProperty("title", new StringValue("test 2"));
getSession().save();
Version lastVersion = node.checkin();
node.checkout();
node.setProperty("title", new StringValue("test 3"));
getSession().save();
node.checkin();
System.out.println("CURRENT: " + node.getProperty("title").getValue().getString());
node.restore(lastVersion, true);
System.out.println("RESTORED: " + node.getProperty("title").getValue().getString());
The output will be:
CURRENT: test 3
RESTORED: test 2
How do I iterate over all versions of a Node?
VersionIterator i = node.getVersionHistory().getAllVersions();
i.skip(1); // important, otherwise the currentNode will fail to read the 'title' property
while (i.hasNext()) {
Version v = i.nextVersion();
NodeIterator nodeIterator = v.getNodes();
while (nodeIterator.hasNext()) {
Node currentNode = nodeIterator.nextNode();
System.out.println("Version: " + v.getName());
System.out.println(currentNode.getProperty("title").getValue().getString());
}
}
Do I have to add JcrConstants.MIX_VERSIONABLE to my subnodes?
No, changed subnodes are correctly stored under the version of the versionable Node.
Node node = root.addNode(name);
node.addMixin(JcrConstants.MIX_VERSIONABLE);
node.setProperty("title", new StringValue("test 1"));
Node subnode = node.addNode("subnode");
subnode.setProperty("descr", "this is a description");
getSession().save();
node.checkin();
node.checkout();
subnode = node.getNode("subnode");
subnode.setProperty("descr", "this is a NEW description");
node.setProperty("title", new StringValue("test 2"));
getSession().save();
node.checkin();
VersionIterator i = node.getVersionHistory().getAllVersions();
i.skip(1);
while (i.hasNext()) {
Version v = i.nextVersion();
NodeIterator nodeIterator = v.getNodes();
while (nodeIterator.hasNext()) {
Node currentNode = nodeIterator.nextNode();
System.out.println("Version: " + v.getName());
System.out.println(currentNode.getProperty("title").getValue().getString());
if (currentNode.hasNodes()) {
for (NodeIterator childs = currentNode.getNodes(); childs.hasNext();) {
Node child = childs.nextNode();
System.out.println("Description: " + child.getProperty("descr").getValue().getString());
}
}
}
}
OUTPUT:
Version: 1.0
test 1
Description: this is a description
Version: 1.1
test 2
Description: this is a NEW description
How can I export a Node and all it's Versions?
That's not possible.
If I delete a Node will it's history be deleted as well?
No you have to iterate over the versions and call VersionHistory.removeVersion(String versionName);
Usefull links:
http://www.onjava.com/pub/a/onjava/2006/10/04/what-is-java-content-repository.html?page=1
http://jcp.org/en/jsr/detail?id=170
Labels:
content,
jackrabbit,
java,
jcr,
repository,
version
Subscribe to:
Posts (Atom)