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 :)
Now for the things which work even with velocity it's more complex for
doing it the generic way.
One solution I can think of right now:
- first have class/objects to mimic component descriptor (like we do
for wiki macros)
- a jmock like dynamic proxy which will be registered to the
component Manager (because you have to implement the proper interface
to give it to the CM)
- when a method is called we execute the page content with in the
context a "component" object (like the "macro" object of wiki macros)
- $context.component.fieds.set/getField1 to store anything a
component want to persist in the component instance (if it's not a
per-lookup component)
- $context.component.method return the name of the method called
we can then organise the script with some #if/#elseif based on the
method name (or call the corresponding method of the object it stored
in component.fields the first time it has been called, for language
like groovy which i'm sure have easy tools to call an object method
from a string)
- $component.parameters.param1 to get the parameters of the method
- $component.setResult() to inject to the result of the execution
- 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