What I want to do?
I'm working on a Apache Cocoon Project and want to find solution to return paramaters in HTML pages.
I need to get the parameter, which has ArrayList type, and use it in HTML page in order to fill a table. How can I do this? Is it correct to set a request parameter? If yes, then how to use it inside HTML code? If no, then how to return the parameter correctly?
ActionClass.java
public class ActionClass implements Action, ThreadSafe{
public Map act(Redirector rdrctr, org.apache.cocoon.environment.SourceResolver sr, Map map, String string, Parameters params) throws Exception {
// READ REQUEST
Request request = ObjectModelHelper.getRequest(map);
// DO SOMETHING XQUERY VIA BASEX, SPARQL RDFSTORE WHATEVER
ArrayList<ResultBean> results = xquery();
Map sitemapParams = new HashMap();
// SET REQUEST PARAMETER
request.setAttribute("results",results);
return sitemapParams;
}
}
ResultBean.java
package com.kiddo.grlegislation;
public class ResultBean {
private String id;
private String title;
private String type;
public void setId(String i){
this.id = i;
};
public void setTitle(String t){
this.title = t;
};
public String getId(){
return this.id;
};
public String getTitle(){
return this.title;
};
}
First of all, are you sure that you need an Action? Actions are meant to act somehow (update something in the database, invoke a web service, etc). If you just need to generate content, a Generator class could be a better fit for you...
Anyway... How could you return something from an Action into HTML? Lets see it with an example:
Action class: because it extends Action, it must return a Map. Just add there whatever data you need to pass to your HTML:
package com.stackoverflow;
public class ActionClass extends Action {
public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters params) {
Map<String, String> sitemapParams = new HashMap<String, String>();
sitemapParams.put("myVariable", "hello world!");
return sitemapParams;
}
}
sitemap.xmap: in your sitemap file, you can access any data returned by the Action, by placing it's key between brackets. Then you can pass it to your HTML generator:
<map:components>
<map:actions>
<map:action name="myAction" src="com.stackoverflow.ActionClass" />
</map:actions>
</map:components>
...
<map:match ...>
<map:generate ... />
<map:act type="myAction">
<map:transform src="myTransformation.xsl">
<map:parameter name="something" value="{myVariable}"/>
</map:transform>
</map:act>
<map:serialize .../>
</map:match>
myTransformation.xsl: your XSLT file should read the data and embed it into your HTML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="something" select="'default value if you wish to specify one'"/>
<xsl:template match="xxx">
<html><body>...
<xsl:value-of select="$something" />
...</body></html>
</xsl:template>
</xsl:stylesheet>
You can get more information about Actions, Generators and the sitemap in this page. It's from Apache Cocoon 2.1 documentation, but it also applies to 2.2.
Generator class: this file builds a XML document, which is then passed into the pipeline. You could have something like this:
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
...
public class GeneratorClass extends AbstractGenerator {
private String foo;
@Override
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters params) throws ProcessingException, SAXException, IOException {
super.setup(resolver, objectModel, src, params);
// you can read input parameters in here:
foo = params.getParameter("someParameter");
}
public void generate() throws IOException, SAXException, ProcessingException {
ArrayList<ResultBean> beans = xQuery(foo);
// Let's build the XML document. I'll do it by manually appending text strings,
// but there is no need, we could just use Xstream or any similar library
StringBuilder xml = new StringBuilder();
xml.append("<results>");
// Iterate through the array list...
for (ResultBean b : beans) {
xml.append("<result>");
xml.append("<id>").append(b.getId()).append("</id>");
xml.append("<title>").append(b.getTitle()).append("</title>");
xml.append("</result>");
}
// ... and we end the XML string
xml.append("</results>");
// Return the XML to Cocoon's pipeline
XMLReader xmlreader = XMLReaderFactory.createXMLReader();
xmlreader.setContentHandler(super.xmlConsumer);
InputSource source = new InputSource(new StringReader(xml.toString()));
xmlreader.parse(source);
try {
this.finalize();
} catch (Throwable e) {
}
}
}
Sitemap.xmap: you just need to call your generator, and then apply your XSLT to the generated XML:
<map:components>
<map:generators>
<map:generator type="myGenerator" src="com.stackoverflow.GeneratorClass" />
</map:generators>
/<map:components>
<map:generate type="myGenerator">
<!-- if you need to pass input data to the generator... -->
<map:parameter name="someParameter" select="{request-param:something}" />
</map:generate>
<map:transform src="myTransformation.xsl" />
<map:serialize type="html"/>
myTransformation.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head></head>
<body>
<table>
<xsl:for-each select="results/result">
<tr>
<td><xsl:value-of select="id/text()"/></td>
<td><xsl:value-of select="title/text()"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
You can get more info about Cocoon generators here. Once again, it's an official tutorial for Cocoon 2.1, but it's also valid for Cocoon 2.2.