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  /***
19   * Info about text piece from textual node identified by nodeID.
20   * 
21   * @author Tomáš Studva 24.1.2006
22   */
23  public class TextPieceInfoImpl implements ITextPieceInfo {
24  
25      /***
26       * Id of text node from which text piece is.
27       */
28      private String nodeID;
29  
30      /***
31       * Holds text piece. Text piece is substring of text of textual node
32       * identified by nodeID starting at index offset.
33       */
34      private String text;
35  
36      /***
37       * Offset of first character in displayed text of text node.
38       */
39      private int offset;
40  
41      /***
42       * Offset of first character in original text of text node.
43       */
44      private int originalOffset;
45  
46      /***
47       * Constructor.
48       * 
49       * @param nodeID
50       *            id of text node of text piece
51       * @param offset
52       *            of first character in displayed text of text node
53       * @param originalOffset
54       *            offset of first character in original text of text node
55       * @param text
56       *            text from textual node with id nodeID and starting at position
57       *            offset
58       */
59      public TextPieceInfoImpl(String nodeID, int offset, int originalOffset,
60              String text) {
61          super();
62          this.nodeID = nodeID;
63          this.text = text;
64          this.offset = offset;
65          this.originalOffset = originalOffset;
66      }
67  
68      /***
69       * Returns id for text piece in this TextPieceInfo. Text piece id is unique
70       * identifier for substring of text of textual node from xml document. Id is
71       * build by adding offset and length to id of textual node containig this
72       * text. The id has format: id of node<offset, length>
73       * 
74       * @return text piece id : id of node<offset, length>
75       */
76      public String getID() {
77          return buildID(getNodeID(), getOffset(), getLength());
78      }
79  
80      /*
81       * (non-Javadoc)
82       * 
83       * @see sk.uniba.euromath.editor.TextPieceInfo#getNodeID()
84       */
85      public String getNodeID() {
86          return this.nodeID;
87      }
88  
89      /*
90       * (non-Javadoc)
91       * 
92       * @see sk.uniba.euromath.editor.TextPieceInfo#getOffset()
93       */
94      public int getOffset() {
95          return this.offset;
96      }
97  
98      /*
99       * (non-Javadoc)
100      * 
101      * @see sk.uniba.euromath.editor.textEditor.ITextPieceInfo#getLastIndex()
102      */
103     public int getLastIndex() {
104         return getOffset() + getLength() - 1;
105     }
106 
107     /*
108      * (non-Javadoc)
109      * 
110      * @see sk.uniba.euromath.editor.TextPieceInfo#getLength()
111      */
112     public int getLength() {
113         return getText().length();
114     }
115 
116     /*
117      * (non-Javadoc)
118      * 
119      * @see sk.uniba.euromath.editor.TextPieceInfo#getText()
120      */
121     public String getText() {
122         return this.text;
123     }
124 
125     /***
126      * Parses node id with multiplicity from id.
127      * 
128      * @param id
129      *            some id
130      * @return id of node
131      */
132     public static String getNodeID(String id) {
133         if (id.indexOf('<') > 0)
134             return id.substring(0, id.indexOf('<'));
135         return id;
136     }
137 
138     /***
139      * Parses node id without multiplicity - anything include and after ":" is
140      * omitted.
141      * 
142      * @param nodeId
143      *            id of node
144      * @return id without multiplicity
145      */
146     public static final String getParsedNodeId(String nodeId) {
147         if (nodeId.indexOf(':') > 0)
148             return nodeId.substring(0, nodeId.indexOf(':'));
149         return getNodeID(nodeId);
150     }
151 
152     /***
153      * Parses offset of text piece from text piece id. If id is not text piece
154      * id, IllegalArgumentException is thrown.
155      * 
156      * @param id
157      *            id of text piece
158      * @return offset of text piece
159      */
160     public static int getOffset(String id) {
161         if (id.indexOf('<') > 0)
162             try {
163                 return Integer.parseInt(id.substring(id.indexOf('<') + 1,
164                         id.indexOf(',')).trim());
165             } catch (NumberFormatException e) {
166                 throw new IllegalArgumentException(e);
167             }
168         throw new IllegalArgumentException();
169     }
170 
171     /***
172      * Parses length of text piece from text piece's id. If id is not text piece
173      * id, IllegalArgumentException is thrown.
174      * 
175      * @param id
176      *            id of text piece
177      * @return length of text piece
178      */
179     public static int getLength(String id) {
180         if (id.indexOf('<') > 0)
181             try {
182                 return Integer.parseInt(id.substring(id.indexOf(',') + 1,
183                         id.indexOf('>')).trim());
184             } catch (NumberFormatException e) {
185                 throw new IllegalArgumentException(e);
186             }
187         throw new IllegalArgumentException();
188     }
189 
190     /***
191      * @deprecated ak sa ti to hodi pouzit informuj STUDVU
192      * @param nodeID
193      *            id of text node
194      * @param offset
195      *            offset in text piece
196      * @return index of character from start of this text piece
197      */
198     @Deprecated
199     public int contains(String nodeID, int offset, int length) {
200         int result = -1;
201         if (getNodeID().equals(nodeID)) {
202             if ((offset >= getOffset())
203                     && (offset + length < getOffset() + getLength())) {
204                 return (offset - getOffset());
205             }
206         }
207         return result;
208     }
209 
210     /***
211      * True if parameter id is text piece/selection id, it means of form int<int,
212      * int>.
213      * 
214      * @param id
215      *            to examine
216      * 
217      * @return true if id is textpiece/selection id
218      */
219     public static boolean isTextPieceId(String id) {
220         // TODO Studva more precise
221         return (id.indexOf('<') > 0) && (id.indexOf('>') > 0);
222     }
223 
224     /***
225      * Static method to build text piece id from nodeID, offset and length.
226      * 
227      * @param nodeID
228      *            id of node of text piece
229      * @param offset
230      *            of first character in text of text node
231      * @param length
232      *            of text to identify
233      * @return nodeID<offset, length>
234      */
235     public static final String buildID(String nodeID, int offset, int length) {
236         return getParsedNodeId(nodeID) + "<" + offset + "," + length + ">"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
237     }
238 
239     /***
240      * Any text piece ids which are neighbour are joined together. Neighbour
241      * text piece ids are satisfiing these conditions: have same node id and
242      * offset + length - 1 == offset of second (where first ends, second
243      * starts).
244      * 
245      * @param ids
246      *            <b>text piece</b> ids to tidy up
247      */
248     public static void tidyUpIds(List<String> ids) {
249         Collections.sort(ids, new Comparator<String>() {
250 
251             // TODO GUI ako lepsie?
252             public int compare(String s1, String s2) {
253                 if (!isTextPieceId(s1) || !isTextPieceId(s2))
254                     throw new IllegalArgumentException(
255                             "All ids must be text piece ids."); //$NON-NLS-1$
256                 int nodeIdComparement = getParsedNodeId(s1).compareTo(
257                         getParsedNodeId(s2));
258                 if (nodeIdComparement != 0)
259                     return nodeIdComparement;
260                 int offset1 = getOffset(s1);
261                 int offset2 = getOffset(s2);
262                 if(offset1 < offset2)
263                     return -1;
264                 if(offset1 == offset2)
265                     return 0;
266                 if(offset1 > offset2)
267                     return 1;
268                 // newer occurs
269                 return 0;
270             }
271         });
272         String first, second;
273         for (int i = 0; i < ids.size() - 1; i++) {
274             first = ids.get(i);
275             second = ids.get(i + 1);
276             if ((getParsedNodeId(first) == getParsedNodeId(second))
277                     && (getOffset(first) + getLength(first) - 1 == getOffset(second))) {
278                 int length = getLength(first) + getLength(second);
279                 first = getParsedNodeId(first) + getOffset(first) + length;
280                 ids.set(i, first);
281                 ids.remove(i + 1);
282             }
283         }
284     }
285 
286     public int getOriginalOffset() {
287         return this.originalOffset;
288     }
289 }