Search code examples
filedynamicdownloadtapestrygenerated

Tapestry how to serve a dynamically generated XML file?


I am having problems related to Tapestry on my final year project (Maven + Hibernate + Spring + Tapestry). I hope somebody could help on it. I generate an XML file (its content is my MySql DB data in a custom format I created) on my service layer (I tried it and it is propperly generated: it is working). I tested it from my Junit tests. The problem is that I am unable to get it working from view layer, using Tapestry.

I tried this but unsuccessfully I think that it is because file does not exist already: it is dinamically generated when user clicks on "Download XML" link.

Here you are my source code (user clicks on a link which points to this page). POJO for the page (xmlService.exportXml is the method from my service layer which creates the XML file):

public class DownloadAll {
    @Component
    private Form xmlDownloadForm;

    @Property
    private File xmlFile;

    @Property
    @SessionState(create=false)
    private UserSession userSession;

    @Inject
    private XmlService xmlService;

    public StreamResponse onSubmit() {
      xmlFile = xmlService.exportXml(userSession.getUserProfileId());
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
      InputStream input = DownloadAll.class.getResourceAsStream("exportedData-"
          + userSession.getLoginName() + timeStamp + ".xml");
      return new XMLAttachment(input);
    }
}

And this is the page template:

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
    t:type="Layout" t:pageTitle="title"
    xmlns:p="tapestry:parameter"
    t:menuExplanation="menuExplanation">
      <form t:type="Form" t:id="xmlDownloadForm">
    <input type="submit" value="${message:download}"/>
  </form>
</html>

Does anybody know how to make it working? Thanks and regards.

Edit: File is generated (I can see it in the folder) when I submit the form but file is not served. I get this error instead:

org.apache.tapestry5.runtime.ComponentEventException Class es.udc.decompras.web.pages.xml.util.XMLAttachment has been transformed and may not be directly instantiated.

XMLAttachment is the same than JPEGAttachment.java from this link Here you are the source code:

public class XMLAttachment extends AttachmentStreamResponse {

    public XMLAttachment(InputStream is, String args) {
      super(is, args);
      this.contentType = "application/xml";
      this.extension = "xml";
    }

    public XMLAttachment(InputStream is) {
      super(is);
      this.contentType = "application/xml";
      this.extension = "xml";
    }
}

Solution

  • Only pages can be in your "pages" package. Move XMLAttachment class to any package not managed by tapestry (eg NOT base, components or pages).

    Tapestry performs byte code magic on the managed packages and uses a special classloader to load them which is not compatible for utility classes etc.