You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Joshua Long <lh...@adelphia.net> on 2005/03/05 12:41:09 UTC
CSV Renderer Link thingy.. CSV Component donation...
Hi guys
I am donating a CSV component if anyone wants it... when used, it allows
you to render a link that when clicked will return a CSV
(comma-seperated value) dump of a 2 dimensional array that you pass in.
Interesting sidebar: csv dumps whose first row, and first cell, contain
'ID' (without quotes, in capital letters) will cause Excel on OS X to
freak out and die. 'Id','id', all work fine..
ANYWAY!
I'll post it somewhere like Tacos eventually,but I'm sure it might stand
some improvement/feedback and I'm somewhat pressed for time.
I'm licensing it under the do-whatever-you-want-with-it-but-remember
your-old-pal-Josh-when-you-win-the-lottery-or-make-cool-changes-to-it
license.
Joshua Long
josh@joshlong.com
Code, documentation follow
to get it working int he application, of course, put the following in
the application specification
<service name="com.roartechnologies.ap.view.services.csv-service"
class="com.roartechnologies.ap.view.services.CSVService"/>
Anyway, here are the various cogs of the machine...
/// first the component class....
package com.roartechnologies.ap.view.components.csv;
import com.roartechnologies.ap.view.services.CSVService;
import org.apache.tapestry.AbstractComponent;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
/**
* @author Joshua Long (josh@joshlong.com)
*
* Builds a request to our CSVService, which in turn
* does the heavy lifting of generating
* the actual dump.
*
* This follows a pretty standard idiom
* as set forth in <i>Tapestry In Action</i>
*
*/
public abstract class CSVComponent extends AbstractComponent {
public abstract Object getMap();
public abstract void setMap(Object mp);
public abstract Boolean getDisabled();
public abstract void setDisabled(Boolean mp);
protected void renderComponent(IMarkupWriter writer,
IRequestCycle cycle) {
if (cycle.isRewinding())
return;
Boolean disabled = getDisabled();
if (disabled != null) {
if (disabled.booleanValue()) {
writer.begin("span");
writer.attribute("class", "csv_disabled");
renderInformalParameters(writer, cycle);
writer.printRaw("CSV");
writer.end();
return ;
}
}
Object map = getMap();
if (null == map)
Tapestry.createRequiredParameterException(this, "map");
String key = Long.toString(System.currentTimeMillis());
cycle.getRequestContext().getSession().setAttribute(key, map);
IEngineService service =
cycle.getEngine().getService(CSVService.SERVICE_NAME);
ILink link = service.getLink(cycle, this, new Object[]{key});
String url = link.getURL();
writer.begin("a");
writer.attribute("class", "csv_enabled");
writer.attribute("href", url);
renderInformalParameters(writer, cycle);
writer.printRaw("CSV");
writer.end();
}
}
// next the backend service
package com.roartechnologies.ap.view.services;
import com.generationjava.io.CsvWriter;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.engine.AbstractService;
import org.apache.tapestry.engine.IEngineServiceView;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.request.ResponseOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.MessageFormat;
import java.util.Date;
/**
* @author Joshua Long (josh@joshlong.com)
* <p/>
* The service takes the key passed in from
* the component and uses it to lookup the dump
* in a known place and then it generates the actual dump.
* <p/>
* This component uses the <i>Generation Java CSV </i>
* component to generate the CSV response stream.
* <p/>
* I am not too sure where to find it,
* but it's worked wonders for me and I completely recommend it.
*/
public class CSVService extends AbstractService {
public static final String SERVICE_NAME =
"com.roartechnologies.ap.view.services.csv-service";
public String getName() {
return SERVICE_NAME;
}
public void service(IEngineServiceView service_view,
IRequestCycle cycle,
ResponseOutputStream os) throws
ServletException, IOException {
Object[] params = getParameters(cycle);
String key = (String) params[0];
HttpSession session = cycle.getRequestContext().getSession();
Object mp = session.getAttribute(key);
if (null == mp) {
System.out.println(MessageFormat.format("There is no key
with value {0} exiting @ {1,date,long}", new Object[]{key, new
Date()}));
}
Object[][] rows_array = (Object[][]) mp;
RequestContext context = cycle.getRequestContext();
HttpServletResponse response = context.getResponse();
String dispositionHeader =
MessageFormat.format("attachment;filename=report_{0}.csv",
new
Object[]{Long.toString(System.currentTimeMillis())});
response.setHeader("Content-Disposition", dispositionHeader);
os.setContentType("application/vnd.ms-excel");
/* "text/comma-separated-values");*/
CsvWriter csv_writer = new CsvWriter(new
OutputStreamWriter(os));
for (int i = 0; i < rows_array.length; i++) {
Object row [] = rows_array[i];
String[] string_row = new String[row.length];
for (int a = 0; a < row.length; a++) {
string_row[a] = row[a] == null ? "" : row[a].toString();
}
csv_writer.writeLine(string_row);
}
csv_writer.close();
}
public ILink getLink(IRequestCycle iRequestCycle, IComponent
iComponent, Object[] objects) {
return constructLink(iRequestCycle, SERVICE_NAME, null, objects,
false);
}
}
/// now, finally, the specification..
<!DOCTYPE component-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<component-specification
class="com.roartechnologies.ap.view.components.csv.CSVComponent"
allow-body="yes"
allow-informal-parameters="yes">
<parameter name="map"
direction="in"
required="yes"
type="java.lang.Object"/>
<parameter name="disabled"
direction="in"
required="no"
type="java.lang.Boolean"/>
<reserved-parameter name="href"/>
</component-specification>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Query on update within form
Posted by Nick Westgate <ni...@key-planning.co.jp>.
I had a similar situation with floors, rooms & beds of a rest home.
Floors and beds are drop-downs. This is how I did my initialisation:
(All the setX() functions are for persistent properties)
public abstract class BedsView extends BedControlPage implements
PageRenderListener
{
// ...
public void pageBeginRender(PageEvent event)
{
// initialize properties etc
if (!event.getRequestCycle().isRewinding())
{
// ...
if (getFloorSelectionModel() == null)
{
// this model is created only once
ArrayList floorList = getBedCache().getFloorStringList();
floorList.add(0, getMessage("selectAllString"));
setFloorSelectionModel(new FloorSelectionModel(floorList));
setFloor(getFloorSelectionModel().getValue(0));
setPreviousFloor(getFloor());
if (getRoomSelectionModel() == null)
{
setRoomSelectionModel(getNewRoomSelectionModel());
setRoom(getRoomSelectionModel().getValue(0));
}
}
// ...
Cheers,
Nick.
Derick Fernando wrote:
> Quoting sales <sa...@digiatlas.net>:
>
>
>>Anybody?
>>
>>
>>sales wrote:
>>
>>>My question is, where is it best to initialise things? Each list gets
>>>initialised in the model when the models are realised. However, I also
>>>need a way to initialise the page variables (county needs to be
>>>initialised to a real county ID value, not 0, in order for Place to be
>>>populated correctly from the database).
>
>
> Hi,
>
> Check the wiki for lazy initialization and the pageBeginRender method. You
> should implement the PageRenderListener and lazy initialize your variables
> there.
>
> ........................
> Derick Fernando
> Lead Architect
> TheLab, LLC
> http://www.thelabllc.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Query on update within form
Posted by Derick Fernando <de...@thelabllc.com>.
Quoting sales <sa...@digiatlas.net>:
> Anybody?
>
>
> sales wrote:
> >
> >
> > I have a form with two drop-downs. The second of these (Place) gives a
> > list of place names which depend on the first drop-down (County). I
> > have county submit the form when the user selects something so that
> > Place gets populated with a new list of places.
> >
> > My question is, where is it best to initialise things? Each list gets
> > initialised in the model when the models are realised. However, I also
> > need a way to initialise the page variables (county needs to be
> > initialised to a real county ID value, not 0, in order for Place to be
> > populated correctly from the database).
> >
> > I have put the following for my accessors for the models:
> >
> >
> > public IPropertySelectionModel getPlaceModel()
> > {
> > if (placeModel == null)
> > {
> > placeModel = new PlaceModel();
> > }
> >
> > return placeModel;
> > }
> >
> >
> > public IPropertySelectionModel getCountyModel()
> > {
> > if (countyModel == null)
> > {
> > countyModel = new CountyModel();
> > setCounty(((Integer)countyModel.getOption(0)).intValue());
> > }
> >
> > return countyModel;
> > }
> >
> >
> > My callback to handle the form asks the Place model to re-fetch its data.
> >
> > But I'm not sure I'm really going about this the right way. It also
> > won't work unless I make the page properties, County and Place,
> > persistent. Obviously I only want to initialise County when the page is
> > first displayed to the user - subsequent submits and redisplays should
> > leave County as-is.
> >
> > dd
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
Hi,
Check the wiki for lazy initialization and the pageBeginRender method. You
should implement the PageRenderListener and lazy initialize your variables
there.
........................
Derick Fernando
Lead Architect
TheLab, LLC
http://www.thelabllc.com
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: Query on update within form
Posted by sales <sa...@digiatlas.net>.
Anybody?
sales wrote:
>
>
> I have a form with two drop-downs. The second of these (Place) gives a
> list of place names which depend on the first drop-down (County). I
> have county submit the form when the user selects something so that
> Place gets populated with a new list of places.
>
> My question is, where is it best to initialise things? Each list gets
> initialised in the model when the models are realised. However, I also
> need a way to initialise the page variables (county needs to be
> initialised to a real county ID value, not 0, in order for Place to be
> populated correctly from the database).
>
> I have put the following for my accessors for the models:
>
>
> public IPropertySelectionModel getPlaceModel()
> {
> if (placeModel == null)
> {
> placeModel = new PlaceModel();
> }
>
> return placeModel;
> }
>
>
> public IPropertySelectionModel getCountyModel()
> {
> if (countyModel == null)
> {
> countyModel = new CountyModel();
> setCounty(((Integer)countyModel.getOption(0)).intValue());
> }
>
> return countyModel;
> }
>
>
> My callback to handle the form asks the Place model to re-fetch its data.
>
> But I'm not sure I'm really going about this the right way. It also
> won't work unless I make the page properties, County and Place,
> persistent. Obviously I only want to initialise County when the page is
> first displayed to the user - subsequent submits and redisplays should
> leave County as-is.
>
> dd
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Query on update within form
Posted by sales <sa...@digiatlas.net>.
I have a form with two drop-downs. The second of these (Place) gives a
list of place names which depend on the first drop-down (County). I
have county submit the form when the user selects something so that
Place gets populated with a new list of places.
My question is, where is it best to initialise things? Each list gets
initialised in the model when the models are realised. However, I also
need a way to initialise the page variables (county needs to be
initialised to a real county ID value, not 0, in order for Place to be
populated correctly from the database).
I have put the following for my accessors for the models:
public IPropertySelectionModel getPlaceModel()
{
if (placeModel == null)
{
placeModel = new PlaceModel();
}
return placeModel;
}
public IPropertySelectionModel getCountyModel()
{
if (countyModel == null)
{
countyModel = new CountyModel();
setCounty(((Integer)countyModel.getOption(0)).intValue());
}
return countyModel;
}
My callback to handle the form asks the Place model to re-fetch its data.
But I'm not sure I'm really going about this the right way. It also
won't work unless I make the page properties, County and Place,
persistent. Obviously I only want to initialise County when the page is
first displayed to the user - subsequent submits and redisplays should
leave County as-is.
dd
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org