On Sat, Aug 8, 2009 at 20:50, Asiri
Rathnayake<asiri.rathnayake(a)gmail.com> wrote:
Hi All,
When working on officeimporter document splitting feature we wanted to make
it possible to provide hooks so that the whole import process can be
customized external to the officeimporter module via a groovy class (on a
wiki page). Since we were in a little hurry, the solution we devised might
be called "hackish"; we provided the following interface which can be
implemented in groovy:
<code>
public interface OfficeImporterFilter {
void filter(String documentName, Document document);
void filter(String documentName, XDOM xdom, boolean isSplit);
String filter(String documentName, String content, boolean isSplit);
void setDocBridge(DocumentAccessBridge docBridge);
}
</code>
Now, Officeimporter application would pass a parameter into
DefaultOfficeImporter indicating the wiki page which contains the groovy
filter implementation. Then we do something like:
<code>
String groovyFilterParam = params.get("groovyFilter");
String groovyScript = docBridge.getDocumentContent(groovyFilterParam);
GroovyClassLoader gcl = new GroovyClassLoader();
OfficeImporterFilter importerFilter =
(OfficeImporterFilter) gcl.parseClass(groovyScript).newInstance();
importerFilter.setDocBridge(docBridge);
return importerFilter;
}
</code>
The purpose of setDocBridge() method is to inject the DAB into the filter so
that it can access wiki documents. Now I question myself why it is not
possible for a groovy class to access wiki documents without the DAB. This
also proves that this solution was not well planned or discussed with the
community. Another problem with the filter interface is that it does several
things. It would have been better to have three filters instead.
Now to the topic of this email; if we can allow groovy code to implement
XWiki components (if it is possible), we can make this whole thing very
simple. For an example, officeimporter application would pass the role-hint
of the component implementing a particular filter (which is a groovy
implementation) and DefaultOfficeImporter will simply lookup this component
and use it.
As for implementing this kind of a mechanism, we can follow something
similar to what we did with wiki macros. A special class
XWiki.XWikiComponent would contain fields like componentRole (String),
roleHint (String) & groovyClass(TextArea) and when a document with an object
of XWiki.WikiComponent is saved, we can register a new component against the
CM.
This idea was suggested to me by vincent & I thought it's time to start a
discussion about this to see what others think. Although I have few unclear
points (like how dependency injection would work), I think it would be a
handy tool to have.
Thanks in advance for your comments & suggestions :)
Note that you can register an component you want simply by using the
component manager api. So this work with any language as soon as it
can access Utils.getComponentManager() and has class and object
support (like groovy for example).
So the quickest way would be to list pages to execute at startup.
Among other things they could register any component they want.
- Asiri
PS: OfficeImporter code has been polluted a lot because I have stuffed a lot
of features into it without properly designing them. I will be refactoring
officeimporter a little by little in coming days (as time permits).
_______________________________________________
devs mailing list
devs(a)xwiki.org
http://lists.xwiki.org/mailman/listinfo/devs
--
Thomas Mortagne