- Revision
- 634
- Author
- mauro
- Date
- 2008-04-20 09:34:51 -0500 (Sun, 20 Apr 2008)
Log Message
WAFFLE-73: Added ExportView. Updated freemarker-example to use it.
Modified Paths
- trunk/examples/freemarker-example/src/main/java/org/codehaus/waffle/example/freemarker/controller/PersonController.java
- trunk/examples/freemarker-example/src/main/webapp/people/manage.ftl
- trunk/waffle-core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java
- trunk/waffle-core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java
Added Paths
Diff
Modified: trunk/examples/freemarker-example/src/main/java/org/codehaus/waffle/example/freemarker/controller/PersonController.java (633 => 634)
--- trunk/examples/freemarker-example/src/main/java/org/codehaus/waffle/example/freemarker/controller/PersonController.java 2008-04-20 12:40:22 UTC (rev 633) +++ trunk/examples/freemarker-example/src/main/java/org/codehaus/waffle/example/freemarker/controller/PersonController.java 2008-04-20 14:34:51 UTC (rev 634) @@ -9,6 +9,8 @@ import org.codehaus.waffle.example.freemarker.model.Person; import org.codehaus.waffle.example.freemarker.persister.PersistablePerson; import org.codehaus.waffle.example.freemarker.persister.PersonPersister; +import org.codehaus.waffle.view.ExportView; +import org.codehaus.waffle.view.View; @SuppressWarnings("serial") public class PersonController implements Serializable { @@ -40,6 +42,18 @@ } return selected; } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + public List<String> getSkills() { + return skills; + } public void remove(Long personId) { persister.delete(personId); @@ -65,16 +79,20 @@ person = null; } - public Person getPerson() { - return person; + public View export() { + StringBuffer sb = new StringBuffer(); + sb.append("Id,First Name,Last Name,Date of Birth\n"); + for ( Person person : getSelectedPeople() ){ + sb.append(person.getId()); + sb.append(","); + sb.append(person.getFirstName()); + sb.append(","); + sb.append(person.getLastName()); + sb.append(","); + sb.append(person.getDateOfBirth()); + sb.append("\n"); + } + return new ExportView(this, "text/csv", sb.toString().getBytes(), "export.csv"); } - public void setPerson(Person person) { - this.person = person; - } - - public List<String> getSkills() { - return skills; - } - }
Modified: trunk/examples/freemarker-example/src/main/webapp/people/manage.ftl (633 => 634)
--- trunk/examples/freemarker-example/src/main/webapp/people/manage.ftl 2008-04-20 12:40:22 UTC (rev 633) +++ trunk/examples/freemarker-example/src/main/webapp/people/manage.ftl 2008-04-20 14:34:51 UTC (rev 634) @@ -34,7 +34,7 @@ </#list> </table> - <a href="" <a href="" Selected</a> + <a href="" <a href="" Selected</a> <div id="showArea"> Selected people are:
Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java (633 => 634)
--- trunk/waffle-core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java 2008-04-20 12:40:22 UTC (rev 633) +++ trunk/waffle-core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java 2008-04-20 14:34:51 UTC (rev 634) @@ -10,23 +10,28 @@ *****************************************************************************/ package org.codehaus.waffle.view; +import static java.text.MessageFormat.format; + +import java.io.IOException; + +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; -import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codehaus.waffle.monitor.ViewMonitor; -import java.io.IOException; - /** - * The ViewDispatcher handles redirecting/forwarding to the view + * The ViewDispatcher handles redirecting/forwarding/exporting to the view * * @author Michael Ward * @author Paulo Silveira * @author Mauro Talevi */ public class DefaultViewDispatcher implements ViewDispatcher { + static final String ATTACHMENT_FILENAME = "attachment; filename={0}"; + static final String CONTENT_DISPOSITION_HEADER = "content-disposition"; + static final String LOCATION_HEADER = "Location"; private final ViewResolver viewResolver; private final ViewMonitor viewMonitor; @@ -36,15 +41,19 @@ } // todo may need to handle ... http://java.sun.com/products/servlet/Filters.html for Character Encoding from request - public void dispatch(HttpServletRequest request, - HttpServletResponse response, - View view) throws IOException, ServletException { + public void dispatch(HttpServletRequest request, HttpServletResponse response, View view) throws IOException, + ServletException { String path = viewResolver.resolve(view); - if (view instanceof RedirectView) { + if (view instanceof ExportView) { + ExportView exportView = (ExportView) view; + response.setContentType(exportView.getContentType()); + response.setHeader(CONTENT_DISPOSITION_HEADER, format(ATTACHMENT_FILENAME, exportView.getFilename())); + response.getOutputStream().write(exportView.getContent()); + } else if (view instanceof RedirectView) { RedirectView redirectView = (RedirectView) view; response.setStatus(redirectView.getStatusCode()); - response.setHeader("Location", path); + response.setHeader(LOCATION_HEADER, path); viewMonitor.viewRedirected(redirectView); } else if (view instanceof ResponderView) { ResponderView responderView = (ResponderView) view;
Added: trunk/waffle-core/src/main/java/org/codehaus/waffle/view/ExportView.java (0 => 634)
--- trunk/waffle-core/src/main/java/org/codehaus/waffle/view/ExportView.java (rev 0) +++ trunk/waffle-core/src/main/java/org/codehaus/waffle/view/ExportView.java 2008-04-20 14:34:51 UTC (rev 634) @@ -0,0 +1,42 @@ +/***************************************************************************** + * Copyright (c) 2005-2008 Michael Ward * + * All rights reserved. * + * ------------------------------------------------------------------------- * + * The software in this package is published under the terms of the BSD * + * style license a copy of which has been included with this distribution in * + * the LICENSE.txt file. * + * * + * Original code by: Mauro Talevi * + *****************************************************************************/ +package org.codehaus.waffle.view; + +/** + * Indicates that the view should contain export data. + * + * @author Mauro Talevi + */ +public class ExportView extends View { + private final String contentType; + private final byte[] content; + private final String filename; + + public ExportView(Object fromController, String contentType, byte[] content, String filename) { + super(null, fromController); + this.contentType = contentType; + this.content = content; + this.filename = filename; + } + + public String getContentType() { + return contentType; + } + + public byte[] getContent() { + return content; + } + + public String getFilename() { + return filename; + } + +}
Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java (633 => 634)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java 2008-04-20 12:40:22 UTC (rev 633) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java 2008-04-20 14:34:51 UTC (rev 634) @@ -1,9 +1,16 @@ package org.codehaus.waffle.view; +import static java.text.MessageFormat.format; +import static org.codehaus.waffle.view.DefaultViewDispatcher.ATTACHMENT_FILENAME; +import static org.codehaus.waffle.view.DefaultViewDispatcher.CONTENT_DISPOSITION_HEADER; +import static org.codehaus.waffle.view.DefaultViewDispatcher.LOCATION_HEADER; +import static org.junit.Assert.assertTrue; + import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -12,7 +19,6 @@ import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JMock; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,39 +34,44 @@ private final HttpServletRequest mockRequest = mockRequest(); private final HttpServletResponse mockResponse = mockResponse(); - class SomeResponderView extends ResponderView { + @Test + public void canDispatchExportView() throws IOException, ServletException { + final String contentType = "text/csv"; + final String content = "1,2,3"; + final String filename = "export.csv"; + ExportView view = new ExportView(null, contentType, content.getBytes(), filename); + ViewResolver viewResolver = mockViewResolver(view, PATH); - private boolean responded = false; + mockery.checking(new Expectations() {{ + one(mockResponse).setContentType(contentType); + one(mockResponse).setHeader(CONTENT_DISPOSITION_HEADER, format(ATTACHMENT_FILENAME,filename)); + one(mockResponse).getOutputStream(); + will(returnValue(mockOutputStream())); + }}); - @Override - public void respond(ServletRequest req, HttpServletResponse resp) throws IOException { - responded = true; - } - - public boolean isResponded() { - return responded; - } + DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(viewResolver, new SilentMonitor()); + viewDispatcher.dispatch(mockRequest, mockResponse, view); } @Test - public void dispatchShouldCallRespondIfViewIsOfTypeResponder() throws IOException, ServletException { + public void canDispatchViewOfTypeResponder() throws IOException, ServletException { SomeResponderView view = new SomeResponderView(); ViewResolver viewResolver = mockViewResolver(view, PATH); DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(viewResolver, new SilentMonitor()); viewDispatcher.dispatch(mockRequest, mockResponse, view); - Assert.assertTrue(view.isResponded()); + assertTrue(view.isResponded()); } - + @Test - public void dispatchShouldHandleRedirectView() throws IOException, ServletException { + public void canDispatchRedirectView() throws IOException, ServletException { RedirectView redirectView = new RedirectView(PATH, null); ViewResolver viewResolver = mockViewResolver(redirectView, PATH); mockery.checking(new Expectations() {{ one(mockResponse).setStatus(HttpServletResponse.SC_SEE_OTHER); - one(mockResponse).setHeader("Location", PATH); + one(mockResponse).setHeader(LOCATION_HEADER, PATH); }}); DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(viewResolver, new SilentMonitor()); @@ -68,12 +79,11 @@ } @Test - public void dispatchShouldHandleStandardView() throws IOException, ServletException { + public void canDispatchStandardView() throws IOException, ServletException { View view = new View(PATH, null); ViewResolver viewResolver = mockViewResolver(view, PATH); final RequestDispatcher requestDispatcher = mockery.mock(RequestDispatcher.class); - mockery.checking(new Expectations() {{ one(mockRequest).getRequestDispatcher(PATH); will(returnValue(requestDispatcher)); @@ -86,22 +96,46 @@ private ViewResolver mockViewResolver(final View view, final String path) { final ViewResolver viewResolver = mockery.mock(ViewResolver.class); - Expectations expectations = new Expectations() { + mockery.checking(new Expectations() { { allowing(viewResolver).resolve(view); will(returnValue(path)); } - }; - mockery.checking(expectations); + }); return viewResolver; } + private HttpServletRequest mockRequest() { + return mockery.mock(HttpServletRequest.class); + } + private HttpServletResponse mockResponse() { return mockery.mock(HttpServletResponse.class); } - private HttpServletRequest mockRequest() { - return mockery.mock(HttpServletRequest.class); + private ServletOutputStream mockOutputStream() throws IOException { + return new ServletOutputStream(){ + + @Override + public void write(int b) throws IOException { + } + + }; } + class SomeResponderView extends ResponderView { + + private boolean responded = false; + + @Override + public void respond(ServletRequest req, HttpServletResponse resp) throws IOException { + responded = true; + } + + public boolean isResponded() { + return responded; + } + } + + }
Added: trunk/waffle-core/src/test/java/org/codehaus/waffle/view/ExportViewTest.java (0 => 634)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/view/ExportViewTest.java (rev 0) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/view/ExportViewTest.java 2008-04-20 14:34:51 UTC (rev 634) @@ -0,0 +1,24 @@ +package org.codehaus.waffle.view; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * + * @author Mauro Talevi + */ +public class ExportViewTest { + + @Test + public void canCreateExportView() { + String content = "1,2,3"; + String contentType = "text/csv"; + String filename = "export.csv"; + ExportView view = new ExportView(null, contentType, content.getBytes(), filename); + assertEquals(content, new String(view.getContent())); + assertEquals(contentType, view.getContentType()); + assertEquals(filename, view.getFilename()); + } + +}
To unsubscribe from this list please visit:
