1 | /* | |
2 | * Copyright 2005 by Paulo Soares. | |
3 | * | |
4 | * The contents of this file are subject to the Mozilla Public License Version 1.1 | |
5 | * (the "License"); you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
7 | * | |
8 | * Software distributed under the License is distributed on an "AS IS" basis, | |
9 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
10 | * for the specific language governing rights and limitations under the License. | |
11 | * | |
12 | * The Original Code is 'iText, a free JAVA-PDF library'. | |
13 | * | |
14 | * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
15 | * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. | |
16 | * All Rights Reserved. | |
17 | * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
18 | * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. | |
19 | * | |
20 | * Contributor(s): all the names of the contributors are added in the source code | |
21 | * where applicable. | |
22 | * | |
23 | * Alternatively, the contents of this file may be used under the terms of the | |
24 | * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
25 | * provisions of LGPL are applicable instead of those above. If you wish to | |
26 | * allow use of your version of this file only under the terms of the LGPL | |
27 | * License and not to allow others to use your version of this file under | |
28 | * the MPL, indicate your decision by deleting the provisions above and | |
29 | * replace them with the notice and other provisions required by the LGPL. | |
30 | * If you do not delete the provisions above, a recipient may use your version | |
31 | * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
32 | * | |
33 | * This library is free software; you can redistribute it and/or modify it | |
34 | * under the terms of the MPL as stated above or under the terms of the GNU | |
35 | * Library General Public License as published by the Free Software Foundation; | |
36 | * either version 2 of the License, or any later version. | |
37 | * | |
38 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
39 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
40 | * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
41 | * details. | |
42 | * | |
43 | * Contributions by: | |
44 | * Lubos Strapko | |
45 | * | |
46 | * If you didn't download this code from the following link, you should check if | |
47 | * you aren't using an obsolete version: | |
48 | * http://www.lowagie.com/iText/ | |
49 | */ | |
50 | ||
51 | package com.lowagie.text.pdf.hyphenation; | |
52 | ||
53 | ||
54 | import com.lowagie.text.ExceptionConverter; | |
55 | import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; | |
56 | import com.lowagie.text.xml.simpleparser.SimpleXMLParser; | |
57 | ||
58 | import java.io.FileInputStream; | |
59 | import java.io.IOException; | |
60 | import java.io.InputStream; | |
61 | import java.util.ArrayList; | |
62 | import java.util.Map; | |
63 | import java.util.StringTokenizer; | |
64 | ||
65 | /** Parses the xml hyphenation pattern. | |
66 | * | |
67 | * @author Paulo Soares (psoares@consiste.pt) | |
68 | */ | |
69 | public class SimplePatternParser implements SimpleXMLDocHandler, | |
70 | PatternConsumer { | |
71 | int currElement; | |
72 | ||
73 | PatternConsumer consumer; | |
74 | ||
75 | StringBuffer token; | |
76 | ||
77 | ArrayList exception; | |
78 | ||
79 | char hyphenChar; | |
80 | ||
81 | SimpleXMLParser parser; | |
82 | ||
83 | static final int ELEM_CLASSES = 1; | |
84 | ||
85 | static final int ELEM_EXCEPTIONS = 2; | |
86 | ||
87 | static final int ELEM_PATTERNS = 3; | |
88 | ||
89 | static final int ELEM_HYPHEN = 4; | |
90 | ||
91 | /** Creates a new instance of PatternParser2 */ | |
92 | public SimplePatternParser() { | |
93 | token = new StringBuffer(); | |
94 | hyphenChar = '-'; // default | |
95 | } | |
96 | ||
97 | public void parse(InputStream stream, PatternConsumer consumer) { | |
98 | this.consumer = consumer; | |
99 | try { | |
100 |
1
1. parse : removed call to com/lowagie/text/xml/simpleparser/SimpleXMLParser::parse → NO_COVERAGE |
SimpleXMLParser.parse(this, stream); |
101 | } catch (IOException e) { | |
102 | throw new ExceptionConverter(e); | |
103 | } finally { | |
104 | try { | |
105 |
1
1. parse : removed call to java/io/InputStream::close → NO_COVERAGE |
stream.close(); |
106 | } catch (Exception e) { | |
107 | } | |
108 | } | |
109 | } | |
110 | ||
111 | protected static String getPattern(String word) { | |
112 | StringBuilder pat = new StringBuilder(); | |
113 | int len = word.length(); | |
114 |
3
1. getPattern : changed conditional boundary → NO_COVERAGE 2. getPattern : Changed increment from 1 to -1 → NO_COVERAGE 3. getPattern : negated conditional → NO_COVERAGE |
for (int i = 0; i < len; i++) { |
115 |
1
1. getPattern : negated conditional → NO_COVERAGE |
if (!Character.isDigit(word.charAt(i))) { |
116 | pat.append(word.charAt(i)); | |
117 | } | |
118 | } | |
119 |
1
1. getPattern : mutated return of Object value for com/lowagie/text/pdf/hyphenation/SimplePatternParser::getPattern to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return pat.toString(); |
120 | } | |
121 | ||
122 | protected ArrayList normalizeException(ArrayList ex) { | |
123 | ArrayList res = new ArrayList(); | |
124 | for (Object item : ex) { | |
125 |
1
1. normalizeException : negated conditional → NO_COVERAGE |
if (item instanceof String) { |
126 | String str = (String) item; | |
127 | StringBuilder buf = new StringBuilder(); | |
128 |
3
1. normalizeException : changed conditional boundary → NO_COVERAGE 2. normalizeException : Changed increment from 1 to -1 → NO_COVERAGE 3. normalizeException : negated conditional → NO_COVERAGE |
for (int j = 0; j < str.length(); j++) { |
129 | char c = str.charAt(j); | |
130 |
1
1. normalizeException : negated conditional → NO_COVERAGE |
if (c != hyphenChar) { |
131 | buf.append(c); | |
132 | } else { | |
133 | res.add(buf.toString()); | |
134 |
1
1. normalizeException : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
buf.setLength(0); |
135 | char[] h = new char[1]; | |
136 | h[0] = hyphenChar; | |
137 | // we use here hyphenChar which is not necessarily | |
138 | // the one to be printed | |
139 | res.add(new Hyphen(new String(h), null, null)); | |
140 | } | |
141 | } | |
142 |
2
1. normalizeException : changed conditional boundary → NO_COVERAGE 2. normalizeException : negated conditional → NO_COVERAGE |
if (buf.length() > 0) { |
143 | res.add(buf.toString()); | |
144 | } | |
145 | } else { | |
146 | res.add(item); | |
147 | } | |
148 | } | |
149 |
1
1. normalizeException : mutated return of Object value for com/lowagie/text/pdf/hyphenation/SimplePatternParser::normalizeException to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return res; |
150 | } | |
151 | ||
152 | protected String getExceptionWord(ArrayList ex) { | |
153 | StringBuilder res = new StringBuilder(); | |
154 | for (Object item : ex) { | |
155 |
1
1. getExceptionWord : negated conditional → NO_COVERAGE |
if (item instanceof String) { |
156 | res.append((String) item); | |
157 | } else { | |
158 |
1
1. getExceptionWord : negated conditional → NO_COVERAGE |
if (((Hyphen) item).noBreak != null) { |
159 | res.append(((Hyphen) item).noBreak); | |
160 | } | |
161 | } | |
162 | } | |
163 |
1
1. getExceptionWord : mutated return of Object value for com/lowagie/text/pdf/hyphenation/SimplePatternParser::getExceptionWord to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return res.toString(); |
164 | } | |
165 | ||
166 | protected static String getInterletterValues(String pat) { | |
167 | StringBuilder il = new StringBuilder(); | |
168 | String word = pat + "a"; // add dummy letter to serve as sentinel | |
169 | int len = word.length(); | |
170 |
3
1. getInterletterValues : changed conditional boundary → NO_COVERAGE 2. getInterletterValues : Changed increment from 1 to -1 → NO_COVERAGE 3. getInterletterValues : negated conditional → NO_COVERAGE |
for (int i = 0; i < len; i++) { |
171 | char c = word.charAt(i); | |
172 |
1
1. getInterletterValues : negated conditional → NO_COVERAGE |
if (Character.isDigit(c)) { |
173 | il.append(c); | |
174 |
1
1. getInterletterValues : Changed increment from 1 to -1 → NO_COVERAGE |
i++; |
175 | } else { | |
176 | il.append('0'); | |
177 | } | |
178 | } | |
179 |
1
1. getInterletterValues : mutated return of Object value for com/lowagie/text/pdf/hyphenation/SimplePatternParser::getInterletterValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return il.toString(); |
180 | } | |
181 | ||
182 | public void endDocument() { | |
183 | } | |
184 | ||
185 | public void endElement(String tag) { | |
186 |
2
1. endElement : changed conditional boundary → NO_COVERAGE 2. endElement : negated conditional → NO_COVERAGE |
if (token.length() > 0) { |
187 | String word = token.toString(); | |
188 | switch (currElement) { | |
189 | case ELEM_CLASSES: | |
190 |
1
1. endElement : removed call to com/lowagie/text/pdf/hyphenation/PatternConsumer::addClass → NO_COVERAGE |
consumer.addClass(word); |
191 | break; | |
192 | case ELEM_EXCEPTIONS: | |
193 | exception.add(word); | |
194 | exception = normalizeException(exception); | |
195 |
1
1. endElement : removed call to com/lowagie/text/pdf/hyphenation/PatternConsumer::addException → NO_COVERAGE |
consumer.addException(getExceptionWord(exception), |
196 | (ArrayList) exception.clone()); | |
197 | break; | |
198 | case ELEM_PATTERNS: | |
199 |
1
1. endElement : removed call to com/lowagie/text/pdf/hyphenation/PatternConsumer::addPattern → NO_COVERAGE |
consumer.addPattern(getPattern(word), |
200 | getInterletterValues(word)); | |
201 | break; | |
202 | case ELEM_HYPHEN: | |
203 | // nothing to do | |
204 | break; | |
205 | } | |
206 |
1
1. endElement : negated conditional → NO_COVERAGE |
if (currElement != ELEM_HYPHEN) { |
207 |
1
1. endElement : removed call to java/lang/StringBuffer::setLength → NO_COVERAGE |
token.setLength(0); |
208 | } | |
209 | } | |
210 |
1
1. endElement : negated conditional → NO_COVERAGE |
if (currElement == ELEM_HYPHEN) { |
211 | currElement = ELEM_EXCEPTIONS; | |
212 | } else { | |
213 | currElement = 0; | |
214 | } | |
215 | } | |
216 | ||
217 | public void startDocument() { | |
218 | } | |
219 | ||
220 | public void startElement(String tag, Map<String, String> h) { | |
221 | switch (tag) { | |
222 | case "hyphen-char": | |
223 | String hh = h.get("value"); | |
224 |
2
1. startElement : negated conditional → NO_COVERAGE 2. startElement : negated conditional → NO_COVERAGE |
if (hh != null && hh.length() == 1) { |
225 | hyphenChar = hh.charAt(0); | |
226 | } | |
227 | break; | |
228 | case "classes": | |
229 | currElement = ELEM_CLASSES; | |
230 | break; | |
231 | case "patterns": | |
232 | currElement = ELEM_PATTERNS; | |
233 | break; | |
234 | case "exceptions": | |
235 | currElement = ELEM_EXCEPTIONS; | |
236 | exception = new ArrayList(); | |
237 | break; | |
238 | case "hyphen": | |
239 |
2
1. startElement : changed conditional boundary → NO_COVERAGE 2. startElement : negated conditional → NO_COVERAGE |
if (token.length() > 0) { |
240 | exception.add(token.toString()); | |
241 | } | |
242 | exception.add(new Hyphen(h.get("pre"), h.get("no"), h.get("post"))); | |
243 | currElement = ELEM_HYPHEN; | |
244 | break; | |
245 | } | |
246 |
1
1. startElement : removed call to java/lang/StringBuffer::setLength → NO_COVERAGE |
token.setLength(0); |
247 | } | |
248 | ||
249 | public void text(String str) { | |
250 | StringTokenizer tk = new StringTokenizer(str); | |
251 |
1
1. text : negated conditional → NO_COVERAGE |
while (tk.hasMoreTokens()) { |
252 | String word = tk.nextToken(); | |
253 | // System.out.println("\"" + word + "\""); | |
254 | switch (currElement) { | |
255 | case ELEM_CLASSES: | |
256 |
1
1. text : removed call to com/lowagie/text/pdf/hyphenation/PatternConsumer::addClass → NO_COVERAGE |
consumer.addClass(word); |
257 | break; | |
258 | case ELEM_EXCEPTIONS: | |
259 | exception.add(word); | |
260 | exception = normalizeException(exception); | |
261 |
1
1. text : removed call to com/lowagie/text/pdf/hyphenation/PatternConsumer::addException → NO_COVERAGE |
consumer.addException(getExceptionWord(exception), |
262 | (ArrayList) exception.clone()); | |
263 |
1
1. text : removed call to java/util/ArrayList::clear → NO_COVERAGE |
exception.clear(); |
264 | break; | |
265 | case ELEM_PATTERNS: | |
266 |
1
1. text : removed call to com/lowagie/text/pdf/hyphenation/PatternConsumer::addPattern → NO_COVERAGE |
consumer.addPattern(getPattern(word), |
267 | getInterletterValues(word)); | |
268 | break; | |
269 | } | |
270 | } | |
271 | } | |
272 | ||
273 | // PatternConsumer implementation for testing purposes | |
274 | public void addClass(String c) { | |
275 |
1
1. addClass : removed call to java/io/PrintStream::println → NO_COVERAGE |
System.out.println("class: " + c); |
276 | } | |
277 | ||
278 | public void addException(String w, ArrayList e) { | |
279 |
1
1. addException : removed call to java/io/PrintStream::println → NO_COVERAGE |
System.out.println("exception: " + w + " : " + e.toString()); |
280 | } | |
281 | ||
282 | public void addPattern(String p, String v) { | |
283 |
1
1. addPattern : removed call to java/io/PrintStream::println → NO_COVERAGE |
System.out.println("pattern: " + p + " : " + v); |
284 | } | |
285 | ||
286 | public static void main(String[] args) { | |
287 | try { | |
288 |
2
1. main : changed conditional boundary → NO_COVERAGE 2. main : negated conditional → NO_COVERAGE |
if (args.length > 0) { |
289 | SimplePatternParser pp = new SimplePatternParser(); | |
290 |
1
1. main : removed call to com/lowagie/text/pdf/hyphenation/SimplePatternParser::parse → NO_COVERAGE |
pp.parse(new FileInputStream(args[0]), pp); |
291 | } | |
292 | } catch (Exception e) { | |
293 |
1
1. main : removed call to java/lang/Exception::printStackTrace → NO_COVERAGE |
e.printStackTrace(); |
294 | } | |
295 | } | |
296 | } | |
Mutations | ||
100 |
1.1 |
|
105 |
1.1 |
|
114 |
1.1 2.2 3.3 |
|
115 |
1.1 |
|
119 |
1.1 |
|
125 |
1.1 |
|
128 |
1.1 2.2 3.3 |
|
130 |
1.1 |
|
134 |
1.1 |
|
142 |
1.1 2.2 |
|
149 |
1.1 |
|
155 |
1.1 |
|
158 |
1.1 |
|
163 |
1.1 |
|
170 |
1.1 2.2 3.3 |
|
172 |
1.1 |
|
174 |
1.1 |
|
179 |
1.1 |
|
186 |
1.1 2.2 |
|
190 |
1.1 |
|
195 |
1.1 |
|
199 |
1.1 |
|
206 |
1.1 |
|
207 |
1.1 |
|
210 |
1.1 |
|
224 |
1.1 2.2 |
|
239 |
1.1 2.2 |
|
246 |
1.1 |
|
251 |
1.1 |
|
256 |
1.1 |
|
261 |
1.1 |
|
263 |
1.1 |
|
266 |
1.1 |
|
275 |
1.1 |
|
279 |
1.1 |
|
283 |
1.1 |
|
288 |
1.1 2.2 |
|
290 |
1.1 |
|
293 |
1.1 |