KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > core > util > PDETextHelper


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.pde.internal.core.util;
13
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.regex.Matcher JavaDoc;
18 import java.util.regex.Pattern JavaDoc;
19
20 /**
21  * PDETextHelper
22  *
23  */

24 public class PDETextHelper {
25
26     public static final String JavaDoc F_DOTS = "..."; //$NON-NLS-1$
27

28     /**
29      * @param text
30      * @return
31      */

32     public static String JavaDoc truncateAndTrailOffText(String JavaDoc text, int limit) {
33         String JavaDoc trimmed = text.trim();
34         int dotsLength = F_DOTS.length();
35         int trimmedLength = trimmed.length();
36         int limitWithDots = limit - dotsLength;
37         
38         if (limit >= trimmedLength) {
39             return trimmed;
40         }
41         // limit <= trimmedLength
42
if (limit <= dotsLength) {
43             return ""; //$NON-NLS-1$
44
}
45         // dotsLength < limit < trimmedLength
46
return trimmed.substring(0, limitWithDots) + F_DOTS;
47     }
48     
49     /**
50      * @param text
51      * @return
52      */

53     public static boolean isDefined(String JavaDoc text) {
54         if ((text == null) ||
55                 (text.length() == 0)) {
56             return false;
57         }
58         return true;
59     }
60
61     /**
62      * @param text
63      * @return
64      */

65     public static boolean isDefinedAfterTrim(String JavaDoc text) {
66         if (text == null) {
67             return false;
68         }
69         String JavaDoc trimmedText = text.trim();
70         if (trimmedText.length() == 0) {
71             return false;
72         }
73         return true;
74     }
75     
76     /**
77      * Strips \n, \r, \t
78      * Strips leading spaces, trailing spaces, duplicate spaces
79      * @param text
80      * @return never null
81      */

82     public static String JavaDoc translateReadText(String JavaDoc text) {
83         // Ensure not null
84
if (text == null) {
85             return ""; //$NON-NLS-1$
86
}
87         String JavaDoc result = ""; //$NON-NLS-1$
88
// Get rid of leading and trailing whitespace
89
String JavaDoc inputText = text.trim();
90         int length = inputText.length();
91         char previousChar = ' ';
92         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(length);
93         // Visit each character in text
94
for (int i = 0; i < length; i++) {
95             char currentChar = inputText.charAt(i);
96
97             if ((currentChar == '\r') || (currentChar == '\n') ||
98                     (currentChar == '\t')) {
99                 // Convert newlines, carriage returns and tabs to spaces
100
currentChar = ' ';
101             }
102             
103             if (currentChar == ' ') {
104                 // Skip multiple spaces
105
if (previousChar != ' ') {
106                     buffer.append(currentChar);
107                     previousChar = currentChar;
108                 }
109             } else {
110                 buffer.append(currentChar);
111                 previousChar = currentChar;
112             }
113         }
114         result = buffer.toString();
115         if (PDEHTMLHelper.isAllWhitespace(result)) {
116             return ""; //$NON-NLS-1$
117
}
118         return result;
119     }
120
121     /**
122      * @param text
123      * @param substituteChars
124      * @return
125      */

126     public static String JavaDoc translateWriteText(String JavaDoc text, HashMap JavaDoc substituteChars) {
127         return translateWriteText(text, null, substituteChars);
128     }
129     
130     /**
131      * @param text
132      * @param tagExceptions
133      * @param substituteChars
134      * @return
135      */

136     public static String JavaDoc translateWriteText(String JavaDoc text, HashSet JavaDoc tagExceptions,
137             HashMap JavaDoc substituteChars) {
138         // Ensure not null
139
if (text == null) {
140             return ""; //$NON-NLS-1$
141
}
142         // Process tag exceptions if provided
143
boolean processTagExceptions = false;
144         int scanLimit = 0;
145         if ((tagExceptions != null) &&
146                 (tagExceptions.isEmpty() == false)) {
147             processTagExceptions = true;
148             // Use the biggest entry in the set as the limit
149
scanLimit = determineMaxLength(tagExceptions);
150         }
151         // Process substitute characters if provided
152
boolean processSubstituteChars = false;
153         if ((substituteChars != null) &&
154                 (substituteChars.isEmpty() == false)) {
155             processSubstituteChars = true;
156         }
157         // Translated buffer
158
StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(text.length());
159         // Visit each character in text
160
for (IntegerPointer index = new IntegerPointer(0);
161                 index.getInteger() < text.length();
162                 index.increment()) {
163             // Process the current character
164
char currentChar = text.charAt(index.getInteger());
165             boolean processed = false;
166             // If we are processing tag exceptions, check to see if this
167
// character is part of a tag exception and process it accordingly
168
// if it is
169
if ((processed == false) &&
170                     (processTagExceptions == true)) {
171                 processed = processTagExceptions(currentChar, substituteChars,
172                         tagExceptions, buffer, scanLimit, text, index);
173             }
174             // If the character was not part of a tag exception and we are
175
// processing substitution characters, check to see if this
176
// character needs to be translated and process it accordingly if
177
// it is
178
if ((processed == false) &&
179                     (processSubstituteChars == true)) {
180                 processed = processSubstituteChars(currentChar, substituteChars,
181                         buffer);
182             }
183             // If the character did not need to be translated, just append it
184
// as is to the buffer
185
if (processed == false) {
186                 buffer.append(currentChar);
187             }
188         }
189         // Return the translated buffer
190
return buffer.toString();
191     }
192
193     /**
194      * @param currentChar
195      * @param substituteChars
196      * @param buffer
197      * @return
198      */

199     private static boolean processSubstituteChars(char currentChar,
200             HashMap JavaDoc substituteChars, StringBuffer JavaDoc buffer) {
201         Character JavaDoc character = new Character JavaDoc(currentChar);
202         if (substituteChars.containsKey(character)) {
203             String JavaDoc value = (String JavaDoc)substituteChars.get(character);
204             if (isDefined(value)) {
205                 // Append the value if defined
206
buffer.append(value);
207             }
208             // If the value was not defined, then we will strip the character
209
return true;
210         }
211         return false;
212     }
213     
214     /**
215      * @param currentChar
216      * @param tagExceptions
217      * @param buffer
218      * @param scanLimit
219      * @param inputText
220      * @param index
221      * @return
222      */

223     private static boolean processTagExceptions(char currentChar,
224             HashMap JavaDoc substituteChars, HashSet JavaDoc tagExceptions, StringBuffer JavaDoc buffer, int scanLimit,
225             String JavaDoc text, IntegerPointer index) {
226         // If the current character is an open angle bracket, then it may be
227
// part of a valid tag exception
228
if (currentChar == '<') {
229             // Determine whether this bracket is part of a tag that is a
230
// valid tag exception
231
// Respect character array boundaries. Adjust accordingly
232
int limit = text.length() + index.getInteger() + 2;
233             // Scan ahead buffer
234
StringBuffer JavaDoc parsedText = new StringBuffer JavaDoc();
235             // Scan ahead in text to parse out a possible element tag name
236
for (int j = index.getInteger() + 1; j < limit; j++) {
237                 char futureChar = text.charAt(j);
238                 if (futureChar == '>') {
239                     // An ending bracket was found
240
// This is indeed a element tag
241
// Determine if the element tag we found is a valid
242
// tag exception
243
String JavaDoc futureBuffer = parsedText.toString();
244                     if (isValidTagException(tagExceptions, futureBuffer)) {
245                         // The element tag is a valid tag exception
246
// Process the tag exception characters
247
processTagExceptionCharacters(substituteChars, buffer, futureBuffer);
248                         // Fast forward the current index to the scanned ahead
249
// index to skip what we just found
250
index.setInteger(j);
251                         return true;
252                     }
253                     return false;
254                 }
255                 // Accumulate the possible element tag name
256
parsedText.append(futureChar);
257             }
258         }
259         return false;
260     }
261     
262     /**
263      * @param substituteChars
264      * @param buffer
265      * @param text
266      */

267     private static void processTagExceptionCharacters(HashMap JavaDoc substituteChars, StringBuffer JavaDoc buffer, String JavaDoc text) {
268         // Get the tag name
269
String JavaDoc tagName = getTagName(text);
270         // Determine if there is a trailing forward slash
271
boolean trailingSlash = text.endsWith("/"); //$NON-NLS-1$
272
// Extract the attribute list of the element tag content
273
// It may contain trailing spaces or a trailing '/'
274
String JavaDoc attributeList = text.substring(tagName.length());
275         // If the attribute list is not valid, discard the attribute list
276
if ((isValidTagAttributeList(attributeList) == false)) {
277             buffer.append('<');
278             buffer.append(tagName);
279             // Since, this tag has an attribute list and we are discarding it,
280
// we have to make sure to replace the trailing slash if it had one
281
if (trailingSlash) {
282                 buffer.append('/');
283             }
284             buffer.append('>');
285             return;
286         } else if (attributeList.length() == 0) {
287             // If the tag has no attribute list then just return the tag
288
// as is (trailing slash is already including in the tag name)
289
buffer.append('<');
290             buffer.append(tagName);
291             buffer.append('>');
292             return;
293         }
294         boolean inQuote = false;
295         // Append the opening element bracket
296
buffer.append('<');
297         // Traverse the tag element content character by character
298
// Translate any substitution characters required only inside attribute
299
// value double-quotes
300
for (int i = 0; i < text.length(); i++) {
301             boolean processed = false;
302             char currentChar = text.charAt(i);
303             boolean onQuote = (currentChar == '"');
304             // Determine whether we are currently processing the quote character
305
if (onQuote) {
306                 if (inQuote) {
307                     // Quote encountered is an end quote
308
inQuote = false;
309                 } else {
310                     // Quote encountered is a begin quote
311
inQuote = true;
312                 }
313             }
314             // If we are currently within an attribute value double-quotes and
315
// not on a quote character, translate this character if necessary
316
if (inQuote && !onQuote) {
317                 processed = processSubstituteChars(currentChar, substituteChars,
318                         buffer);
319             }
320             // If the character did not require translation, just append it
321
// as-is
322
if (processed == false) {
323                 buffer.append(currentChar);
324             }
325         }
326         // Append the closing element bracket
327
buffer.append('>');
328     }
329     
330     /**
331      * @param tagExceptions
332      * @param buffer
333      * @return
334      */

335     private static boolean isValidTagException(HashSet JavaDoc tagExceptions, String JavaDoc buffer) {
336         // Sample buffer format:
337
// NO '<'
338
// tagName att1="value" att2="value"
339
// NO '>'
340
// Parse tag name and ignore attributes (if any specified)
341
String JavaDoc tagName = getTagName(buffer);
342         // Check to see if the tag name is a tag exception
343
if (tagExceptions.contains(tagName)) {
344             return true;
345         }
346         return false;
347     }
348     
349     /**
350      * @param text
351      * @return
352      */

353     private static boolean isValidTagAttributeList(String JavaDoc text) {
354         // Determine whether the given attribute list is formatted in the
355
// valid name="value" XML format
356
// Sample formats:
357
// " att1="value1" att2="value2"
358
// " att1="value1" att2="value2 /"
359
// " att1="value1"
360

361         // space attributeName space = space "attributeValue" space /
362
String JavaDoc patternString = "^([\\s]+[A-Za-z0-9_:\\-\\.]+[\\s]?=[\\s]?\".+?\")*[\\s]*[/]?$"; //$NON-NLS-1$
363
Pattern JavaDoc pattern = Pattern.compile(patternString);
364         Matcher JavaDoc matcher = pattern.matcher(text);
365         // Determine whether the given attribute list matches the pattern
366
return matcher.find();
367     }
368     
369     /**
370      * @param buffer
371      * @return
372      */

373     private static String JavaDoc getTagName(String JavaDoc buffer) {
374         // Sample buffer format:
375
// NO '<'
376
// tagName att1="value" att2="value"
377
// NO '>'
378
StringBuffer JavaDoc tagName = new StringBuffer JavaDoc();
379         // The tag name is every non-whitespace character in the buffer until
380
// a whitespace character is encountered
381
for (int i = 0; i < buffer.length(); i++) {
382             char character = buffer.charAt(i);
383             if (Character.isWhitespace(character)) {
384                 break;
385             }
386             tagName.append(character);
387         }
388         return tagName.toString();
389     }
390     
391     /**
392      * @param set
393      * @return
394      */

395     private static int determineMaxLength(HashSet JavaDoc set) {
396         Iterator JavaDoc iterator = set.iterator();
397         int maxLength = -1;
398         while (iterator.hasNext()) {
399             // Has to be a String
400
String JavaDoc object = (String JavaDoc)iterator.next();
401             if (object.length() > maxLength) {
402                 maxLength = object.length();
403             }
404         }
405         return maxLength;
406     }
407     
408     /**
409      * IntegerPointer
410      *
411      */

412     private static class IntegerPointer {
413
414         private int fInteger;
415         
416         /**
417          *
418          */

419         public IntegerPointer(int integer) {
420             fInteger = integer;
421         }
422         
423         /**
424          * @return
425          */

426         public int getInteger() {
427             return fInteger;
428         }
429         
430         /**
431          * @param integer
432          */

433         public void setInteger(int integer) {
434             fInteger = integer;
435         }
436         
437         /**
438          *
439          */

440         public void increment() {
441             fInteger++;
442         }
443     }
444     
445 }
446
Popular Tags