View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics
3    * and Informatics, Comenius University, Bratislava. This file is protected by
4    * the Mozilla Public License version 1.1 (the License); you may not use this
5    * file except in compliance with the License. You may obtain a copy of the
6    * License at http://euromath2.sourceforge.net/license.html Unless required by
7    * applicable law or agreed to in writing, software distributed under the
8    * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
9    * OF ANY KIND, either express or implied. See the License for the specific
10   * language governing permissions and limitations under the License.
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                  // return buildID(getNodeID(), getOffset(), getLength());
80                  return "";
81          }
82  
83          /*
84           * (non-Javadoc)
85           * 
86           * @see sk.uniba.euromath.editor.TextPieceInfo#getNodeID()
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                 // TODO Studva more precise
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 + ">"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
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."); //$NON-NLS-1$
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                                 // newer occurs
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          * (non-Javadoc)
229          * 
230          * @see sk.uniba.euromath.editor.textEditor.ITextPieceInfo#getRenderedOffset()
231          */
232         public int getRenderedOffset() {
233                 return this.renderedOffset;
234         }
235 
236         /*
237          * (non-Javadoc)
238          * 
239          * @see sk.uniba.euromath.editor.textEditor.ITextPieceInfo#getRenderedText()
240          */
241         public String getRenderedText() {
242                 return this.keeper.getTextLocator().getText();
243         }
244 
245         /*
246          * (non-Javadoc)
247          * 
248          * @see sk.uniba.euromath.editor.textEditor.ITextPieceInfo#resolveRenderedIndex(int,
249          *      sk.uniba.euromath.document.XMLAccess)
250          */
251         public int resolveRenderedIndex(int indexInRenderedText,
252                         XMLAccess xmlAccess) {
253                 if ((indexInRenderedText < 0)
254                 // last valid index to resolve is text length
255                                 || (indexInRenderedText > getRenderedText()
256                                                 .length()))
257                         throw new IllegalArgumentException();
258                 return getKeeper().getTextContainer().resolveRenderedIndex(
259                                 getRenderedOffset() + indexInRenderedText,
260                                 xmlAccess);
261         }
262 
263         /*
264          * (non-Javadoc)
265          * 
266          * @see sk.uniba.euromath.editor.textEditor.ITextPieceInfo#getLastIndex()
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          * (non-Javadoc)
280          * 
281          * @see sk.uniba.euromath.editor.textEditor.ITextPieceInfo#getKeeper()
282          */
283         public ITextPieceKeeper getKeeper() {
284                 return this.keeper;
285         }
286 
287         public DomPointer getDomPointer(int charGapIndex, XMLAccess xmlAccess) {
288                 // resolve rendered offset to offset in original node's
289                 // text
290                 int originalOffset = keeper.getTextPieceInfo()
291                                 .resolveRenderedIndex(charGapIndex, xmlAccess);
292                 try {
293                         Node node = xmlAccess.getIDManager().getNode(
294                                         this.nodeID).item(0);
295                         // return pointer in node at index
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 }