HTMLGenerator.java
001 /*
002  *  HTMLGenerator.java
003  *
004  *  Niraj Aswani, 19/March/07
005  *
006  *  $Id: HTMLGenerator.html,v 1.0 2007/03/19 16:22:01 niraj Exp $
007  */
008 package gate.creole.annic;
009 
010 import java.util.*;
011 
012 /**
013  * This class provides methods to export the annic patterns to HTML. The
014  * HTML provides a way to look at various annotations that span across
015  * the found annic pattern.
016  
017  @author niraj
018  */
019 public class HTMLGenerator {
020 
021   /**
022    * This method exports the annic pattern to HTML. The HTML provides a
023    * way to look at various annotations that span across the found annic
024    * pattern.
025    
026    @param pattern
027    @return
028    */
029   public static String generateHTMLTable(Pattern pattern) {
030     PatternAnnotation[] patternAnnotations = pattern.getPatternAnnotations();
031 
032     // for each table we create a separate html code
033     String html = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"100%\" style=\"border-collapse: collapse; border: medium none; background: #E6E6E6\">";
034 
035     // at the begining we find out number of rows we need to create for
036     // this
037     List<String> rows = getRowData(patternAnnotations);
038     Collections.sort(rows);
039 
040     // find out the number of columns
041     List<String> colPositions = getColsPositions(patternAnnotations);
042     Collections.sort(colPositions, new Comparator<String>() {
043       public int compare(String a, String b) {
044         int aVal = Integer.parseInt((String)a);
045         int bVal = Integer.parseInt((String)b);
046         return aVal - bVal;
047       }
048     });
049 
050     patternAnnotations = sort(patternAnnotations);
051 
052     html += "\n"
053             "<tr> " +
054             "<td style=\"width: 85.25pt; border-left: medium none; border-right: 1.0pt dashed blue; " +
055             "border-top: 1.0pt dashed blue; border-bottom: 1.0pt dashed blue; padding-left: 5.4pt; " +
056             "padding-right: 5.4pt; padding-top: 0cm; padding-bottom: 0cm\">" +
057             "<p class=\"MsoNormal\" align=\"center\">Pattern Text : </td>";
058     int endPos = patternAnnotations[0].getStartOffset();
059     int startPos = 0;
060     for(int j = 1; j < colPositions.size(); j++) {
061       startPos = endPos;
062       endPos = Integer.parseInt(colPositions.get(j));
063       String text = pattern.getPatternText(startPos, endPos);
064       html += "\n"
065               "<td style=\"border: 1.0pt dashed blue;\" align=\"center\">"
066               + text + "</td>";
067     }
068 
069     // and now for each type we create a new Row
070     for(int j = 0; j < rows.size(); j++) {
071 
072       // first column is the annotation Type
073       html += "\n" "<tr width=\"100%\" height=\"19\"> <td>"
074               + rows.get(j"</td>";
075       List<PatternAnnotation> rowAnnotations = findOutAnnotationsOfType(patternAnnotations,
076               rows.get(j));
077 
078       int columnsDrawn = 0;
079       for(int k = 0; k < rowAnnotations.size(); k++) {
080         // for each annotation we will create a column
081         PatternAnnotation annot = (PatternAnnotation)rowAnnotations.get(k);
082 
083         // we may need to draw few columns before this annotations
084         html += "\n"
085                 + columnsToDraw(patternAnnotations, rowAnnotations, k,
086                         colPositions);
087         columnsDrawn += noOfColumnsToDraw;
088 
089         // now lets find out the annotations at the same starting
090         // positions
091         List<PatternAnnotation> tempList = new ArrayList<PatternAnnotation>();
092         tempList.add(annot);
093 
094         int maxEndOffset = annot.getEndOffset();
095         int m = k + 1;
096         for(; m < rowAnnotations.size(); m++) {
097           PatternAnnotation annot1 = rowAnnotations.get(m);
098           if(annot.getStartOffset() == annot1.getStartOffset()) {
099             tempList.add(annot1);
100             if(annot1.getEndOffset() > maxEndOffset) {
101               maxEndOffset = annot1.getEndOffset();
102             }
103           }
104           else {
105             m--;
106             break;
107           }
108         }
109 
110         if(k != m) {
111           k = m;
112         }
113 
114         int colSpan = getColSpan(annot.getStartOffset(), maxEndOffset,
115                 colPositions);
116 
117         if(colSpan > 0) {
118           html += "\n"
119                   "<td style=\"border: 1.0pt dashed blue;\" align=\"center\" colspan=\""
120                   + colSpan + "\" <p align=\"center\">";
121           columnsDrawn += colSpan;
122         }
123         else {
124           html += "\n"
125                   "<td style=\"border: 1.0pt dashed blue;\" align=\"center\"> <p align=\"center\">";
126           columnsDrawn += 1;
127         }
128 
129         for(m = 0; m < tempList.size(); m++) {
130           html += addFeatures(tempList.get(m).getFeatures())
131                   "<br>";
132         }
133 
134         html += "</td>";
135       }
136 
137       // now see how many columns are yet to be drawn
138       for(int k = 0; k < colPositions.size() - columnsDrawn; k++) {
139         html += "\n" "<td style=\"border: 1.0pt dashed blue;\">&nbsp;</td>";
140       }
141       html += "\n" "</tr>";
142     }
143 
144     // and finally we need to add all the annotations at the end
145     html += "\n" "</table>";
146     return html;
147   }
148 
149   /**
150    * This method is used for sorting the pattern annotations.
151    
152    @param annots
153    @return
154    */
155   private static PatternAnnotation[] sort(PatternAnnotation[] annots) {
156 
157     for(int i = 0; i < annots.length; i++) {
158       for(int j = 0; j < annots.length - 1; j++) {
159         if(annots[j].getStartOffset() > annots[j + 1].getStartOffset()) {
160           PatternAnnotation temp = annots[j + 1];
161           annots[j + 1= annots[j];
162           annots[j= temp;
163           break;
164         }
165 
166         if(annots[j].getEndOffset() > annots[j + 1].getEndOffset()) {
167           PatternAnnotation temp = annots[j + 1];
168           annots[j + 1= annots[j];
169           annots[j= temp;
170           break;
171         }
172       }
173     }
174     return annots;
175   }
176 
177   /**
178    * Number of columns to draw in the html table.
179    */
180   private static int noOfColumnsToDraw = 0;
181 
182   private static String columnsToDraw(
183           PatternAnnotation[] currentTableAnnotations,
184           List<PatternAnnotation> rowAnnotations, int currentPos, List<String> colPositions) {
185 
186     // if currentPos == 0
187     // this is the first annotation in this row
188     int startPoint = 0;
189     if(currentPos == 0) {
190       startPoint = ((PatternAnnotation)currentTableAnnotations[0])
191               .getStartOffset();
192     }
193     else {
194       startPoint = ((PatternAnnotation)rowAnnotations.get(currentPos - 1))
195               .getEndOffset();
196     }
197 
198     noOfColumnsToDraw = noOfColumnsToDraw(startPoint,
199             rowAnnotations.get(currentPos)
200                     .getStartOffset(), colPositions);
201     String html = "";
202     for(int i = 0; i < noOfColumnsToDraw; i++) {
203       html += "\n" "<td style=\"border: 1.0pt dashed blue;\">&nbsp;</td>";
204     }
205     return html;
206   }
207 
208   private static int noOfColumnsToDraw(int start, int end,
209           List<String> colPositions) {
210     if(start == endreturn 0;
211 
212     int counter = 0;
213     int i = 0;
214     for(; i < colPositions.size(); i++) {
215       if(Integer.parseInt(colPositions.get(i)) == start) {
216         i++;
217         break;
218       }
219     }
220 
221     if(i == colPositions.size() || i < 0i = 0;
222 
223     for(; i < colPositions.size(); i++) {
224       if(end == Integer.parseInt(colPositions.get(i))) {
225         counter++;
226         break;
227       }
228       counter++;
229     }
230 
231     return counter;
232   }
233 
234   /**
235    * From given an array of pattern annotations, this method finds out
236    * the annotations of the given type.
237    
238    @param annotations
239    @param type
240    @return
241    */
242   private static List<PatternAnnotation> findOutAnnotationsOfType(
243           PatternAnnotation[] annotations, String type) {
244     List<PatternAnnotation> annots = new ArrayList<PatternAnnotation>();
245     for(int i = 0; i < annotations.length; i++) {
246       if(annotations[i].getType().equals(type)) {
247         annots.add(annotations[i]);
248       }
249     }
250     return annots;
251   }
252 
253   private static int getColSpan(int startOffset, int endOffset,
254           List<String> colPositions) {
255     // given startOffset and endOffset
256     // we need to find out how many columns this particular annotations
257     // needs to span
258     int counter = 0;
259 
260     // lets find out the starting position
261     int i = 0;
262     for(; i < colPositions.size(); i++) {
263       if(Integer.parseInt(colPositions.get(i)) == startOffset) {
264         i++;
265         break;
266       }
267     }
268 
269     if(i == colPositions.size() || i < 0) {
270       // because this is the first annotation, it cannot satisfy the
271       // condition startOffset > colVal
272       // and therefore it simply reached here
273       // we will set it back to the 0
274       i = 0;
275     }
276 
277     // now we need to start the counter until we find out the end
278     // position
279     // in the col Positions
280     for(; i < colPositions.size(); i++) {
281       if(endOffset == Integer.parseInt(colPositions.get(i))) {
282         counter++;
283         break;
284       }
285       counter++;
286     }
287     return counter;
288   }
289 
290   private static List<String> getColsPositions(PatternAnnotation[] annotations) {
291     // the logic is:
292     // find out the unique number of endOffsets
293     List<String> offsets = new ArrayList<String>();
294     for(int i = 0; i < annotations.length; i++) {
295       int endOffset = annotations[i].getEndOffset();
296       int startOffset = annotations[i].getStartOffset();
297 
298       if(offsets.contains("" + endOffset)) {
299         // do nothing
300       }
301       else {
302         offsets.add("" + endOffset);
303       }
304 
305       if(offsets.contains("" + startOffset)) {
306         // do nothing
307       }
308       else {
309         offsets.add("" + startOffset);
310       }
311 
312     }
313     return offsets;
314   }
315 
316   /**
317    * This method return the unique rows. Each row refers to a different
318    * annotation type
319    
320    @param annotations
321    @return a list of string objects referring to the annotation types
322    */
323   private static List<String> getRowData(PatternAnnotation[] annotations) {
324     List<String> types = new ArrayList<String>();
325     for(int i = 0; i < annotations.length; i++) {
326       String type = annotations[i].getType();
327       if(types.contains(type))
328         continue;
329       else types.add(type);
330     }
331     return types;
332   }
333 
334   // this method takes the features of a particular annotations
335   // and returns the equivalent html code
336   private static String addFeatures(Map<String, String> features) {
337     String html = "<select size=\"1\" >";
338     Iterator<String> fIter = features.keySet().iterator();
339     while(fIter.hasNext()) {
340       String key = fIter.next();
341       String value = features.get(key).toString();
342       html += "\n" "<option>" + key + " = \"" + value + "\"</option>";
343     }
344     html += "\n" "</select>";
345     return html;
346   }
347 }