source: other-projects/GlamED/trunk/src/org/honours/greenstone/CollectionCustomizer.java@ 26588

Last change on this file since 26588 was 26588, checked in by davidb, 11 years ago

Initial import of Korii's 520 project for managing digital cultural collections from Greenstone in Expeditee.

File size: 29.7 KB
Line 
1package org.honours.greenstone;
2
3import java.awt.Color;
4import java.awt.Font;
5import java.awt.Rectangle;
6import java.io.File;
7import java.util.ArrayList;
8import java.util.Collections;
9import java.util.Comparator;
10import java.util.List;
11
12import org.expeditee.gui.Frame;
13import org.expeditee.io.Conversion;
14import org.expeditee.items.Dot;
15import org.expeditee.items.Item;
16import org.expeditee.items.Picture;
17import org.expeditee.items.Text;
18import org.honours.collection.CollectionItem;
19import org.honours.html.Div;
20import org.honours.html.Table;
21import org.honours.html.TableRow;
22import org.honours.items.Data;
23import org.honours.items.PictureInformation;
24import org.honours.items.TextInformation;
25import org.w3c.dom.Document;
26import org.w3c.dom.Element;
27
28public class CollectionCustomizer {
29
30 private final String CONFIG_FILE = "collectionConfig.xml";
31 private final String ETC_DIR_NAME = "etc";
32
33 private List<Text> _textList;
34 private List<Text> _annotationList;
35 private List<Picture> _pictureList;
36 private List<Dot> _dotList;
37 private List<Table> _tablesList;
38 private List<Div> _divsList;
39
40 private List<Object> _remove;
41
42 private String _collectionConfigFilePath = null;
43
44 private CollectionConfigEditor _collectConfigEditor;
45
46 private static CollectionCustomizer _collectionCustomizer;
47
48 private CollectionItem _collectionItem;
49 private Frame _mainItemFrame;
50
51 /**
52 * Instantiate a new CollectionCustomizer object.
53 * @param collectionPath
54 */
55 private CollectionCustomizer(String collectionPath){
56 _collectionConfigFilePath = collectionPath + File.separator +
57 ETC_DIR_NAME + File.separator + CONFIG_FILE;
58
59 _textList = new ArrayList<Text>();
60 _annotationList = new ArrayList<Text>();
61 _pictureList = new ArrayList<Picture>();
62 _dotList = new ArrayList<Dot>();
63 _tablesList = new ArrayList<Table>();
64 _divsList = new ArrayList<Div>();
65
66 _remove = new ArrayList<Object>();
67
68 _collectConfigEditor = CollectionConfigEditor.getInstance(_collectionConfigFilePath);
69 }
70
71 /**
72 * Get instance of a CollectionCustomizer object.
73 * @param _collectionPath
74 * @return
75 */
76 public static CollectionCustomizer getInstance(String _collectionPath) {
77
78 if(_collectionCustomizer == null)
79 _collectionCustomizer = new CollectionCustomizer(_collectionPath);
80
81 return _collectionCustomizer;
82 }
83
84 /**
85 * Entry point where we start customizing
86 * the display of the collection.
87 * @param currCI
88 */
89 public void customize(CollectionItem cItem) {
90 _collectionItem = cItem;
91 _mainItemFrame = _collectionItem.getFrame();
92
93 getFrameItems();
94 sortDotItems();
95 obtainTables();
96 obtainDivs();
97 editGsdlDisplay();
98
99 }
100
101 /**
102 * Reset collection customizer instance so
103 * we can instantiate a new one for another collection/frameset.
104 */
105 public static void reset() {
106 _collectionCustomizer = null;
107
108 }
109
110 /**
111 * Reads all items on the frame and stores them
112 * for future use.
113 */
114 private void getFrameItems(){
115 for(Item item : _mainItemFrame.getItems()){
116
117 if(item.isAnnotation()){
118 if (item.getText().startsWith("@i:"))
119 _pictureList.add(PictureInformation.getPicture((Text)item));
120 else
121 _annotationList.add((Text) item);
122 }
123 else if (item instanceof Text) {
124 _textList.add((Text) item);
125 } else if (item instanceof Dot) {
126
127 // the dot belongs to a rectangle.
128 if (item.getConstraints().size() == 2 && item.getLines().size() == 2)
129 _dotList.add((Dot) item);
130 }
131
132 }
133 }
134
135 /**
136 * Retrieve all the dot items. For each rectangle on a frame,
137 * only one dot from that rectangle will remain in the dot list.
138 */
139 @SuppressWarnings({ "unchecked", "rawtypes" })
140 private void sortDotItems(){
141 Collections.sort(_dotList, new Comparator() {
142
143 public int compare(Object o1, Object o2) {
144 Dot d1 = (Dot) o1;
145 Dot d2 = (Dot) o2;
146 return new Integer(d1.getID()).compareTo(new Integer(d2.getID()));
147 }
148 });
149
150
151 int iter = 0;
152 List<Dot> tempDotList = _dotList;
153 List<Rectangle> tempRectList = new ArrayList<Rectangle>();
154 _dotList = new ArrayList<Dot>();
155
156 while(iter < tempDotList.size()){
157
158 Dot curr = tempDotList.get(iter);
159 Rectangle currRect = curr.getEnclosedRectangle();
160
161 if(!tempRectList.contains(currRect)){
162 tempRectList.add(currRect);
163 _dotList.add(curr);
164 }
165
166 iter++;
167 }
168 }
169
170 /**
171 * Obtain all rectangles on a frame that are considered
172 * to be a table object. Each rectangle is sorted firstly
173 * by its x coordinate and then its y coordinate.
174 */
175 @SuppressWarnings({ "unchecked", "rawtypes" })
176 private void obtainTables(){
177 //Sort dot list by x coordinate.
178 Collections.sort(_dotList, new Comparator(){
179 public int compare(Object o1, Object o2){
180 Dot d1 = (Dot) o1;
181 Dot d2 = (Dot) o2;
182
183 Rectangle r1 = d1.getEnclosedRectangle();
184 Rectangle r2 = d2.getEnclosedRectangle();
185 return new Integer(r1.x).compareTo(r2.x);
186 }
187 });
188
189 // Sort dot list by y coordinate.
190 Collections.sort(_dotList, new Comparator() {
191
192 public int compare(Object o1, Object o2) {
193 Dot d1 = (Dot) o1;
194 Dot d2 = (Dot) o2;
195
196 Rectangle r1 = d1.getEnclosedRectangle();
197 Rectangle r2 = d2.getEnclosedRectangle();
198 return new Integer(r1.y).compareTo(r2.y);
199 }
200 });
201
202 if(_dotList.size() > 0){
203
204 TableRow row = new TableRow();
205 row.addDot(_dotList.get(0));
206 Rectangle curr = _dotList.get(0).getEnclosedRectangle();
207 List<TableRow> listOfRows = new ArrayList<TableRow>();
208
209 recursionRows(curr, 1, row, listOfRows);
210
211 // Now that we have found all rows, we determine how to group these
212 // rows in their respective tables!
213 if (listOfRows.size() > 0) {
214 TableRow currRow = listOfRows.get(0);
215 Table table = new Table();
216 recursionTables(currRow, table, 1, listOfRows);
217 }
218 }
219 }
220
221 /**
222 * Obtains all rows of rectangles from a frame and turns them into table row (tr) objects.
223 * @param r - the current rectangle being read on the frame.
224 * @param i - a counter.
225 * @param row - the row for adding the rectangle to.
226 * @param listOfRows - the list to add the row to.
227 */
228 private void recursionRows(Rectangle r, int i, TableRow row, List<TableRow> listOfRows){
229 if (!row.getRow().contains(r))
230 row.add(r);
231
232 if (i < _dotList.size()) {
233 Rectangle compare = _dotList.get(i).getEnclosedRectangle();
234
235 if (r.y == compare.y) {
236
237 if (r.x + r.width == compare.x) {
238 row.add(compare);
239 row.addDot(_dotList.get(i));
240 i++;
241 recursionRows(compare, i, row, listOfRows);
242 }
243 } else {
244 listOfRows.add(row);
245 row = new TableRow();
246 row.addDot(_dotList.get(i));
247 i++;
248 recursionRows(compare, i, row, listOfRows);
249 }
250 } else {
251 listOfRows.add(row);
252 return;
253 }
254 }
255
256 /**
257 * Once all rows are obtained on a frame, they are grouped
258 * together to obtain tables.
259 * @param row - the current row being processed
260 * @param table - the table to add the row to
261 * @param i - a counter
262 * @param listOfRows - to obtain a row for comparison.
263 */
264 private void recursionTables(TableRow row, Table table, int i, List<TableRow> listOfRows){
265
266 if (!table.getTable().contains(row))
267 table.addRow(row);
268
269 if (i < listOfRows.size()) {
270
271 TableRow compare = listOfRows.get(i);
272 Rectangle rowRect = row.getRow().get(0);
273 Rectangle compareRect = compare.getRow().get(0);
274
275 if (rowRect.x == compareRect.x) {
276
277 if (rowRect.y + rowRect.height == compareRect.y) {
278 table.addRow(compare);
279 i++;
280 recursionTables(compare, table, i, listOfRows);
281 }
282 else{ //not sure if i need this else statement just yet...
283 _tablesList.add(table);
284 table = new Table();
285 i++;
286 recursionTables(compare,table,i,listOfRows);
287 }
288 } else {
289 _tablesList.add(table);
290 table = new Table();
291 i++;
292 recursionTables(compare, table, i, listOfRows);
293 }
294 } else {
295 _tablesList.add(table);
296 return;
297 }
298 }
299
300 /**
301 * Obtains all rectangles on a frame that are considered to be div objects.
302 * A rectangle is considered a div if it stands alone
303 * (i.e. no other rectangles are joined to it).
304 */
305 private void obtainDivs(){
306
307 int iter = _tablesList.size() - 1;
308 while (iter > -1) {
309
310 Table table = _tablesList.get(iter);
311 if (table.getTable().size() == 1) {
312
313 TableRow row = table.getTable().get(0);
314
315 if (row.getRow().size() == 1) {
316 Rectangle r = row.getRow().get(0);
317 Dot d = row.getDots().get(0);
318
319 Div div = new Div(r);
320 div.setDot(d);
321 _divsList.add(div);
322 _tablesList.remove(iter); // remove table from _tablesList since it is really a div.
323 }
324 }
325 iter--;
326 }
327 }
328
329 /**
330 * This is where we start processing all items on
331 * a frame and writing out the matching HTML.
332 */
333 private void editGsdlDisplay(){
334
335 try{
336 Element documentContent = _collectConfigEditor.getDocumentContentTemplate();
337
338 //setUpAnnotationsTemplate(_collectConfigEditor.getExpediteeAttrTable());
339
340 List<Object> objects = new ArrayList<Object>();
341
342 addToObjects(objects, _textList);
343 addToObjects(objects, _pictureList);
344 addToObjects(objects, _tablesList);
345 addToObjects(objects, _divsList);
346
347 sortObjectsList(objects);
348
349 processItems(objects,documentContent,null,null);
350
351 //Append showAssocFilePath template.
352 appendAssocFilePathTemplate(documentContent);
353
354 //changeGsContentHeight();
355
356 _collectConfigEditor.write();
357
358 }catch(Exception e){
359 e.printStackTrace();
360 return;
361 }
362 }
363
364 /**
365 * Add in the "showAssocFilePath" template to the collectionConfig.xml file and calls
366 * this template in the documentContent section.
367 * The "showAssocFilePath" template is used to display the GSDL document's
368 * matching assocfilepath value, provided the user has appended the document's
369 * URL with "p.showAssocFilePath=1".
370 * @param documentContent - the document content template to append the <xsl:call-template name="showAssocFilePath"/> element to.
371 */
372 private void appendAssocFilePathTemplate(Element documentContent){
373
374 Document doc = documentContent.getOwnerDocument();
375 Element assocFilePathTemplate = _collectConfigEditor.getAssocFilePathTemplate();
376
377 Element xslIf = doc.createElement("xsl:if");
378 xslIf.setAttribute("test","/page/pageRequest/paramList/param[@name='p.showAssocFilePath']/@value='1'");
379 assocFilePathTemplate.appendChild(xslIf);
380
381 Element span = doc.createElement("span");
382 span.setAttribute("data", "gsdl.Metadata: assocfilepath");
383 xslIf.appendChild(span);
384
385 span.appendChild(doc.createTextNode("@assocfilepath "));
386
387 Element gsfMetadata = doc.createElement("gsf:metadata");
388 gsfMetadata.setAttribute("name","assocfilepath");
389 span.appendChild(gsfMetadata);
390
391 //Generate <xsl:call-template name="showAssocFilePath"/> and append to end of documentContent template.
392 Element xslCall = doc.createElement("xsl:call-template");
393 xslCall.setAttribute("name", "showAssocFilePath");
394
395 documentContent.appendChild(xslCall);
396
397 }
398
399 /**
400 * Method to add items in a list to a list of objects.
401 * @param objects
402 * @param list
403 */
404 @SuppressWarnings("rawtypes")
405 public static void addToObjects(List<Object> objects, List list) {
406 for (int i = 0; i < list.size(); i++) {
407 objects.add(list.get(i));
408 }
409 }
410
411 /**
412 * Sort all objects in a list first by their x coordinate
413 * and then by their y coordinate.
414 * @param l
415 */
416 @SuppressWarnings({ "unchecked", "rawtypes" })
417 public static void sortObjectsList(List<Object> l) {
418
419 //sort by x-coordinate
420 Collections.sort(l, new Comparator(){
421
422 @Override
423 public int compare(Object o1, Object o2){
424
425 int d1 = 0;
426 int d2 = 0;
427
428 if(o1 instanceof Text){
429 Text t1 = (Text)o1;
430 d1 = t1.getX();
431 }else if(o1 instanceof Picture){
432 Picture p1 = (Picture) o1;
433 d1 = p1.getX();
434 }else if(o1 instanceof Table){
435 Table t1 = (Table)o1;
436 d1 = (int)(t1.getTable().get(0).getRow().get(0).getY());
437 }else if(o1 instanceof Div){
438 Div div1 = (Div)o1;
439 d1 = (int)(div1.getDiv().getY());
440 }
441
442 if(o2 instanceof Text){
443 Text t2 = (Text)o2;
444 d2 = t2.getX();
445 }else if(o2 instanceof Picture){
446 Picture p2 = (Picture)o2;
447 d2 = p2.getX();
448 }else if(o2 instanceof Table){
449 Table t2 = (Table)o2;
450 d2 = (int)(t2.getTable().get(0).getRow().get(0).getY());
451 }else if(o2 instanceof Div){
452 Div div2 = (Div)o2;
453 d2 = (int)(div2.getDiv().getY());
454 }
455
456 return new Integer(d1).compareTo(new Integer(d2));
457 }
458 });
459
460
461 //sort by y-coordinate
462 Collections.sort(l, new Comparator() {
463
464 @Override
465 public int compare(Object o1, Object o2) {
466 int d1 = 0;
467 int d2 = 0;
468
469 if (o1 instanceof Text) {
470 Text t1 = (Text) o1;
471 d1 = t1.getY();
472 } else if (o1 instanceof Picture) {
473 Picture p1 = (Picture) o1;
474 d1 = p1.getY();
475 } else if (o1 instanceof Table) {
476 Table t1 = (Table) o1;
477 d1 = (int) (t1.getTable().get(0).getRow().get(0).getY());
478 } else if (o1 instanceof Div) {
479 Div div1 = (Div) o1;
480 d1 = (int) (div1.getDiv().getY());
481 }
482
483 if (o2 instanceof Text) {
484 Text t2 = (Text) o2;
485 d2 = t2.getY();
486 } else if (o2 instanceof Picture) {
487 Picture p2 = (Picture) o2;
488 d2 = p2.getY();
489 } else if (o2 instanceof Table) {
490 Table t2 = (Table) o2;
491 d2 = (int) (t2.getTable().get(0).getRow().get(0).getY());
492 } else if (o2 instanceof Div) {
493 Div div2 = (Div) o2;
494 d2 = (int) (div2.getDiv().getY());
495 }
496
497 return new Integer(d1).compareTo(new Integer(d2));
498 }
499 });
500 }
501
502 /**
503 *
504 * @param objects
505 * @param docContent
506 * @param containerElem
507 * @param containeRect
508 */
509 private void processItems(List<Object> objects,Element docContent,Element containerElem,Rectangle containerRect)
510 throws Exception{
511
512 for (Object o : objects) {
513 if (o instanceof Text) {
514 Text text = (Text) o;
515 processText(text, docContent, containerElem,containerRect);
516 } else if (o instanceof Picture) {
517 Picture pic = (Picture) o;
518 processPicture(pic, docContent, containerElem, containerRect);
519 } else if (o instanceof Table) {
520 Table table = (Table) o;
521 drawTable(table,docContent,containerElem,containerRect);
522 } else if (o instanceof Div) {
523 Div div2 = (Div) o;
524 drawDiv(div2,docContent,containerElem,containerRect);
525 }
526
527 }
528 }
529
530 /**
531 * Process any text items on an Expeditee frame and
532 * write out the appropriate html.
533 * @param text
534 * @param docContent
535 * @param containerElem
536 * @param containerRect
537 */
538 private void processText(Text text, Element docContent, Element containerElem, Rectangle containerRect){
539
540 if(!_remove.contains(text)){
541
542 Font font = text.getPaintFont();
543 Color c = text.getColor();
544 float size = text.getSize();
545
546 String[] fontAttr = TextInformation.setUpFontAttributes(font,c);
547
548 Document doc = docContent.getOwnerDocument();
549
550 //Returns either a heading or paragraph html element depending on font styles & size.
551 Element elem = TextInformation.determineTextElemType(size,fontAttr[1].equals("bold"),doc);
552 docContent.appendChild(elem);
553
554 //StringBuffer to store value of the paragraph's style attributes
555 StringBuffer style = new StringBuffer("");
556
557 //Only write out font size if dealing with a paragraph element.
558 if(elem.getNodeName().equals("p")){
559 style.append("font-size: " + size + "px; ");
560 }
561
562 style.append("font-family: " + fontAttr[0] + "; ");
563 style.append("font-style: " + fontAttr[2] + "; ");
564 style.append("color: " + fontAttr[3] + "; ");
565
566 //if the text has a parent element
567 if(containerElem != null){
568 containerElem.appendChild(elem);
569
570 if(containerElem.getNodeName().equals("div")){
571
572 style.append("position: absolute;");
573 int left = text.getX() - containerRect.x;
574 int top = (text.getArea().getBounds().y - text.getHeight()) - containerRect.y;
575 style.append("left: " + left + "px; ");
576 style.append("top: " + top + "px; ");
577 }
578 }
579
580 elem.setAttribute("style",style.toString());
581
582 if(Data.HasData(text)){
583
584 Element e = doc.createElement("gsf:metadata");
585 String data = text.getData().get(0);
586 elem.setAttribute("data", data);
587 e.setAttribute("name",data);
588 elem.appendChild(e);
589 }else{
590 org.w3c.dom.Text textNode = doc.createTextNode(text.getText());
591 elem.appendChild(textNode);
592 }
593
594 _remove.add(text);
595
596 }
597 }
598
599 /**
600 *
601 * Process any picture items on the frame and
602 * write out image tags in the collectionConfig.xml file.
603 * Creates an <xsl:template></xsl:template> which should
604 * overwrite GSDL's <xsl:template name="sectionImage"></xsl:template>
605 * originally located in web\interfaces\default\transform\pages\document.xsl.
606 * Then the line: <xsl:call-template name="sectionImage"/> should be
607 * written to the document-content template.
608 *
609 * @param pic - the Expeditee picture item currently being processed
610 * @param docContent - the document-content template we are writing html to
611 * @param containerElem - an element the picture may be a child of
612 * @param containerRect - the rectangle representing the container element
613 */
614 private void processPicture(Picture pic, Element docContent, Element containerElem, Rectangle containerRect){
615 if(!_remove.contains(pic)){
616
617 //Border styling info
618 Color c = pic.getBorderColor();
619 float thickness = (pic.getThickness() <= 0) ? 1 : pic.getThickness();
620 String color = (c != null) ? Conversion.getCssColor(c) : Conversion.getCssColor(Color.BLACK);
621
622 Document doc = docContent.getOwnerDocument();
623
624 //true for now...
625 boolean isGsdlImage = true;
626 Text source = pic.getSource();
627
628 if(isGsdlImage){
629
630 Element sectionImgTemplate = _collectConfigEditor.getSectionImageTemplate();
631
632 StringBuffer style = new StringBuffer("");
633
634 //Deal with changes in size of image.
635 int width = pic.getBoundsWidth();
636 int height = pic.getBoundsHeight();
637
638
639 style.append("border: " + thickness + "px solid " + color + "; ");
640
641 Element xslCallTemplate = doc.createElement("xsl:call-template");
642 xslCallTemplate.setAttribute("name","sectionImage");
643
644 //if image is a child of another element (such as a div)
645 if(containerElem != null){
646
647 if(containerElem.getNodeName().equals("div")){
648 style.append("position: absolute; ");
649
650 int left = pic.getX() - containerRect.x;
651 int top = pic.getY() - containerRect.y;
652
653 style.append("left: " + left + "px; ");
654 style.append("top: " + top + "px; ");
655
656 containerElem.appendChild(xslCallTemplate);
657
658 }else if(containerElem.getNodeName().equals("td")){
659 containerElem.appendChild(xslCallTemplate);
660 }
661 }else{
662 docContent.appendChild(xslCallTemplate);
663 }
664
665 //Create <xsl:variable></xsl:variable> element
666 Element screenXslVariable = doc.createElement("xsl:variable");
667 screenXslVariable.setAttribute("name","ScreenName");
668 screenXslVariable.appendChild(doc.createTextNode("Screen"));
669
670 sectionImgTemplate.appendChild(screenXslVariable);
671
672 //Create <img></img> element
673 Element img = doc.createElement("img");
674 img.setAttribute("style",style.toString());
675 img.setAttribute("width",Integer.toString(width));
676 img.setAttribute("height",Integer.toString(height));
677 sectionImgTemplate.appendChild(img);
678
679 //Create <xsl:attribute name='src'></xsl:attribute> element
680 Element srcXslAttribute = doc.createElement("xsl:attribute");
681 srcXslAttribute.setAttribute("name","src");
682 img.appendChild(srcXslAttribute);
683
684 //Create <xsl:value-of ..../> element.
685 Element xslValueOf = createXslValueOfElem("yes", "/page/pageResponse/collection/metadataList/metadata[@name= 'httpPath']",doc);
686 srcXslAttribute.appendChild(xslValueOf);
687
688
689 //Create <xsl:text></xsl:text> element
690 Element xslText = createXslText("/index/assoc/",doc);
691
692 System.err.println("xslText: " + xslText);
693 System.err.println("srcXslAttribute: " + srcXslAttribute);
694
695 srcXslAttribute.appendChild(xslText);
696
697 xslValueOf = createXslValueOfElem("yes","/page/pageResponse/document/metadataList/metadata[@name = 'assocfilepath']",doc);
698 srcXslAttribute.appendChild(xslValueOf);
699
700 xslText = createXslText("/",doc);
701 srcXslAttribute.appendChild(xslText);
702
703 xslValueOf = createXslValueOfElem("yes","(.//metadataList)[last()]/metadata[@name = $ScreenName]",doc);
704 srcXslAttribute.appendChild(xslValueOf);
705 }else{
706
707 _annotationList.add(source);
708 }
709
710 //TODO: Deal with situation where actual image changes.
711
712 //TODO: Deal with display of multiple images.
713
714 //TODO: Deal with adding images not part of GSDL collection.
715
716 _remove.add(pic);
717
718 }
719 }
720
721 private Element createXslValueOfElem(String disable, String select, Document doc){
722
723 Element xslValueOf = doc.createElement("xsl:value-of");
724
725 xslValueOf.setAttribute("disable-output-escaping",disable);
726 xslValueOf.setAttribute("select",select);
727
728 return xslValueOf;
729 }
730
731 private Element createXslText(String text, Document doc){
732
733 Element xslText = doc.createElement("xsl:text");
734 xslText.appendChild(doc.createTextNode(text));
735
736 return xslText;
737 }
738
739 /**
740 *
741 * @param table
742 * @param docContent
743 * @param containerElem
744 * @param containerRect
745 */
746 private void drawTable(Table table, Element docContent, Element containerElem, Rectangle containerRect){
747 if(!_remove.contains(table)){
748
749 int tableWidth = 0;
750 List<Rectangle> firstRow = table.getTable().get(0).getRow();
751
752 for (Rectangle rect : firstRow)
753 tableWidth += rect.width;
754
755 Color bg, c;
756 String bgColor, color;
757 float thickness;
758
759 Dot d = table.getTable().get(0).getDots().get(0);
760 c = (d.getBorderColor() != null) ? d.getBorderColor() : d.getColor();
761 color = (c != null) ? Conversion.getCssColor(c) : Conversion.getCssColor(Color.black);
762 thickness = d.getThickness() >= 0 ? d.getThickness() : 1;
763
764 Document doc = docContent.getOwnerDocument();
765 Element tableEl = doc.createElement("table");
766 docContent.appendChild(tableEl);
767
768 StringBuffer styleAttr = new StringBuffer("");
769 styleAttr.append("border-collapse: collapse; ");
770 styleAttr.append("border: " + thickness + "px solid " + color + "; ");
771
772 if (containerRect != null) {
773 String percentageWidth = String.format("%2.02f",
774 ((float) tableWidth) / containerRect.width * 100) + "%";
775 styleAttr.append("width: " + percentageWidth + "; ");
776 }
777
778 if (containerElem != null) {
779 //absolute position table within its parent
780 styleAttr.append("position: absolute; ");
781 int left = firstRow.get(0).x - containerRect.x;
782 int top = firstRow.get(0).y - containerRect.y;
783 styleAttr.append("left: " + left + "px; ");
784 styleAttr.append("top: " + top + "px;");
785 }
786
787 tableEl.setAttribute("style", styleAttr.toString());
788 tableEl.setAttribute("cellpadding", "1");
789 tableEl.setAttribute("cellspacing", "0");
790
791 // Retrieve each table row (<tr>)
792 for (int j = 0; j < table.getTable().size(); j++) {
793
794 TableRow currRow = table.getTable().get(j);
795 Element row = doc.createElement("tr");
796
797 //Retrieve each table cell <td>
798 for(int k = 0; k < currRow.getRow().size(); k++){
799
800 Dot currCellDot = currRow.getDots().get(k);
801 Rectangle currCell = currRow.getRow().get(k);
802 bg = currCellDot.getFillColor();
803 bgColor = (bg != null) ? Conversion.getCssColor(bg) : Conversion.getCssColor(Color.WHITE);
804
805 Element td = doc.createElement("td");
806
807 styleAttr = new StringBuffer("");
808 styleAttr.append("border: " + thickness + "px solid " + color + "; ");
809 styleAttr.append("background-color: " + bgColor + ";");
810 td.setAttribute("style", styleAttr.toString());
811 getItemsWithinContainer(currCell, td, docContent);
812
813 row.appendChild(td);
814 }
815
816 tableEl.appendChild(row);
817
818 }
819
820 if (containerElem != null)
821 containerElem.appendChild(tableEl);
822
823 _remove.add(table);
824 }
825 }
826
827 private void getItemsWithinContainer(Rectangle currContainer, Element elem,Element docContent){
828
829 int currX = currContainer.x;
830 int currY = currContainer.y;
831
832 int currWidth = currContainer.width;
833 int currHeight = currContainer.height;
834
835 int[] dimensions = new int[]{ currX, currY, currWidth, currHeight };
836
837 List<Item> itemsInCell = new ArrayList<Item>();
838
839 addToItemsInCell(_textList,itemsInCell,dimensions);
840 addToItemsInCell(_pictureList,itemsInCell,dimensions);
841
842 for(Item i : itemsInCell){
843 if(i instanceof Text){
844 processText((Text)i,docContent,elem,currContainer);
845 }else if(i instanceof Picture){
846 processPicture((Picture)i,docContent,elem,currContainer);
847 }
848 }
849 }
850
851 /**
852 * Method to add items to a list of items within a particular cell/container.
853 * @param items
854 * @param itemsInCell
855 * @param dimensions
856 */
857 @SuppressWarnings("rawtypes")
858 public static void addToItemsInCell(List items, List<Item> itemsInCell,int[] dimensions) {
859
860 for (int i = 0; i < items.size(); i++) {
861 Item t = (Item) items.get(i);
862 if (t.getX() >= dimensions[0]
863 && t.getX() <= dimensions[0] + dimensions[2]) {
864 if (t.getY() >= dimensions[1]
865 && t.getY() <= dimensions[1] + dimensions[3])
866 itemsInCell.add(t);
867 }
868 }
869 }
870
871 /**
872 * Writes out div html and any html
873 * within the div to the collectionConfig.xml file.
874 * @param div
875 * @param docContent
876 * @param containerElem
877 * @param containerRect
878 */
879 private void drawDiv(Div div, Element docContent, Element containerElem, Rectangle containerRect){
880
881 if(!_remove.contains(div)){
882
883 Dot d = div.getDot();
884
885 Color c = (d.getBorderColor() != null) ? d.getBorderColor() : d.getColor();
886 String color = (c != null) ? Conversion.getCssColor(c) : Conversion.getCssColor(Color.BLACK);
887 Color bg = d.getFillColor();
888
889 String bgColor = (bg != null) ? Conversion.getCssColor(bg) : Conversion.getCssColor(Color.WHITE);
890
891 float thickness = d.getThickness() >= 0 ? d.getThickness() : 1;
892 int width = div.getDiv().width;
893 int height = div.getDiv().height;
894
895 Document doc = docContent.getOwnerDocument();
896 Element divEl = doc.createElement("div");
897 docContent.appendChild(divEl);
898
899 StringBuffer styleAttr = new StringBuffer("");
900 styleAttr.append("border: " + thickness + "px solid " + color + "; ");
901 styleAttr.append("background-color: " + bgColor + "; ");
902 styleAttr.append("width: " + width + "px; ");
903 styleAttr.append("height: " + height + "px; ");
904
905 //the element has a parent so position the element relevant to this parent.
906 if (containerRect != null) {
907 styleAttr.append("position: absolute; ");
908 int left = div.getDiv().x - containerRect.x;
909 int top = div.getDiv().y - containerRect.y;
910
911 styleAttr.append("left: " + left + "px; ");
912 styleAttr.append("top: " + top + "px;");
913 } else // the element does NOT have a parent (i.e. it most likely IS a parent)
914 styleAttr.append("position: relative; ");
915
916 String id = null;
917 if(Data.HasData(d)){
918 id = d.getData().get(0);
919 }
920
921 if(id != null)
922 divEl.setAttribute("id",id);
923
924 divEl.setAttribute("style", styleAttr.toString());
925
926 // Add ALL items within the div to this list.
927 List<Object> objects = new ArrayList<Object>();
928
929 Rectangle container = div.getDiv();
930
931 addToChildrenObjects(objects, _textList, div, container);
932 addToChildrenObjects(objects, _pictureList, div, container);
933 addToChildrenObjects(objects, _tablesList, div, container);
934 addToChildrenObjects(objects, _divsList, div, container);
935
936 sortObjectsList(objects);
937
938 try{
939 processItems(objects, docContent,divEl,div.getDiv());
940 }catch(Exception e){
941 e.printStackTrace();
942 return;
943 }
944
945 if (containerElem != null)
946 containerElem.appendChild(divEl);
947
948 _remove.add(div);
949 }
950 }
951
952 /**
953 * Used to add all items located within another item (such
954 * as a rectangle) to the same list.
955 * @param objects
956 * @param list
957 * @param div
958 * @param container
959 */
960 @SuppressWarnings({ "rawtypes" })
961 public static void addToChildrenObjects(List<Object> objects, List list, Div div,Rectangle container) {
962 for (int i = 0; i < list.size(); i++) {
963
964 if (list.get(i) instanceof Item) {
965 Item currItem = (Item) list.get(i);
966 int currItemX = currItem.getX();
967 int currItemY = currItem.getY();
968 if (currItemX >= container.x && currItemX <= container.x + container.width)
969 if (currItemY >= container.y && currItemY <= container.y + container.height)
970 objects.add(currItem);
971
972 } else if (list.get(i) instanceof Div) {
973
974 Div currDiv = (Div) list.get(i);
975 Rectangle currDivRect = currDiv.getDiv();
976
977 if (currDivRect.x >= container.x && currDivRect.x <= container.x + container.width)
978 if (currDivRect.y >= container.y && currDivRect.y <= container.y + container.height)
979 if (currDiv != div)
980 objects.add(currDiv);
981
982 } else if (list.get(i) instanceof Table) {
983
984 Table currTable = (Table) list.get(i);
985 Rectangle currTableRect = currTable.getTable().get(0).getRow().get(0);
986
987 if (currTableRect.x >= container.x && currTableRect.x <= container.x + container.width)
988 if (currTableRect.y >= container.y && currTableRect.y <= container.y + container.height)
989 objects.add(currTable);
990 }
991 }
992 }
993
994
995}
Note: See TracBrowser for help on using the repository browser.