blob: ab67ed5bdf8feb0666dd22588b5eeee9e4e1a1f6 [file] [log] [blame]
Nils Diewaldff0f8742015-02-26 20:42:45 +00001package de.ids_mannheim.korap.response.match;
Nils Diewald79f6c4d2014-09-17 17:34:01 +00002
3import org.apache.lucene.util.FixedBitSet;
Nils Diewald392bcf32015-02-26 20:01:17 +00004import de.ids_mannheim.korap.response.Match;
Nils Diewaldff0f8742015-02-26 20:42:45 +00005import de.ids_mannheim.korap.response.match.Relation;
Nils Diewaldfe6a3652015-02-05 20:34:27 +00006import static de.ids_mannheim.korap.util.KorapString.*;
Nils Diewald79f6c4d2014-09-17 17:34:01 +00007import 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) {
Nils Diewaldff0f8742015-02-26 20:42:45 +000027 this.type = type;
28 this.number = number;
Nils Diewald79f6c4d2014-09-17 17:34:01 +000029 };
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) {
Nils Diewaldff0f8742015-02-26 20:42:45 +000035 this.type = type;
36 this.number = number;
37 this.terminal = terminal;
Nils Diewald79f6c4d2014-09-17 17:34:01 +000038 };
39
40 // Constructor for textual data
41 public HighlightCombinatorElement (String characters) {
Nils Diewaldff0f8742015-02-26 20:42:45 +000042 this.type = (byte) 0;
43 this.characters = characters;
Nils Diewald79f6c4d2014-09-17 17:34:01 +000044 };
45
46 // Return html fragment for this combinator element
Nils Diewald392bcf32015-02-26 20:01:17 +000047 public String toHTML (Match match, FixedBitSet level, byte[] levelCache) {
Nils Diewalddcd5ab12015-02-20 02:59:09 +000048 // Opening
49 if (this.type == 1) {
50 StringBuilder sb = new StringBuilder();
51 if (this.number == -1) {
52 sb.append("<mark>");
53 }
Nils Diewald79f6c4d2014-09-17 17:34:01 +000054
Nils Diewalddcd5ab12015-02-20 02:59:09 +000055 else if (this.number < -1) {
56 sb.append("<span xml:id=\"")
57 .append(match.getPosID(match.getClassID(this.number)))
58 .append("\">");
59 }
Nils Diewaldff0f8742015-02-26 20:42:45 +000060
Nils Diewalddcd5ab12015-02-20 02:59:09 +000061 else if (this.number >= 256) {
62 sb.append("<span ");
63 if (this.number < 2048) {
64 sb.append("title=\"")
65 .append(match.getAnnotationID(this.number))
66 .append('"');
67 }
68 else {
69 Relation rel = match.getRelationID(this.number);
70 sb.append("xlink:title=\"")
71 .append(rel.annotation)
72 .append("\" xlink:type=\"simple\" xlink:href=\"#")
73 .append(match.getPosID(rel.ref))
74 .append('"');
75 };
76 sb.append('>');
77 }
Nils Diewald52bd1cd2014-11-06 20:44:24 +000078
Nils Diewalddcd5ab12015-02-20 02:59:09 +000079 // Highlight - < 256
80 else {
81 // Get the first free level slot
82 byte pos;
83 if (levelCache[this.number] != '\0') {
84 pos = levelCache[this.number];
85 }
86 else {
87 pos = (byte) level.nextSetBit(0);
88 level.clear(pos);
89 levelCache[this.number] = pos;
90 };
91 sb.append("<mark class=\"class-")
92 .append(this.number)
93 .append(" level-")
94 .append(pos)
95 .append("\">");
96 };
97 return sb.toString();
98 }
99 // Closing
100 else if (this.type == 2) {
101 if (this.number < -1 || this.number >= 256)
102 return "</span>";
103
104 if (this.number == -1)
105 return "</mark>";
106
107 if (this.terminal)
108 level.set((int) levelCache[this.number]);
109 return "</mark>";
Nils Diewald79f6c4d2014-09-17 17:34:01 +0000110 };
111
112 // HTML encode primary data
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000113 return escapeHTML(this.characters);
Nils Diewald79f6c4d2014-09-17 17:34:01 +0000114 };
115
116 // Return bracket fragment for this combinator element
Nils Diewald392bcf32015-02-26 20:01:17 +0000117 public String toBrackets (Match match) {
Nils Diewald79f6c4d2014-09-17 17:34:01 +0000118 if (this.type == 1) {
119 StringBuilder sb = new StringBuilder();
120
121 // Match
122 if (this.number == -1) {
123 sb.append("[");
124 }
125
126 // Identifier
127 else if (this.number < -1) {
128 sb.append("{#");
129 sb.append(match.getClassID(this.number));
130 sb.append(':');
131 }
132
133 // Highlight, Relation, Span
134 else {
135 sb.append("{");
136 if (this.number >= 256) {
137 if (this.number < 2048)
138 sb.append(match.getAnnotationID(this.number));
139 else {
140 Relation rel = match.getRelationID(this.number);
141 sb.append(rel.annotation);
142 sb.append('>').append(rel.ref);
143 };
144 sb.append(':');
145 }
146 else if (this.number != 0)
147 sb.append(this.number).append(':');
148 };
149 return sb.toString();
150 }
151 else if (this.type == 2) {
152 if (this.number == -1)
153 return "]";
154 return "}";
155 };
156 return this.characters;
157 };
158};