Tuesday January 12, 2010
In this post I describe how to create doc/literal-style Web Services for Confluence using XFire.
Why do you want to do that?
There are two alternatives. Confluence provides the web service plugin module, which offer good support for rpc-style services. However, these don’t work well with some clients, as some platforms do not support rpc-style web services.
Instead of using web services REST might be an alternative. Since Confluence 3.1. there is a plugin module type for REST interfaces, which builds the JAX-WS reference implementation called Jersey. Btw, the REST plugin module type also work on Confluence 3.0, but you will have to install some plugins manually. While REST is certainly the way to go for future developments, it has the same short coming as RPC-style web services: client platforms may not be able to use it (or at least make it hard to use it).
In my case the doc-literal web service client is InfoPath (part of Microsoft Office), which works allows users to edit pages in a office-style application and better keeps the structure of a page than the Word editor.
Overview
XFire is a quite old project and is actually now maintained/developed as CXF at Apache. However, there are three reasons for using XFire: XFire is included in the Confluence distribution, CXF still has some dependencies to XFire and introducing another library doesn’t make things easier (believe me I tried).
In order to use XFire we need to setup the dependencies correctly, create and deploy a XFireServlet as a servlet module, which handles the HTTP request and invokes the XFire web service stack.
POM Configuration
It is not possible to import the XFire packages through OSGi Bundle-Instructions (Atlassian does not expose it to plugins for whatever reason), so it is necessary define XFire as a dependencies. On the other hand it is necessary to exclude all unneeded or conflicting dependendencies of XFire. I added the following dependencies to the default dependency section:
<dependency>
<groupId>org.codehaus.xfire</groupId>
<artifactId>xfire-aegis</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.xfire</groupId>
<artifactId>xfire-java5</artifactId>
<version>1.2.6</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.xfire</groupId>
<artifactId>xfire-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>xfire</groupId>
<artifactId>xfire-jsr181-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.xfire</groupId>
<artifactId>xfire-core</artifactId>
<version>1.2.6</version>
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</exclusion>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
</exclusion>
<exclusion>
<groupId>stax</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.ws.commons</groupId>
<artifactId>XmlSchema</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>wstx-asl</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
The XFire-Servlet
The XFire-Servlet handles HTTP Requests and invokes the XFire web service stack, which in turn hands over the web service call to our service implementation. Therefore the servlet initializes the service in the servlets init() method (when trying this yourself, please not that the init() method gets called lazily on first access).
public class MyXfireServlet extends XFireServlet {
public void init() throws ServletException {
super.init();
// The ObjectServiceFactory creates services from Java objects
ObjectServiceFactory factory = new ObjectServiceFactory(getXFire().getTransportManager(), null);
// we don't want to expose compareTo
factory.addIgnoredMethods("java.lang.Comparable");
Service service = factory.create(DokumentService.class, "dokument", null, null);
service.setProperty(ObjectInvoker.SERVICE_IMPL_CLASS, DokumentServiceImpl.class);
// unregister old Service
Service oldService = getServiceRegistry().getService("dokument");
if(oldService != null) {
getServiceRegistry().unregister(oldService);
}
getServiceRegistry().register(service);
}
protected ServiceRegistry getServiceRegistry() throws ServletException {
return getController().getServiceRegistry();
}
}
To register the service the following is needed in Atlassian XML:
<servlet name="Form Editor Servlet" key="com.k15t.example"
class="com.k15t.example.webservice.XfireServlet">
<url-pattern>/xfire/*</url-pattern>
</servlet>
This will make the XfireServlet to be available at http://localhost:1990/confluence/plugins/servlet/xfire/ (replace the hostname, port and context root and note the trailing slash). It will list the available services including a link to retrieve the WSDL for the service. In our case there is one service called “dokument”.
Implementing the Service
As you can see above the service is defined in the interface DokumentService and the implementation is implemented in DokumentServiceImpl. XFire will take care of converting the SOAP message to method parameters, if the service interface only uses the following types (source):
- Basic types: int, double, float, long, byte[], short, String, BigDecimal
- Arrays
- Collections
- Dates: java.util.Date, java.util.Calendar, java.sql.Timestamp, java.sql.Date, java.sql.Time
- XML: org.w3c.dom.Docmument, org.jdom.Element, XMLStreamReader, Source
- Complex types which are aggregations of the above
This is the interface of the service, the implementation is calling the Confluence API to do stuff (Dokument is a complex bean containing some page data):
public interface DokumentService {
public Dokument load(String spaceName, String pageId, String token);
public void save(Dokument document, String token);
}
That’s all.
It is important to notice, that the ServiceRegistry is shared between different XFireServlets, so take care if you install multiple of those.
Posted on Jan 12, 2010 at 12:06 (MET) |
Permalink |
Saturday March 14, 2009
While there weren’t any news related to Sun’s JWebPane, there is a new contestant: WebKit for SWT by Genuitec. The website says:
WebKit for SWT (ver. 0.5) is an embeddable Java™ WebKit browser component developed by Genuitec. This component can be used in the development of a wide range of Java SWT applications that require integration of rich HTML5, CSS3, JavaScript and Flash content and functionality.
The solution seems a little bit more high-level than Sun’s approach: While Sun is integrating WebKit directly, Genuitec build on top of Google’s chromium. The biggest difference however at this time: They provide code, documentation and samples.
Posted on Mar 14, 2009 at 10:50 (MET) |
Permalink |
Monday February 9, 2009
JWebPane provides WebKit as a Swing component - how cool is that. Let the UI guys use HTML/CSS to do the user interface, and let the Java guys implement the functionality.
Not tested, not even downloadable yet, just wanted to let you know…
Posted on Feb 9, 2009 at 21:47 (MET) |
Permalink |
Thursday January 8, 2009
2009 will be interesting. This is the last entry of this series of posts, about my thoughts/wishes about technological improvements in 2009. Previous entries: Really Rich Internet Applications, Easy JavaScript for Everyone, Databases and Persistence, Distributed Version Control.
Wiki-based documentation will become the single source for documentation in 2009. While wikis have been great for collaboratively created documentation ever since, the problem is that they are not very well export their contents to other formats in order to ship documentation as printed books or integrated online help. DocBook export is needed here.
I have requested this[1] for my favourite wiki[2] back in 2004 with no luck. However, this year we will ship a solution[3] for this. The Scroll Wiki Exporter for Confluence lets wiki-users export their documentation from trees of wiki pages to DocBook and PDF. Eventually we will support other output formats, pluggable, themes, and much more.
[1] Feature request for DocBook Export: CONF-762
[2] Atlassian Confluence
[3] Scroll Wiki Exporter
Posted on Jan 8, 2009 at 06:14 (MET) |
Permalink |
Wednesday January 7, 2009
2009 will be interesting. In this series of posts, I publish some thoughts/wishes about technological improvements in 2009. Previous entries: Really Rich Internet Applications, Easy JavaScript for Everyone, Databases and Persistence.
Couple years back, I thought CVS was ok. Nowadays, I think it was crap and I am happy that I don’t have to use it anymore. Instead I use Subversion, which I thought SVN was ok. After watching Linus’ talk about DVCS and Git[2] and using it for SproutCore, I am sure that SVN days are counted, too. My bet is on Git, because it is already well established among open-source projects through github. Mercurial is nice, as is provides an SVN interface.
Note: I heard a couple times people telling that Git only works on Linux and Macs. Don’t believe that[3].
[1] Two DVCS contenders:Git, Mercurial
[2] Linus Torvalds on git
[3] GIT on Windows
Posted on Jan 7, 2009 at 06:00 (MET) |
Permalink |
Tuesday January 6, 2009
2009 will be interesting. In this series of posts, I publish some thoughts/wishes about technological improvements in 2009. Previous entries: Really Rich Internet Applications, Easy JavaScript for Everyone.
Before I go on, let me state: Relational Databases will continue to stay as the backbone of persistence.
BUT: Non-relational databases will become more popular this year. Examples include document oriented data stores[1] or as graphs databases[2]. Also, it will become more popular to split storage and search. This will allow more flexibility and search performance. E.g. store your data in different data stores, and keep a local index/copy for searching[3].
[1] Couch DB
[2] Neo DB
[3] Read this blog (and comments) for a very nice overview.
Posted on Jan 6, 2009 at 08:11 (MET) |
Permalink |
Saturday October 18, 2008
Greg has written a good write up about the recent misunderstanding of the open source model (Spring, ExtJS).
Quote:
But those of us who work in open source, must not forget that freedom is the at core of our model and that we must grant those freedoms on a non-discrimanatory basis.
+1
Posted on Oct 18, 2008 at 15:36 (MET) |
Permalink |
Sunday October 12, 2008
After a lot of feedback from the community (including myself), SpringSource decided to tune their maintenance policy. Although we are not at the original status with the maintenance releases, I am satisfied that maintenance releases will be available for each major version until the next major version is out.
Also, Rod’s clear statement about Spring’s license makes me a little bit more confident about my engagement with the Spring community:
Let me take this opportunity once again to guarantee that Spring will remain open source for the community, under the current (Apache) license. Period.
Also, it seems that at least parts of Spring 3 are available in a public repository. According to Matt it is available here: https://src.springframework.org/svn/spring-framework/trunk/. I didn’t find much code there, but Jürgen pointed out that they are behind schedule. So let’s keep our fingers crossed.
Posted on Oct 12, 2008 at 14:38 (MET) |
Permalink |
Sunday October 5, 2008
A little bit of background: SpringSource recently announced that after the first three months after a major release they would only provide maintenance releases to paying customers. The press release was very unclear, but finally in the discussion at TSS Rod made clear what this means for non-paying customers:
- SpringSource will create release builds within the first three months. Important: By “major release” they also mean releases like 2.5 or 3.1, which some might consider minor releases.
- After the first three months SpringSource will commit all patches to the public Spring CVS repository, but will neither create release builds nor tag the releases (only to their paying customers).
I don’t want to judge whether SpringSource turned to the bad side by this. However, as Rod points out the real open source community would be able follow the source repository activity and compile a maintenance release themselves (Rod at TSS) when they need it for their project. But there is an issue, which Rod is is not addressing.
If every open source project will compile their own Spring releases and bundle them with their software, we are all very likely to get into BIG problems with our dependencies. If you use framework A and framework B in you project, which both rely on Spring, it is very likely they they will come with different builds of the Spring code, and now it is up to you to decide which Spring build to use in order to have running system. More so, all Maven dependency management efforts are in vain, when there is no tagged version. (BTW: This is not only an issue for non-paying Spring users, but also for the paying folks…)
So what can we do? I thought about this for a while, and I think there are not many options. Referring to daily builds from the repository will lead to proliferation and eventually to dependency hell. Some big companies may make the effort to build their own Spring releases and have some Spring mavens who are responsible for creating internal Spring releases. The third option, and IMO the best option are community builds.
The community can discuss the patches committed to the source repository and decide when to create a community release. This effort has already started: Clinton Begin registered freespring.org, which is supposed to provide tagging based on some voting system. That way, I hope we will all be able to continue to use Spring (and all the frameworks and other software, which build on it) as we do today.
Let’s support freespring.org and hope that SpringSource does care about their community and will not attempt to stop this effort!
Posted on Oct 5, 2008 at 20:22 (MET) |
Permalink |
Monday August 11, 2008
John has posted an article about how to use the archetype:generate plugin. The plugin will present the available archetypes and then lets you entered the required artifacts.
Much better than typing the rather lengthy command line params (if you remembered them anyway).
Posted on Aug 11, 2008 at 11:25 (MET) |
Permalink |
Previous Posts