1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.cms.core.wiki.base;
17
18 import java.awt.Color;
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Properties;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.seasar.tuigwaa.cms.core.CmsConstants;
33 import org.seasar.tuigwaa.cms.core.CmsRequest;
34 import org.seasar.tuigwaa.cms.core.CmsResponse;
35 import org.seasar.tuigwaa.cms.core.Resource;
36 import org.seasar.tuigwaa.cms.core.pdf.PdfCmsPageEvents;
37 import org.seasar.tuigwaa.cms.core.pdf.PdfUtils;
38 import org.seasar.tuigwaa.cms.core.wiki.WikiContext;
39 import org.seasar.tuigwaa.cms.core.wiki.engine.Node;
40 import org.seasar.tuigwaa.cms.core.wiki.engine.SimpleNode;
41 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiAlias;
42 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiAlign;
43 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiAnnotation;
44 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiAnyOther;
45 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiArgs;
46 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiBlockPlugin;
47 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiCSVTable;
48 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiDefineList;
49 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiDefinedWord;
50 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiDeleteline;
51 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiErrors;
52 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiExcerpt;
53 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiExplanationWord;
54 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiFloatAlign;
55 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiGenerateTree;
56 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiHeading;
57 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiHorizontalline;
58 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiInlinePlugin;
59 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiInterwiki;
60 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiLetters;
61 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiLink;
62 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiList;
63 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiListMember;
64 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiPagename;
65 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiParagraph;
66 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiParserVisitor;
67 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiPreshaped;
68 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiSkipToNewline;
69 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiStrongItalic;
70 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiSyntaxError;
71 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiTable;
72 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiTablecolumn;
73 import org.seasar.tuigwaa.cms.core.wiki.engine.WikiTablemember;
74 import org.seasar.tuigwaa.plugin.Plugin;
75 import org.seasar.tuigwaa.plugin.PluginException;
76 import org.seasar.tuigwaa.plugin.PluginRequest;
77 import org.seasar.tuigwaa.system.Constants;
78 import org.seasar.tuigwaa.system.TgwSecurityException;
79
80 import com.isenshi.util.extlib.CJKSplitCharacter;
81 import com.lowagie.text.Anchor;
82 import com.lowagie.text.Annotation;
83 import com.lowagie.text.BadElementException;
84 import com.lowagie.text.Cell;
85 import com.lowagie.text.Chapter;
86 import com.lowagie.text.Chunk;
87 import com.lowagie.text.DocWriter;
88 import com.lowagie.text.Document;
89 import com.lowagie.text.DocumentException;
90 import com.lowagie.text.Element;
91 import com.lowagie.text.ElementTags;
92 import com.lowagie.text.Font;
93 import com.lowagie.text.FontFactory;
94 import com.lowagie.text.Image;
95 import com.lowagie.text.ListItem;
96 import com.lowagie.text.Paragraph;
97 import com.lowagie.text.Phrase;
98 import com.lowagie.text.Rectangle;
99 import com.lowagie.text.Section;
100 import com.lowagie.text.SplitCharacter;
101 import com.lowagie.text.Table;
102 import com.lowagie.text.markup.MarkupParser;
103 import com.lowagie.text.markup.MarkupTags;
104 import com.lowagie.text.pdf.PdfPTable;
105 import com.lowagie.text.pdf.PdfPageEvent;
106 import com.lowagie.text.pdf.PdfWriter;
107 import com.lowagie.text.rtf.RtfWriter2;
108
109 /***
110 * Using parsed wiki node tree, generates PDF or RTF documents. This class
111 * totally depends on iText ver. 1.3.
112 *
113 * KNOWN ISSUES : (2005/11) 1. Cannot specify Japanese character in annotation
114 * contents. Even if setting Japanese font, the result will not contain Japanese
115 * Sentence.
116 *
117 * @author someda
118 */
119 public class PDFWikiVisitor implements WikiParserVisitor {
120
121 private static final float LIST_INDENT = 10;
122
123 private static final float PAGEMARGIN_TOP = 50;
124
125 private static final float PAGEMARGIN_RIGHT = 50;
126
127 private static final float PAGEMARGIN_BOTTOM = 50;
128
129 private static final float PAGEMARGIN_LEFT = 50;
130
131 private static final float TABLE_PADDING = 3f;
132
133 private static final float TABLE_BORDERWIDTH = 0.5f;
134
135 private static final float TABLE_WIDTH = 100f;
136
137
138
139 private static final int SECTION_NUMBEROFDEPTH = 3;
140
141 private static final float SECTION_INDENT = 10;
142
143 private static final String CREATER_APPLICATION = "WebUDA Tuigwaa";
144
145 private Document doc_;
146
147 private DocWriter writer_;
148
149 private ByteArrayOutputStream baos_ = new ByteArrayOutputStream();
150
151 private List chapterList = null;
152
153 private Section currentSection_ = null;
154
155 private Section lastSection_ = null;
156
157 private Map pushedMap_ = null;
158
159 private CmsRequest request_;
160
161 private CmsResponse response_;
162
163 private WikiConfiguration config_;
164
165 private WikiContext ctx;
166
167 private Font defaultFont_;
168
169 private float paragraphSpacing_;
170
171 private Log log_ = LogFactory.getLog(getClass());
172
173 private SplitCharacter split = new CJKSplitCharacter();
174
175 public PDFWikiVisitor(CmsRequest request, CmsResponse response,
176 WikiConfiguration config) {
177 this.request_ = request;
178 this.response_ = response;
179 this.config_ = config;
180 this.ctx = config.getWikiContext();
181
182 try {
183 init();
184 } catch (DocumentException de) {
185 log_
186 .error("failed to initialize the document : "
187 + de.getMessage());
188 throw new RuntimeException(de);
189 }
190 }
191
192 private void init() throws DocumentException {
193
194 Resource resource = request_.getPage().getResource();
195 String style = resource.getProperty(CmsConstants.PROPERTY_PDFSTYLE);
196 if (style == null)
197 style = PdfUtils.DEFAULT_PDF_PAGESTYLE;
198
199 Rectangle rec = PdfUtils.getRectangle(style);
200 doc_ = new Document(rec, PAGEMARGIN_LEFT, PAGEMARGIN_RIGHT,
201 PAGEMARGIN_TOP, PAGEMARGIN_BOTTOM);
202
203 defaultFont_ = PdfUtils.FONT_JA_MINCHO;
204 paragraphSpacing_ = defaultFont_.size();
205
206 if (request_.isPDFRequest()) {
207 writer_ = PdfWriter.getInstance(doc_, baos_);
208 String pagePath = resource.getPath();
209 PdfPageEvent event = new PdfCmsPageEvents(pagePath, defaultFont_,
210 style);
211 ((PdfWriter) writer_).setPageEvent(event);
212 } else if (request_.isRTFRequest()) {
213 writer_ = RtfWriter2.getInstance(doc_, baos_);
214 } else {
215 throw new IllegalStateException(
216 "request type should be PDF or RTF.");
217 }
218
219 doc_.addAuthor(resource.getModificationUser());
220 doc_.addCreationDate();
221 doc_.addSubject(request_.getPage().getResource().getPath());
222 doc_.addCreator(CREATER_APPLICATION);
223
224 doc_.open();
225 }
226
227 public Object visit(SimpleNode node, Object data) {
228 return null;
229 }
230
231 public Object visit(WikiSyntaxError node, Object data) {
232 return getError(node.letter);
233 }
234
235 public Object visit(WikiSkipToNewline node, Object data) {
236 Chunk c = new Chunk(node.letter, defaultFont_);
237 c.setSplitCharacter(split);
238 return c;
239 }
240
241 /***
242 * Main method, all other method in this class should not be called.
243 */
244 public Object visit(WikiGenerateTree node, Object data) {
245
246 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
247 Object o = node.jjtGetChild(i).jjtAccept(this, data);
248 addDocument(o, node.jjtGetChild(i));
249 }
250
251 /***
252 * NOTE: iText Document#add method writes the contents on-the-fly to
253 * OutputStream, thus, using chapterList to avoid null contents
254 * appeared.
255 */
256 if (chapterList != null) {
257 int n = 0;
258 for (Iterator i = chapterList.iterator(); i.hasNext();) {
259 Element e = (Element) i.next();
260 List list = null;
261 if (pushedMap_ != null)
262 list = (List) pushedMap_.get(new Integer(n));
263
264 try {
265 doc_.add(e);
266 if (list != null) {
267 for (Iterator j = list.iterator(); j.hasNext();) {
268 Element elm = (Element) j.next();
269 doc_.add(elm);
270 }
271 }
272 } catch (DocumentException de) {
273 de.printStackTrace();
274 }
275 n++;
276 }
277 }
278
279 doc_.close();
280 byte[] b = null;
281 try {
282 b = baos_.toByteArray();
283 baos_.close();
284 } catch (IOException ioe) {
285 ioe.printStackTrace();
286 }
287 return b;
288 }
289
290 private void addDocument(Object obj, Node node) {
291
292 try {
293 if (currentSection_ != null && !(node instanceof WikiHeading)) {
294 if (obj != null) {
295 try {
296 currentSection_.add(obj);
297 } catch (ClassCastException cce) {
298 log_.error("couldn't add " + obj
299 + " to current section caused by "
300 + cce.getMessage());
301 }
302 }
303 } else {
304 if (obj != null) {
305 try {
306 doc_.add((Element) obj);
307 } catch (ClassCastException cce) {
308 log_.error("couldn't add " + obj
309 + " to document caused by " + cce.getMessage());
310 }
311 }
312 }
313 } catch (DocumentException de) {
314 de.printStackTrace();
315 }
316 }
317
318 private void pushObject(Element e) {
319 if (pushedMap_ == null)
320 pushedMap_ = new HashMap();
321
322 if (currentSection_ == null) {
323 try {
324 doc_.add(e);
325 } catch (DocumentException de) {
326 log_.error("failed to add element " + de.getMessage());
327 }
328 } else {
329 List list;
330 Integer n = new Integer(chapterList.size() - 1);
331 if ((list = (List) pushedMap_.get(n)) == null) {
332 list = new ArrayList();
333 pushedMap_.put(n, list);
334 }
335 list.add(e);
336 }
337 }
338
339 public Object visit(WikiParagraph node, Object data) {
340 Paragraph p = new Paragraph();
341 p.setLeading(20f);
342 p.setFirstLineIndent(defaultFont_.size());
343 p.setSpacingBefore(paragraphSpacing_);
344 p.setSpacingAfter(paragraphSpacing_);
345 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
346 Object o = node.jjtGetChild(i).jjtAccept(this, data);
347 if (o != null)
348 p.add(o);
349 }
350 return p;
351 }
352
353 public Object visit(WikiExcerpt node, Object data) {
354
355 Properties props = PdfUtils.getDefaultfontProperties(defaultFont_);
356 props.setProperty(ElementTags.STYLE, MarkupTags.CSS_ITALIC);
357
358 Paragraph p = new Paragraph(props);
359 p.setIndentationLeft(20 * node.level);
360 p.setSpacingAfter(paragraphSpacing_);
361 p.setSpacingBefore(paragraphSpacing_);
362 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
363
364 if (node.jjtGetChild(i) instanceof WikiParagraph) {
365 WikiParagraph c = (WikiParagraph) node.jjtGetChild(i);
366 for (int j = 0; j < c.jjtGetNumChildren(); j++) {
367 Object o = c.jjtGetChild(j).jjtAccept(this, data);
368 if (o != null)
369 p.add(o);
370 }
371
372 } else {
373 Object o = node.jjtGetChild(i).jjtAccept(this, data);
374 if (o != null)
375 p.add(o);
376 }
377 }
378 return p;
379 }
380
381 public Object visit(WikiList node, Object data) {
382
383 int curtype = 0;
384 int curlevel = 0;
385 int pretype = 0;
386 int prelevel = 0;
387 com.lowagie.text.List[] state = new com.lowagie.text.List[3];
388
389 Element e = new Paragraph();
390 com.lowagie.text.List curlist = null;
391 com.lowagie.text.List parentlist = null;
392
393 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
394
395 if (node.jjtGetChild(i) instanceof WikiListMember) {
396 WikiListMember child = (WikiListMember) node.jjtGetChild(i);
397
398 curtype = child.type;
399 curlevel = child.level;
400
401
402 if (curlevel > prelevel) {
403 parentlist = curlist;
404
405 curlist = startList(curtype);
406 state[curlevel - 1] = curlist;
407
408 if (parentlist != null) {
409 parentlist.add(curlist);
410 } else {
411 parentlist = curlist;
412 ((Paragraph) e).add(curlist);
413 }
414 }
415
416
417 if (curlevel < prelevel) {
418
419 if (state[curlevel - 1] != null
420 && state[curlevel - 1].size() > 0
421 && isSametype(state[curlevel - 1], curtype)) {
422 curlist = state[curlevel - 1];
423 } else {
424 curlist = startList(curtype);
425 for (int j = curlevel - 2; j >= 0; j--) {
426 if (state[j] != null && state[j].size() > 0) {
427 parentlist = state[j];
428 parentlist.add(curlist);
429 break;
430 }
431 }
432 if (curlevel == 1) {
433 ((Paragraph) e).add(curlist);
434 }
435 }
436 }
437
438
439 if (curlevel == prelevel && curtype != pretype) {
440 curlist = startList(curtype);
441
442 if (curlevel == 1) {
443 ((Paragraph) e).add(curlist);
444 } else {
445 parentlist.add(curlist);
446 }
447 }
448
449
450 if (curlevel != prelevel || curtype != pretype) {
451 pretype = curtype;
452 prelevel = curlevel;
453 }
454 curlist.add(child.jjtAccept(this, data));
455 }
456 }
457 return e;
458 }
459
460 private com.lowagie.text.List startList(int type) {
461 com.lowagie.text.List e = null;
462 if (type == WikiHelper.LIST_TYPE_NORMAL) {
463 e = new com.lowagie.text.List(false, LIST_INDENT);
464 } else if (type == WikiHelper.LIST_TYPE_NUMERICAL) {
465 e = new com.lowagie.text.List(true, LIST_INDENT);
466 }
467 return e;
468 }
469
470 private boolean isSametype(com.lowagie.text.List list, int type) {
471 return (!list.isNumbered() && type == WikiHelper.LIST_TYPE_NORMAL)
472 || (list.isNumbered() && type == WikiHelper.LIST_TYPE_NUMERICAL);
473 }
474
475 public Object visit(WikiListMember node, Object data) {
476 ListItem e = new ListItem();
477 e.setIndentationLeft(LIST_INDENT);
478 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
479 e.add(node.jjtGetChild(i).jjtAccept(this, data));
480 }
481 return e;
482 }
483
484 public Object visit(WikiDefineList node, Object data) {
485 Paragraph p = new Paragraph();
486 p.setSpacingBefore(5f);
487 p.setSpacingAfter(5f);
488 p.setIndentationLeft(5f);
489 p.add(Chunk.NEWLINE);
490 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
491 Object o = node.jjtGetChild(i).jjtAccept(this, data);
492 if (o != null)
493 p.add(o);
494 }
495 return p;
496 }
497
498 public Object visit(WikiDefinedWord node, Object data) {
499
500 Phrase p = null;
501 if (node.jjtGetNumChildren() > 0) {
502 Properties props = PdfUtils.getDefaultfontProperties(defaultFont_);
503 props.setProperty(ElementTags.STYLE, MarkupTags.CSS_BOLD);
504 p = new Phrase(props);
505 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
506 Object o = node.jjtGetChild(i).jjtAccept(this, data);
507 if (o != null)
508 p.add(o);
509 }
510 p.add(Chunk.NEWLINE);
511 }
512 return p;
513 }
514
515 public Object visit(WikiExplanationWord node, Object data) {
516 Paragraph p = new Paragraph();
517 p.setSpacingAfter(5f);
518 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
519
520 Node child = node.jjtGetChild(i);
521 if (child instanceof WikiParagraph) {
522 for (int j = 0; j < child.jjtGetNumChildren(); j++) {
523 Object o = child.jjtGetChild(j).jjtAccept(this, data);
524 if (o != null)
525 p.add(o);
526 }
527 } else {
528 Object o = node.jjtGetChild(i).jjtAccept(this, data);
529 if (o != null)
530 p.add(o);
531 }
532 }
533 p.add(Chunk.NEWLINE);
534 return p;
535 }
536
537 public Object visit(WikiPreshaped node, Object data) {
538
539 Table p = null;
540 try {
541 p = new Table(1);
542 p.setPadding(TABLE_PADDING);
543 p.setBorderWidth(TABLE_BORDERWIDTH);
544 p.setWidth(TABLE_WIDTH);
545 p.disableBorderSide(Rectangle.LEFT);
546 p.disableBorderSide(Rectangle.RIGHT);
547 p.endHeaders();
548 Cell c = new Cell();
549 c.disableBorderSide(Rectangle.LEFT);
550 c.disableBorderSide(Rectangle.RIGHT);
551
552 Paragraph ph = new Paragraph(PdfUtils
553 .getDefaultfontProperties(defaultFont_));
554
555 float indent = 0f;
556 if (currentSection_ != null) {
557 indent = (currentSection_.depth() - 1) * SECTION_INDENT;
558 }
559
560 if (node.jjtGetParent() instanceof Paragraph) {
561 indent += ((Paragraph) node.jjtGetParent()).indentationLeft();
562 }
563
564 if (indent > 0f)
565 ph.setIndentationLeft(indent);
566
567 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
568 ph.add(node.jjtGetChild(i).jjtAccept(this, data));
569 ph.add(Chunk.NEWLINE);
570 }
571 c.add(ph);
572 p.addCell(c);
573 } catch (BadElementException bee) {
574 bee.printStackTrace();
575 }
576 return p;
577 }
578
579 public Object visit(WikiTable node, Object data) {
580 return processTable(node, data);
581 }
582
583 private Object processTable(SimpleNode node, Object data) {
584
585 VisitorUtils.prepareWikiTable(node, data);
586 int prenum = 0;
587 Table t = null;
588
589 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
590
591 int colnum = node.jjtGetChild(i).jjtGetNumChildren();
592
593 if (node.jjtGetChild(i) instanceof WikiTablemember) {
594
595 if (colnum != prenum) {
596
597 if (t != null) {
598 addDocument(t, node);
599 }
600
601 try {
602 t = new Table(colnum);
603 t.setPadding(TABLE_PADDING);
604 t.setBorderWidth(TABLE_BORDERWIDTH);
605 t.setWidth(TABLE_WIDTH);
606 t.setCellsFitPage(true);
607 t.setOffset(10f);
608
609
610 } catch (BadElementException bee) {
611
612 bee.printStackTrace();
613 }
614 }
615 } else {
616 prenum = 0;
617 continue;
618 }
619 prenum = colnum;
620 node.jjtGetChild(i).jjtAccept(this, t);
621 }
622 return t;
623 }
624
625 public Object visit(WikiTablecolumn node, Object data) {
626
627 Cell cell = null;
628 if (!node.iscolspan && !node.isrowspan) {
629 cell = new Cell();
630 Properties props = (data instanceof Properties) ? (Properties) data
631 : PdfUtils.getDefaultfontProperties(defaultFont_);
632 props.setProperty(ElementTags.SIZE, "10.0");
633
634 if (node.align != null)
635 cell.setHorizontalAlignment(getAlign(node.align));
636
637 String bgcolor = null;
638 if ((bgcolor = (String) props.remove(ElementTags.BACKGROUNDCOLOR)) != null) {
639 cell.setBackgroundColor(MarkupParser.decodeColor(bgcolor));
640 }
641
642 if (node.bgcolor != null)
643 cell.setBackgroundColor(VisitorUtils.getColorByString(
644 node.bgcolor, false));
645
646 if (node.color != null) {
647 Color c = VisitorUtils.getColorByString(node.color, true);
648 if (c != null) {
649 props.setProperty(ElementTags.RED, String.valueOf(c
650 .getRed()));
651 props.setProperty(ElementTags.GREEN, String.valueOf(c
652 .getGreen()));
653 props.setProperty(ElementTags.BLUE, String.valueOf(c
654 .getBlue()));
655 }
656 }
657
658 if (node.size != null)
659 props.setProperty(ElementTags.SIZE, node.size);
660
661 if (node.colspannum > 0)
662 cell.setColspan(++node.colspannum);
663
664 if (node.rowspannum > 0) {
665 cell.setRowspan(++node.rowspannum);
666 }
667
668 try {
669 Phrase p = getChildPhrase(node, props, 0);
670 Paragraph ph = new Paragraph(p);
671
672 float indent = 0f;
673 if (currentSection_ != null) {
674 indent = (currentSection_.depth() - 1) * SECTION_INDENT;
675 }
676
677 if (indent > 0)
678 ph.setIndentationLeft(indent);
679
680 cell.addElement(ph);
681 } catch (BadElementException bee) {
682 bee.printStackTrace();
683 }
684 }
685 return cell;
686 }
687
688 public Object visit(WikiTablemember node, Object data) {
689
690 if (data instanceof Table) {
691 Table t = (Table) data;
692 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
693 Properties p = PdfUtils.getDefaultfontProperties(defaultFont_);
694 if (node.type == WikiHelper.TABLE_TYPE_HEADER) {
695 p.setProperty(ElementTags.STYLE, MarkupTags.CSS_BOLD);
696 p.setProperty(ElementTags.BACKGROUNDCOLOR, "#C0C0C0");
697 }
698
699 Object o = node.jjtGetChild(i).jjtAccept(this, p);
700 if (o != null) {
701 t.addCell((Cell) o);
702 }
703 }
704 }
705 return null;
706 }
707
708 public Object visit(WikiCSVTable node, Object data) {
709 return processTable(node, data);
710 }
711
712 public Object visit(WikiHeading node, Object data) {
713
714 Element e = null;
715 Paragraph title;
716
717 if (node.level == 1 || currentSection_ == null) {
718 title = new Paragraph(PdfUtils
719 .getChapterfontProperties(defaultFont_));
720 title.setLeading(20f);
721 title.setSpacingAfter(40f);
722 title.add(getChildPhrase(node, data, 0));
723 if (chapterList == null)
724 chapterList = new ArrayList();
725
726
727
728
729 e = new Chapter(title, chapterList.size() + 1);
730 currentSection_ = (Section) e;
731 chapterList.add(e);
732 } else {
733 title = new Paragraph(PdfUtils.getSectionfontProperties(
734 defaultFont_, node.level));
735 title.setLeading(20f);
736 title.add(getChildPhrase(node, data, 0));
737 Section sec = null;
738 if (node.level == 2) {
739 sec = ((Section) chapterList.get(chapterList.size() - 1))
740 .addSection(SECTION_INDENT, title,
741 SECTION_NUMBEROFDEPTH);
742 } else {
743 int currentDepth = currentSection_.depth();
744 if (currentDepth == SECTION_NUMBEROFDEPTH) {
745 sec = lastSection_.addSection(SECTION_INDENT, title,
746 SECTION_NUMBEROFDEPTH);
747 } else {
748 lastSection_ = currentSection_;
749 sec = currentSection_.addSection(SECTION_INDENT, title,
750 SECTION_NUMBEROFDEPTH);
751 }
752 }
753 if (sec != null)
754 currentSection_ = sec;
755 }
756 return null;
757 }
758
759 public Object visit(WikiAlign node, Object data) {
760 Paragraph p = new Paragraph();
761 String align = node.image.substring(0, node.image.length() - 1);
762 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
763 Object o = node.jjtGetChild(i).jjtAccept(this, data);
764 if (o != null)
765 p.add(o);
766 }
767 p.setAlignment(getAlign(align));
768 return p;
769 }
770
771 public Object visit(WikiFloatAlign node, Object data) {
772 Paragraph p = new Paragraph();
773 String align = node.image.substring(1, node.image.length() - 1);
774 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
775 Object o = node.jjtGetChild(i).jjtAccept(this, data);
776 if (o != null)
777 p.add(o);
778 }
779 p.setAlignment(getAlign(align));
780 return p;
781 }
782
783 public Object visit(WikiHorizontalline node, Object data) {
784
785
786
787 Chunk c = new Chunk("\u00a0");
788 c.setGenericTag(PdfCmsPageEvents.GENERICTAG_HORIZONTAL);
789 Paragraph p = new Paragraph(c);
790 return p;
791 }
792
793 public Object visit(WikiBlockPlugin node, Object data) {
794
795 String name = node.name;
796 boolean ispluginused = false;
797 Object obj = null;
798
799 PluginRequest prequest = VisitorUtils.createPluginRequest(node);
800 String childStr = getChildAsString(node,data,0);
801 if(childStr != null && !Constants.LINEBREAK_CODE.equals(childStr)){
802 prequest.setChild(WikiHelper.deleteParenthesis(childStr,"{","}"));
803 }
804
805 if (config_.isPluginLoaded(name)) {
806 Plugin plugin = config_.getPlugin(name);
807 try {
808 obj = plugin.service(request_, response_, prequest);
809 ispluginused = true;
810 } catch (PluginException pe) {
811 log_.error(pe.getMessage());
812 } catch (Exception e) {
813 e.printStackTrace();
814
815 }
816 }
817
818 if (obj instanceof List && !(obj instanceof Phrase)) {
819
820
821 List list = (List) obj;
822 for (Iterator i = list.iterator(); i.hasNext();) {
823 Element e = (Element) i.next();
824
825 if (e instanceof PdfPTable) {
826 pushObject(e);
827 } else {
828 addDocument(e, node);
829 }
830 }
831 return null;
832 }
833
834 if (!ispluginused)
835 obj = new Chunk("#" + prequest.toString(), defaultFont_);
836 return obj;
837 }
838
839 public Object visit(WikiLetters node, Object data) {
840
841 Element e = null;
842
843 if (node.isURL && !WikiHelper.isImage(node.letter)) {
844 e = new Anchor(node.letter);
845 ((Anchor) e).setReference(node.letter);
846 }
847
848 if (node.isAnchor) {
849 String id = (node.letter.startsWith("#")) ? node.letter
850 .substring(1) : node.letter;
851 e = new Chunk("\u00a0");
852 ((Chunk) e).setLocalDestination(id);
853 }
854
855 if (node.isWikiname) {
856 try {
857 if (ctx.isPageExist(node.letter, request_)) {
858 URL url = ctx.getURLByName(node.letter, request_);
859 e = new Anchor(node.letter);
860 ((Anchor) e).setReference(url.toString());
861 }
862 } catch (TgwSecurityException tse) {
863 e = new Chunk(node.letter, defaultFont_);
864 }
865
866 }
867
868 if (node.isNewline) {
869 e = Chunk.NEWLINE;
870 }
871
872 if (node.isURL && WikiHelper.isImage(node.letter)) {
873 try {
874 Image img = Image.getInstance(new URL(node.letter));
875 img.setAlignment(Image.MIDDLE | Image.TEXTWRAP);
876 return img;
877 } catch (BadElementException bee) {
878 bee.printStackTrace();
879 } catch (MalformedURLException mue) {
880 mue.printStackTrace();
881 } catch (IOException ioe) {
882 ioe.printStackTrace();
883 }
884 }
885
886 if (e == null) {
887 if (data instanceof Properties) {
888 Properties props = PdfUtils
889 .getDefaultfontProperties(defaultFont_);
890 props.putAll((Properties) data);
891 Font f = FontFactory.getFont(props);
892 e = new Chunk(node.letter, f);
893 } else {
894 e = new Chunk(node.letter, defaultFont_);
895 ((Chunk) e).setSplitCharacter(split);
896 }
897 }
898 return e;
899 }
900
901 public Object visit(WikiStrongItalic node, Object data) {
902
903 Properties props = PdfUtils.getDefaultfontProperties(defaultFont_);
904 StringBuffer buf = new StringBuffer();
905 if (VisitorUtils.isBold(node))
906 buf.append(MarkupTags.CSS_BOLD);
907 if (VisitorUtils.isItalic(node))
908 buf.append(MarkupTags.CSS_ITALIC);
909
910 String style = buf.toString();
911 if (style != null && !style.equals(""))
912 props.setProperty(ElementTags.STYLE, buf.toString());
913
914
915 Phrase p = new Phrase(props);
916
917 String pre = VisitorUtils.getAppendString(node, true);
918 String post = VisitorUtils.getAppendString(node, false);
919
920 if (pre != null)
921 p.add(new Chunk(pre, defaultFont_));
922 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
923 p.add(node.jjtGetChild(i).jjtAccept(this, data));
924 }
925 if (post != null)
926 p.add(new Chunk(post, defaultFont_));
927 return p;
928 }
929
930 public Object visit(WikiDeleteline node, Object data) {
931
932 Properties props = PdfUtils.getDefaultfontProperties(defaultFont_);
933 props.setProperty(ElementTags.STYLE, MarkupTags.CSS_LINETHROUGH);
934
935
936 Phrase p = new Phrase(props);
937 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
938 p.add(node.jjtGetChild(i).jjtAccept(this, data));
939 }
940 return p;
941 }
942
943 public Object visit(WikiAnnotation node, Object data) {
944
945 Properties p = PdfUtils.getDefaultfontProperties(defaultFont_);
946 p.setProperty(ElementTags.TITLE, "annotation" + node.num);
947 p.setProperty(ElementTags.CONTENT, getChildAsString(node, data, 0));
948 Annotation a = new Annotation(p);
949
950
951
952 return a;
953 }
954
955
956 public Object visit(WikiInterwiki node, Object data) {
957 return new Chunk("[[" + node.image + "]]", defaultFont_);
958 }
959
960 public Object visit(WikiLink node, Object data) {
961 String[] s = WikiHelper.split(node.image, WikiHelper.LINK_DELIMITER);
962 Anchor a = new Anchor(s[0], defaultFont_);
963 a.setReference(s[1]);
964 return a;
965 }
966
967 public Object visit(WikiAlias node, Object data) {
968 String[] s = WikiHelper.split(node.image, WikiHelper.ALIAS_DELIMITER);
969
970 Element e = null;
971 if (node.islink) {
972 e = new Anchor(s[0], defaultFont_);
973 ((Anchor) e).setReference(s[1]);
974 } else {
975 String[] t = WikiHelper.split(s[1], WikiHelper.ANCHOR_MARK);
976 try {
977 if (t[0] == null || t[0].equals("")) {
978
979 e = new Anchor(s[0], defaultFont_);
980 ((Anchor) e).setReference(WikiHelper.ANCHOR_MARK + t[1]);
981 } else if (ctx.isPageExist(t[0], request_)) {
982 URL url = ctx.getURLByName(t[0], request_);
983 String ref = url.toString();
984 if (t[1] != null && !t[1].equals(""))
985 ref += WikiHelper.ANCHOR_MARK + t[1];
986
987 e = new Anchor(s[0], defaultFont_);
988 ((Anchor) e).setReference(ref);
989 } else {
990 e = new Chunk(s[0], defaultFont_);
991 }
992 } catch (TgwSecurityException tse) {
993 e = new Chunk(s[0], defaultFont_);
994
995 }
996 }
997 return e;
998 }
999
1000 public Object visit(WikiPagename node, Object data) {
1001 String[] s = WikiHelper.split(node.image, WikiHelper.ANCHOR_MARK);
1002 Element e = null;
1003 try {
1004 if (ctx.isPageExist(s[0], request_)) {
1005 URL url = config_.getWikiContext().getURLByName(s[0], request_);
1006 e = new Anchor(s[0], defaultFont_);
1007 String ref = url.toString();
1008 if (s[1] != null && !s[1].equals(""))
1009 ref = ref + WikiHelper.ANCHOR_MARK + s[1];
1010 ((Anchor) e).setReference(ref);
1011 }
1012 } catch (TgwSecurityException tse) {
1013 e = new Chunk(s[0], defaultFont_);
1014 }
1015 return e;
1016 }
1017
1018 public Object visit(WikiInlinePlugin node, Object data) {
1019 String name = node.name;
1020 boolean ispluginused = false;
1021 int inlinestart = 0;
1022 Object obj = null;
1023
1024 PluginRequest prequest = VisitorUtils.createPluginRequest(node);
1025 if (prequest.getArgs() != null)
1026 inlinestart = 1;
1027 Phrase childphrase = getChildPhrase(node, data, inlinestart);
1028 prequest.setChild(childphrase);
1029
1030 if (config_.isPluginLoaded(name)) {
1031 Plugin plugin = config_.getPlugin(name);
1032 try {
1033 obj = plugin.service(request_, response_, prequest);
1034 ispluginused = true;
1035 } catch (PluginException pe) {
1036 log_.error(pe.getMessage());
1037 } catch (Exception e) {
1038 e.printStackTrace();
1039
1040 }
1041 }
1042
1043 if (obj instanceof List && !(obj instanceof Phrase)) {
1044
1045
1046 List list = (List) obj;
1047 for (Iterator i = list.iterator(); i.hasNext();) {
1048 Element e = (Element) i.next();
1049
1050 if (e instanceof PdfPTable) {
1051 pushObject(e);
1052 } else {
1053 addDocument(e, node);
1054 }
1055 }
1056 obj = new Chunk("\u00a0");
1057 }
1058
1059 if (!ispluginused) {
1060 if ("amp".equals(name)) {
1061 obj = new Chunk("\u0026", defaultFont_);
1062
1063 } else {
1064 obj = new Chunk("&" + prequest.toString() + ";", defaultFont_);
1065 }
1066 }
1067 return obj;
1068 }
1069
1070 public Object visit(WikiArgs node, Object data) {
1071 return null;
1072 }
1073
1074 public Object visit(WikiErrors node, Object data) {
1075 return getError(node.letter);
1076 }
1077
1078 private Phrase getChildPhrase(SimpleNode node, Object data, int idx) {
1079 Phrase p = new Phrase();
1080 for (int i = idx; i < node.jjtGetNumChildren(); i++) {
1081 p.add(node.jjtGetChild(i).jjtAccept(this, data));
1082 }
1083 return p;
1084 }
1085
1086 private String getChildAsString(SimpleNode node, Object data, int idx) {
1087 StringBuffer buf = new StringBuffer();
1088 for (int i = idx; i < node.jjtGetNumChildren(); i++) {
1089 Object o = node.jjtGetChild(i).jjtAccept(this, data);
1090 if (o instanceof Chunk) {
1091 buf.append(((Chunk) o).content());
1092 } else if (o instanceof Phrase) {
1093 for (Iterator itr = ((Phrase) o).getChunks().iterator(); itr
1094 .hasNext();) {
1095 buf.append(((Chunk) itr.next()).content());
1096 }
1097 } else {
1098 }
1099 }
1100 return buf.toString();
1101 }
1102
1103
1104
1105 private static int getAlign(String s) {
1106 int align = Element.ALIGN_LEFT;
1107
1108 String ls = s.toLowerCase().trim();
1109 if (ls.startsWith("left")) {
1110 align = Element.ALIGN_LEFT;
1111 } else if (ls.equals("center")) {
1112 align = Element.ALIGN_CENTER;
1113 } else if (ls.startsWith("right")) {
1114 align = Element.ALIGN_RIGHT;
1115 }
1116 return align;
1117 }
1118
1119 private static Chunk getError(String str) {
1120 return new Chunk(str, PdfUtils.FONT_ERROR);
1121 }
1122
1123 public Object visit(WikiAnyOther node, Object data) {
1124 return new Chunk(node.letter, defaultFont_);
1125 }
1126
1127
1128 }