1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor.textEditor;
13
14 import java.util.Collections;
15 import java.util.Comparator;
16 import java.util.List;
17
18 import org.eclipse.core.runtime.IStatus;
19 import org.w3c.dom.DOMException;
20 import org.w3c.dom.Node;
21
22 import sk.baka.ikslibs.ptr.DomPointer;
23 import sk.baka.ikslibs.ptr.DomPointerFactory;
24 import sk.uniba.euromath.EuroMath;
25 import sk.uniba.euromath.document.XMLAccess;
26
27 /***
28 * Info about text piece from textual node identified by nodeID.
29 *
30 * @author Tomáš Studva 24.1.2006
31 */
32 public class TextPieceInfoImpl implements ITextPieceInfo {
33
34 /***
35 * Associated keeper.
36 */
37 private final ITextPieceKeeper keeper;
38
39 /***
40 * Id of text node from which text piece is.
41 */
42 private String nodeID;
43
44 /***
45 * Offset of first character in displayed text of text node.
46 */
47 private int renderedOffset;
48
49 /***
50 * Constructor.
51 *
52 * @param nodeID
53 * id of text node of text piece
54 * @param offset
55 * of first character in rendered text of text node
56 *
57 * @param renderedText
58 * rendered text
59 */
60 public TextPieceInfoImpl(ITextPieceKeeper keeper, String nodeID,
61 int renderedOffset) {
62 super();
63 this.keeper = keeper;
64 this.nodeID = nodeID;
65 this.renderedOffset = renderedOffset;
66 }
67
68 /***
69 * Returns id for text piece in this TextPieceInfo. Text piece id is
70 * unique identifier for substring of text of textual node from xml
71 * document. Id is build by adding offset and length to id of textual
72 * node containig this text. The id has format: id of node<offset,
73 * length>
74 *
75 * @return text piece id : id of node<offset, length>
76 * @deprecated
77 */
78 public String getID() {
79
80 return "";
81 }
82
83
84
85
86
87
88 public String getNodeID() {
89 return this.nodeID;
90 }
91
92 /***
93 * Parses node id with multiplicity from id.
94 *
95 * @param id
96 * some id
97 * @return id of node
98 * @deprecated
99 */
100 public static String getNodeID(String id) {
101 if (id.indexOf('<') > 0)
102 return id.substring(0, id.indexOf('<'));
103 return id;
104 }
105
106 /***
107 * Parses offset of text piece from text piece id. If id is not text
108 * piece id, IllegalArgumentException is thrown.
109 *
110 * @param id
111 * id of text piece
112 * @return offset of text piece
113 * @deprecated
114 */
115 public static int getOffset(String id) {
116 if (id.indexOf('<') > 0)
117 try {
118 return Integer.parseInt(id.substring(
119 id.indexOf('<') + 1,
120 id.indexOf(',')).trim());
121 } catch (NumberFormatException e) {
122 throw new IllegalArgumentException(e);
123 }
124 throw new IllegalArgumentException();
125 }
126
127 /***
128 * Parses length of text piece from text piece's id. If id is not text
129 * piece id, IllegalArgumentException is thrown.
130 *
131 * @param id
132 * id of text piece
133 * @return length of text piece
134 * @deprecated
135 */
136 public static int getLength(String id) {
137 if (id.indexOf('<') > 0)
138 try {
139 return Integer.parseInt(id.substring(
140 id.indexOf(',') + 1,
141 id.indexOf('>')).trim());
142 } catch (NumberFormatException e) {
143 throw new IllegalArgumentException(e);
144 }
145 throw new IllegalArgumentException();
146 }
147
148 /***
149 * True if parameter id is text piece/selection id, it means of form int<int,
150 * int>.
151 *
152 * @param id
153 * to examine
154 *
155 * @return true if id is textpiece/selection id
156 * @deprecated
157 */
158 public static boolean isTextPieceId(String id) {
159
160 return (id.indexOf('<') > 0) && (id.indexOf('>') > 0);
161 }
162
163 /***
164 * Static method to build text piece id from nodeID, offset and length.
165 *
166 * @param nodeID
167 * id of node of text piece
168 * @param offset
169 * of first character in text of text node
170 * @param length
171 * of text to identify
172 * @return nodeID<offset, length>
173 * @deprecated
174 */
175 public static final String buildID(String nodeID, int offset, int length) {
176 return nodeID + "<" + offset + "," + length + ">";
177 }
178
179 /***
180 * Any text piece ids which are neighbour are joined together. Neighbour
181 * text piece ids are satisfiing these conditions: have same node id and
182 * offset + length - 1 == offset of second (where first ends, second
183 * starts).
184 *
185 * @param ids
186 * <b>text piece</b> ids to tidy up
187 * @deprecated
188 */
189 public static void tidyUpIds(List<String> ids) {
190 Collections.sort(ids, new Comparator<String>() {
191
192 public int compare(String s1, String s2) {
193 if (!isTextPieceId(s1) || !isTextPieceId(s2))
194 throw new IllegalArgumentException(
195 "All ids must be text piece ids.");
196 int nodeIdComparement = s1.compareTo(s2);
197 if (nodeIdComparement != 0)
198 return nodeIdComparement;
199 int offset1 = getOffset(s1);
200 int offset2 = getOffset(s2);
201 if (offset1 < offset2)
202 return -1;
203 if (offset1 == offset2)
204 return 0;
205 if (offset1 > offset2)
206 return 1;
207
208 return 0;
209 }
210 });
211 String first, second;
212 for (int i = 0; i < ids.size() - 1; i++) {
213 first = ids.get(i);
214 second = ids.get(i + 1);
215 if ((first == second)
216 && (getOffset(first) + getLength(first)
217 - 1 == getOffset(second))) {
218 int length = getLength(first)
219 + getLength(second);
220 first = first + getOffset(first) + length;
221 ids.set(i, first);
222 ids.remove(i + 1);
223 }
224 }
225 }
226
227
228
229
230
231
232 public int getRenderedOffset() {
233 return this.renderedOffset;
234 }
235
236
237
238
239
240
241 public String getRenderedText() {
242 return this.keeper.getTextLocator().getText();
243 }
244
245
246
247
248
249
250
251 public int resolveRenderedIndex(int indexInRenderedText,
252 XMLAccess xmlAccess) {
253 if ((indexInRenderedText < 0)
254
255 || (indexInRenderedText > getRenderedText()
256 .length()))
257 throw new IllegalArgumentException();
258 return getKeeper().getTextContainer().resolveRenderedIndex(
259 getRenderedOffset() + indexInRenderedText,
260 xmlAccess);
261 }
262
263
264
265
266
267
268 public int getLastIndex() {
269 return getRenderedText().length() - 1;
270 }
271
272 @Override
273 public String toString() {
274 return "TextPieceinfoImpl[id: " + this.nodeID + ", text: "
275 + getRenderedText() + "]";
276 }
277
278
279
280
281
282
283 public ITextPieceKeeper getKeeper() {
284 return this.keeper;
285 }
286
287 public DomPointer getDomPointer(int charGapIndex, XMLAccess xmlAccess) {
288
289
290 int originalOffset = keeper.getTextPieceInfo()
291 .resolveRenderedIndex(charGapIndex, xmlAccess);
292 try {
293 Node node = xmlAccess.getIDManager().getNode(
294 this.nodeID).item(0);
295
296 return DomPointerFactory.create(node, originalOffset);
297 } catch (DOMException e) {
298 EuroMath.log(IStatus.ERROR, 0,
299 "Invalid state of Euromath.", e);
300 throw new IllegalStateException();
301 }
302 }
303 }