001: package com.technoetic.xplanner.export;
002:
003: import com.lowagie.text.Chunk;
004: import com.lowagie.text.Document;
005: import com.lowagie.text.DocumentException;
006: import com.lowagie.text.Element;
007: import com.lowagie.text.Font;
008: import com.lowagie.text.PageSize;
009: import com.lowagie.text.Paragraph;
010: import com.lowagie.text.Phrase;
011: import com.lowagie.text.Rectangle;
012: import com.lowagie.text.pdf.PdfPTable;
013: import com.lowagie.text.pdf.PdfWriter;
014: import com.technoetic.xplanner.domain.Iteration;
015: import com.technoetic.xplanner.domain.Person;
016: import com.technoetic.xplanner.domain.Task;
017: import com.technoetic.xplanner.domain.UserStory;
018: import net.sf.hibernate.Session;
019: import org.apache.commons.lang.StringUtils;
020:
021: import javax.servlet.http.HttpServletResponse;
022: import java.io.ByteArrayOutputStream;
023: import java.io.FileOutputStream;
024: import java.io.OutputStream;
025: import java.util.ArrayList;
026: import java.util.Collection;
027: import java.util.Iterator;
028:
029: public class PdfExporter implements Exporter {
030: public static final int SCALE_FACTOR = 2;
031: public static final Font NORMAL_TEXT_FONT = new Font(
032: Font.HELVETICA, 14 * SCALE_FACTOR, Font.NORMAL);
033: public static final Font BOLD_TEXT_FONT = new Font(Font.HELVETICA,
034: 14 * SCALE_FACTOR, Font.BOLD);
035: public static final Font TITLE_FONT = new Font(Font.HELVETICA,
036: 24 * SCALE_FACTOR, Font.BOLD);
037:
038: public void initializeHeaders(HttpServletResponse response) {
039: response.setHeader("Content-type", "application/pdf");
040: response.setHeader("Content-disposition",
041: "inline; filename=export.pdf");
042: }
043:
044: public byte[] export(Session session, Object object)
045: throws ExportException {
046: ByteArrayOutputStream output = null;
047: try {
048: output = new ByteArrayOutputStream();
049: exportToPdf(object, output);
050: return output.toByteArray();
051: } catch (DocumentException e) {
052: throw new ExportException(e);
053: } finally {
054: if (output != null) {
055: output.reset();
056: }
057: }
058: }
059:
060: public void exportToPdf(Object object, OutputStream output)
061: throws DocumentException, ExportException {
062:
063: PdfWriter docWriter = null;
064:
065: Rectangle pageRectangle = PageSize.LETTER.rotate();
066: Document document = new Document(pageRectangle, 10, 10,
067: 22 * SCALE_FACTOR, 10);
068: try {
069: docWriter = PdfWriter.getInstance(document, output);
070: if (object instanceof Iteration) {
071: write((Iteration) object, document, pageRectangle,
072: docWriter);
073: } else if (object instanceof UserStory) {
074: write((UserStory) object, document, pageRectangle,
075: docWriter);
076: } else if (object instanceof Task) {
077: write((Task) object, document, pageRectangle, docWriter);
078: }
079: } finally {
080: if (document.isOpen())
081: document.close();
082: if (docWriter != null)
083: docWriter.close();
084: }
085: }
086:
087: private void write(Iteration iteration, Document document,
088: Rectangle pageRectangle, PdfWriter docWriter)
089: throws DocumentException {
090: for (Iterator iterator = iteration.getUserStories().iterator(); iterator
091: .hasNext();) {
092: UserStory userStory = (UserStory) iterator.next();
093: write(userStory, document, pageRectangle, docWriter);
094: }
095: }
096:
097: private void write(UserStory story, Document document,
098: Rectangle pageRectangle, PdfWriter docWriter)
099: throws DocumentException {
100:
101: Person customer = story.getCustomer();
102: String customerName = "";
103: if (customer != null)
104: customerName = customer.getName();
105: writeCard(document, pageRectangle, docWriter, story.getName(),
106: story.getDescription(), new Field[] {
107: new Field("Customer", customerName),
108: new Field("Estimate", Double.toString(story
109: .getEstimatedHours())) }, null);
110: Collection tasks = story.getTasks();
111: for (Iterator it = tasks.iterator(); it.hasNext();) {
112: Task task = (Task) it.next();
113: write(task, document, pageRectangle, docWriter);
114: }
115: }
116:
117: private void write(Task task, Document document,
118: Rectangle pageRectangle, PdfWriter docWriter)
119: throws DocumentException {
120:
121: writeCard(document, pageRectangle, docWriter, task.getName(),
122: task.getDescription(), new Field[] {
123: new Field("Acceptor", ""),
124: new Field("Estimate", Double.toString(task
125: .getEstimatedHours())) }, task
126: .getStory().getName());
127: }
128:
129: private void writeCard(Document document, Rectangle pageRectangle,
130: PdfWriter docWriter, String title, String description,
131: Field[] fields, String containerTitle)
132: throws DocumentException {
133: document.resetHeader();
134:
135: // Phrase titlePhrase = new Phrase(title, new Font(Font.HELVETICA, 24 * SCALE_FACTOR, Font.BOLD));
136: // HeaderFooter header = new HeaderFooter(titlePhrase, false);
137: // document.setHeader(header);
138:
139: if (!document.isOpen())
140: document.open();
141:
142: document.newPage();
143:
144: PdfPTable headerTable = newTable(pageRectangle, 1);
145: if (containerTitle != null) {
146: headerTable.getDefaultCell().setPaddingBottom(-5);
147: headerTable.addCell(new Paragraph(containerTitle, new Font(
148: Font.HELVETICA, 6 * SCALE_FACTOR, Font.BOLD)));
149: }
150: headerTable.getDefaultCell().setBorderWidth(2);
151: headerTable.getDefaultCell().setBorder(Rectangle.BOTTOM);
152: headerTable.getDefaultCell().setPaddingBottom(15);
153: headerTable.addCell(new Paragraph(title, TITLE_FONT));
154: headerTable.getDefaultCell().setBorderWidth(0);
155: headerTable.getDefaultCell().setPaddingBottom(0);
156: headerTable.addCell(new Paragraph(StringUtils
157: .defaultString(description), NORMAL_TEXT_FONT));
158: headerTable.writeSelectedRows(0, -1, 10,
159: pageRectangle.height(), docWriter.getDirectContent());
160:
161: PdfPTable table = newTable(pageRectangle, 2);
162:
163: for (int i = 0; i < fields.length; i++) {
164: addFieldCell(table, fields[i]);
165: }
166: table.writeSelectedRows(0, -1, 10f,
167: 10f + table.getRowHeight(0), docWriter
168: .getDirectContent());
169: }
170:
171: private PdfPTable newTable(Rectangle pageRectangle, int columns) {
172: PdfPTable table = new PdfPTable(columns);
173: table.getDefaultCell().setBorderWidth(0);
174: table.setTotalWidth(pageRectangle.width() - 20);
175: return table;
176: }
177:
178: class Field {
179: private String title;
180: private String value;
181:
182: public Field(String title, String value) {
183: this .title = StringUtils.defaultString(title);
184: this .value = StringUtils.defaultString(value);
185: }
186:
187: public String getTitle() {
188: return title;
189: }
190:
191: public String getValue() {
192: return value;
193: }
194: }
195:
196: private void addFieldCell(PdfPTable table, Field field) {
197: Phrase cell = new Phrase(new Chunk(
198: "" + field.getTitle() + ": ", BOLD_TEXT_FONT));
199: cell.add(new Chunk(field.getValue(), NORMAL_TEXT_FONT));
200: table.getDefaultCell().setHorizontalAlignment(
201: Element.ALIGN_LEFT);
202: table.addCell(cell);
203: }
204:
205: public static void main(String[] args) throws Exception {
206: FileOutputStream stream = new FileOutputStream(
207: "XPlannerStories.pdf");
208: PdfExporter exporter = new PdfExporter();
209: Iteration iteration = new Iteration();
210: ArrayList stories = new ArrayList();
211:
212: ArrayList tasks = new ArrayList();
213: tasks.add(newTask("Task 1", "Description of Task 1", 2.0));
214: tasks.add(newTask("Task 2", "Description of Task 2", 3.0));
215: stories.add(newStory("Story 1", new Person(), 1.0, tasks));
216: iteration.setUserStories(stories);
217: exporter.exportToPdf(iteration, stream);
218: stream.close();
219:
220: }
221:
222: private static UserStory newStory(String name, Person customer,
223: double estimatedHours, Collection tasks) {
224: UserStory story = new UserStory();
225: story.setName(name);
226: story.setCustomer(customer);
227: story.setEstimatedHours(estimatedHours);
228: story.setTasks(tasks);
229: return story;
230: }
231:
232: private static Task newTask(String name, String description,
233: double estimatedHours) {
234: Task task = new Task();
235: task.setName(name);
236: task.setDescription(description);
237: task.setEstimatedHours(estimatedHours);
238: return task;
239: }
240: }
|