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