blob: 036e244320e36d9acfd351ff9580062d7cee9775 [file] [log] [blame]
Nils Diewald79f6c4d2014-09-17 17:34:01 +00001package de.ids_mannheim.korap.match;
2
3import org.apache.lucene.util.FixedBitSet;
4import de.ids_mannheim.korap.KorapMatch;
5import de.ids_mannheim.korap.match.Relation;
6import static de.ids_mannheim.korap.util.KorapHTML.*;
7import java.util.*;
8import java.io.*;
9
10/*
11 Class for elements with highlighting information
12*/
13public class HighlightCombinatorElement {
14
15 // Type 0: Textual data
16 // Type 1: Opening
17 // Type 2: Closing
18 public byte type;
19
20 public int number = 0;
21
22 public String characters;
23 public boolean terminal = true;
24
25 // Constructor for highlighting elements
26 public HighlightCombinatorElement (byte type, int number) {
27 this.type = type;
28 this.number = number;
29 };
30
31 // Constructor for highlighting elements,
32 // that may not be terminal, i.e. they were closed and will
33 // be reopened for overlapping issues.
34 public HighlightCombinatorElement (byte type, int number, boolean terminal) {
35 this.type = type;
36 this.number = number;
37 this.terminal = terminal;
38 };
39
40 // Constructor for textual data
41 public HighlightCombinatorElement (String characters) {
42 this.type = (byte) 0;
43 this.characters = characters;
44 };
45
46 // Return html fragment for this combinator element
47 public String toHTML (KorapMatch match, FixedBitSet level, byte[] levelCache) {
48 // Opening
49 if (this.type == 1) {
50 StringBuilder sb = new StringBuilder();
51 if (this.number == -1) {
52 sb.append("<span class=\"match\">");
53 }
54
55 else if (this.number < -1) {
56 sb.append("<span xml:id=\"")
57 .append(match.getPosID(
58 match.getClassID(this.number)))
59 .append("\">");
60 }
61
62 else if (this.number >= 256) {
63 sb.append("<span ");
64 if (this.number < 2048) {
65 sb.append("title=\"")
66 .append(match.getAnnotationID(this.number))
67 .append('"');
68 }
69 else {
70 Relation rel = match.getRelationID(this.number);
71 sb.append("xlink:title=\"")
72 .append(rel.annotation)
73 .append("\" xlink:type=\"simple\" xlink:href=\"#")
74 .append(match.getPosID(rel.ref))
75 .append('"');
76 };
77 sb.append('>');
78 }
79 else {
80 // Get the first free level slot
81 byte pos;
82 if (levelCache[this.number] != '\0') {
83 pos = levelCache[this.number];
84 }
85 else {
86 pos = (byte) level.nextSetBit(0);
87 level.clear(pos);
88 levelCache[this.number] = pos;
89 };
90 sb.append("<em class=\"class-")
91 .append(this.number)
92 .append(" level-")
93 .append(pos)
94 .append("\">");
95 };
96 return sb.toString();
97 }
98 // Closing
99 else if (this.type == 2) {
100 if (this.number <= -1 || this.number >= 256)
101 return "</span>";
102
103 if (this.terminal)
104 level.set((int) levelCache[this.number]);
105 return "</em>";
106 };
107
108 // HTML encode primary data
109 return encodeHTML(this.characters);
110 };
111
112 // Return bracket fragment for this combinator element
113 public String toBrackets (KorapMatch match) {
114 if (this.type == 1) {
115 StringBuilder sb = new StringBuilder();
116
117 // Match
118 if (this.number == -1) {
119 sb.append("[");
120 }
121
122 // Identifier
123 else if (this.number < -1) {
124 sb.append("{#");
125 sb.append(match.getClassID(this.number));
126 sb.append(':');
127 }
128
129 // Highlight, Relation, Span
130 else {
131 sb.append("{");
132 if (this.number >= 256) {
133 if (this.number < 2048)
134 sb.append(match.getAnnotationID(this.number));
135 else {
136 Relation rel = match.getRelationID(this.number);
137 sb.append(rel.annotation);
138 sb.append('>').append(rel.ref);
139 };
140 sb.append(':');
141 }
142 else if (this.number != 0)
143 sb.append(this.number).append(':');
144 };
145 return sb.toString();
146 }
147 else if (this.type == 2) {
148 if (this.number == -1)
149 return "]";
150 return "}";
151 };
152 return this.characters;
153 };
154};