List.java

1
/*
2
 * $Id: List.java 3373 2008-05-12 16:21:24Z xlv $
3
 *
4
 * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * (the "License"); you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the License.
13
 *
14
 * The Original Code is 'iText, a free JAVA-PDF library'.
15
 *
16
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17
 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18
 * All Rights Reserved.
19
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20
 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21
 *
22
 * Contributor(s): all the names of the contributors are added in the source code
23
 * where applicable.
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of the
26
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27
 * provisions of LGPL are applicable instead of those above.  If you wish to
28
 * allow use of your version of this file only under the terms of the LGPL
29
 * License and not to allow others to use your version of this file under
30
 * the MPL, indicate your decision by deleting the provisions above and
31
 * replace them with the notice and other provisions required by the LGPL.
32
 * If you do not delete the provisions above, a recipient may use your version
33
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34
 *
35
 * This library is free software; you can redistribute it and/or modify it
36
 * under the terms of the MPL as stated above or under the terms of the GNU
37
 * Library General Public License as published by the Free Software Foundation;
38
 * either version 2 of the License, or any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful, but WITHOUT
41
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43
 * details.
44
 *
45
 * If you didn't download this code from the following link, you should check if
46
 * you aren't using an obsolete version:
47
 * http://www.lowagie.com/iText/
48
 */
49
50
package com.lowagie.text;
51
52
import java.util.ArrayList;
53
54
import com.lowagie.text.factories.RomanAlphabetFactory;
55
56
/**
57
 * A <CODE>List</CODE> contains several <CODE>ListItem</CODE>s.
58
 * <P>
59
 * <B>Example 1:</B>
60
 * <BLOCKQUOTE><PRE>
61
 * <STRONG>List list = new List(true, 20);</STRONG>
62
 * <STRONG>list.add(new ListItem("First line"));</STRONG>
63
 * <STRONG>list.add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));</STRONG>
64
 * <STRONG>list.add(new ListItem("Third line"));</STRONG>
65
 * </PRE></BLOCKQUOTE>
66
 *
67
 * The result of this code looks like this:
68
 *    <OL>
69
 *        <LI>
70
 *            First line
71
 *        </LI>
72
 *        <LI>
73
 *            The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?
74
 *        </LI>
75
 *        <LI>
76
 *            Third line
77
 *        </LI>
78
 *    </OL>
79
 *
80
 * <B>Example 2:</B>
81
 * <BLOCKQUOTE><PRE>
82
 * <STRONG>List overview = new List(false, 10);</STRONG>
83
 * <STRONG>overview.add(new ListItem("This is an item"));</STRONG>
84
 * <STRONG>overview.add("This is another item");</STRONG>
85
 * </PRE></BLOCKQUOTE>
86
 *
87
 * The result of this code looks like this:
88
 *    <UL>
89
 *        <LI>
90
 *            This is an item
91
 *        </LI>
92
 *        <LI>
93
 *            This is another item
94
 *        </LI>
95
 *    </UL>
96
 *
97
 * @see        Element
98
 * @see        ListItem
99
 */
100
101
public class List implements TextElementArray {
102
    
103
    // constants
104
    
105
    /** a possible value for the numbered parameter */
106
    public static final boolean ORDERED = true;
107
    /** a possible value for the numbered parameter */
108
    public static final boolean UNORDERED = false;
109
    /** a possible value for the lettered parameter */
110
    public static final boolean NUMERICAL = false;
111
    /** a possible value for the lettered parameter */
112
    public static final boolean ALPHABETICAL = true;
113
    /** a possible value for the lettered parameter */
114
    public static final boolean UPPERCASE = false;
115
    /** a possible value for the lettered parameter */
116
    public static final boolean LOWERCASE = true;
117
    
118
    // member variables
119
    
120
    /** This is the <CODE>ArrayList</CODE> containing the different <CODE>ListItem</CODE>s. */
121
    protected ArrayList list = new ArrayList();
122
    
123
    /** Indicates if the list has to be numbered. */
124
    protected boolean numbered = false;
125
    /** Indicates if the listsymbols are numerical or alphabetical. */
126
    protected boolean lettered = false;
127
    /** Indicates if the listsymbols are lowercase or uppercase. */
128
    protected boolean lowercase = false;
129
    /** Indicates if the indentation has to be set automatically. */
130
    protected boolean autoindent = false;
131
    /** Indicates if the indentation of all the items has to be aligned. */
132
    protected boolean alignindent = false;
133
    
134
    /** This variable indicates the first number of a numbered list. */
135
    protected int first = 1;
136
    /** This is the listsymbol of a list that is not numbered. */
137
    protected Chunk symbol = new Chunk("- ");
138
    /**
139
     * In case you are using numbered/lettered lists, this String is added before the number/letter.
140
     * @since    iText 2.1.1
141
     */
142
    protected String preSymbol = "";
143
    /**
144
     * In case you are using numbered/lettered lists, this String is added after the number/letter.    
145
     * @since    iText 2.1.1
146
     */
147
    protected String postSymbol = ". ";
148
    
149
    /** The indentation of this list on the left side. */
150
    protected float indentationLeft = 0;
151
    /** The indentation of this list on the right side. */
152
    protected float indentationRight = 0;
153
    /** The indentation of the listitems. */
154
    protected float symbolIndent = 0;
155
    
156
    // constructors
157
158
    /** Constructs a <CODE>List</CODE>. */
159
    public List() {
160
        this(false, false);
161
    }
162
    
163
    /**
164
     * Constructs a <CODE>List</CODE> with a specific symbol indentation.
165
     * @param    symbolIndent    the symbol indentation
166
     * @since    iText 2.0.8
167
     */
168
    public List(float symbolIndent) {
169
        this.symbolIndent = symbolIndent;
170
    }
171
    
172
    /**
173
     * Constructs a <CODE>List</CODE>.
174
     * @param    numbered        a boolean
175
     */
176
    public List(boolean numbered) {
177
          this(numbered, false);
178
    }
179
        
180
    /**
181
     * Constructs a <CODE>List</CODE>.
182
     * @param    numbered        a boolean
183
     * @param lettered has the list to be 'numbered' with letters
184
     */
185
    public List(boolean numbered, boolean lettered) {
186
        this.numbered = numbered;
187
        this.lettered = lettered;
188
        this.autoindent = true;
189
        this.alignindent = true;
190
    }
191
    
192
    /**
193
     * Constructs a <CODE>List</CODE>.
194
     * <P>
195
     * Remark: the parameter <VAR>symbolIndent</VAR> is important for instance when
196
     * generating PDF-documents; it indicates the indentation of the listsymbol.
197
     * It is not important for HTML-documents.
198
     *
199
     * @param    numbered        a boolean
200
     * @param    symbolIndent    the indentation that has to be used for the listsymbol
201
     */
202
    public List(boolean numbered, float symbolIndent) {
203
        this(numbered, false, symbolIndent);
204
    }
205
    
206
    /**
207
     * Creates a list
208
     * @param numbered has the list to be numbered?
209
     * @param lettered has the list to be 'numbered' with letters
210
     * @param symbolIndent the indentation of the symbol
211
     */
212
    public List(boolean numbered, boolean lettered, float symbolIndent) {
213
        this.numbered = numbered;
214
        this.lettered = lettered;
215
        this.symbolIndent = symbolIndent;
216
    }
217
    
218
    // implementation of the Element-methods
219
    
220
    /**
221
     * Processes the element by adding it (or the different parts) to an
222
     * <CODE>ElementListener</CODE>.
223
     *
224
     * @param    listener    an <CODE>ElementListener</CODE>
225
     * @return    <CODE>true</CODE> if the element was processed successfully
226
     */
227
    public boolean process(ElementListener listener) {
228
        try {
229
            for (Object o : list) {
230
                listener.add((Element) o);
231
            }
232 1 1. process : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return true;
233
        }
234
        catch(DocumentException de) {
235 1 1. process : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return false;
236
        }
237
    }
238
    
239
    /**
240
     * Gets the type of the text element.
241
     *
242
     * @return    a type
243
     */
244
    public int type() {
245
        return Element.LIST;
246
    }
247
    
248
    /**
249
     * Gets all the chunks in this element.
250
     *
251
     * @return    an <CODE>ArrayList</CODE>
252
     */
253
    public ArrayList getChunks() {
254
        ArrayList tmp = new ArrayList();
255
        for (Object o : list) {
256
            tmp.addAll(((Element) o).getChunks());
257
        }
258 1 1. getChunks : mutated return of Object value for com/lowagie/text/List::getChunks to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return tmp;
259
    }
260
    
261
    // methods to set the membervariables
262
    
263
    /**
264
     * Adds an <CODE>Object</CODE> to the <CODE>List</CODE>.
265
     *
266
     * @param    o        the object to add.
267
     * @return true if adding the object succeeded
268
     */
269
    public boolean add(Object o) {
270 1 1. add : negated conditional → NO_COVERAGE
        if (o instanceof ListItem) {
271
            ListItem item = (ListItem) o;
272 2 1. add : negated conditional → NO_COVERAGE
2. add : negated conditional → NO_COVERAGE
            if (numbered || lettered) {
273
                Chunk chunk = new Chunk(preSymbol, symbol.getFont());
274 1 1. add : Replaced integer addition with subtraction → NO_COVERAGE
                int index = first + list.size();
275 1 1. add : negated conditional → NO_COVERAGE
                if ( lettered )
276
                    chunk.append(RomanAlphabetFactory.getString(index, lowercase));
277
                else
278
                    chunk.append(String.valueOf(index));
279
                chunk.append(postSymbol);
280 1 1. add : removed call to com/lowagie/text/ListItem::setListSymbol → NO_COVERAGE
                item.setListSymbol(chunk);
281
            }
282
            else {
283 1 1. add : removed call to com/lowagie/text/ListItem::setListSymbol → NO_COVERAGE
                item.setListSymbol(symbol);
284
            }
285 1 1. add : removed call to com/lowagie/text/ListItem::setIndentationLeft → NO_COVERAGE
            item.setIndentationLeft(symbolIndent, autoindent);
286 1 1. add : removed call to com/lowagie/text/ListItem::setIndentationRight → NO_COVERAGE
            item.setIndentationRight(0);
287 1 1. add : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return list.add(item);
288
        }
289 1 1. add : negated conditional → NO_COVERAGE
        else if (o instanceof List) {
290
            List nested = (List) o;
291 2 1. add : Replaced float addition with subtraction → NO_COVERAGE
2. add : removed call to com/lowagie/text/List::setIndentationLeft → NO_COVERAGE
            nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent);
292 1 1. add : Replaced integer subtraction with addition → NO_COVERAGE
            first--;
293 1 1. add : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return list.add(nested);
294
        }
295 1 1. add : negated conditional → NO_COVERAGE
        else if (o instanceof String) {
296 1 1. add : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return this.add(new ListItem((String) o));
297
        }
298 1 1. add : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return false;
299
    }
300
    
301
    // extra methods
302
    
303
    /** Makes sure all the items in the list have the same indentation. */
304
    public void normalizeIndentation() {
305
        float max = 0;
306
        Element o;
307
        for (Object o2 : list) {
308
            o = (Element) o2;
309 1 1. normalizeIndentation : negated conditional → NO_COVERAGE
            if (o instanceof ListItem) {
310
                max = Math.max(max, ((ListItem) o).getIndentationLeft());
311
            }
312
        }
313
        for (Object o1 : list) {
314
            o = (Element) o1;
315 1 1. normalizeIndentation : negated conditional → NO_COVERAGE
            if (o instanceof ListItem) {
316 1 1. normalizeIndentation : removed call to com/lowagie/text/ListItem::setIndentationLeft → NO_COVERAGE
                ((ListItem) o).setIndentationLeft(max);
317
            }
318
        }
319
    }
320
    
321
    // setters
322
323
    /**
324
     * @param numbered the numbered to set
325
     */
326
    public void setNumbered(boolean numbered) {
327
        this.numbered = numbered;
328
    }
329
330
    /**
331
     * @param lettered the lettered to set
332
     */
333
    public void setLettered(boolean lettered) {
334
        this.lettered = lettered;
335
    }
336
337
    /**
338
     * @param uppercase the uppercase to set
339
     */
340
    public void setLowercase(boolean uppercase) {
341
        this.lowercase = uppercase;
342
    }
343
344
    /**
345
     * @param autoindent the autoindent to set
346
     */
347
    public void setAutoindent(boolean autoindent) {
348
        this.autoindent = autoindent;
349
    }
350
    /**
351
     * @param alignindent the alignindent to set
352
     */
353
    public void setAlignindent(boolean alignindent) {
354
        this.alignindent = alignindent;
355
    }
356
    
357
    /**
358
     * Sets the number that has to come first in the list.
359
     *
360
     * @param    first        a number
361
     */
362
    public void setFirst(int first) {
363
        this.first = first;
364
    }
365
    
366
    /**
367
     * Sets the listsymbol.
368
     *
369
     * @param    symbol        a <CODE>Chunk</CODE>
370
     */
371
    public void setListSymbol(Chunk symbol) {
372
        this.symbol = symbol;
373
    }
374
    
375
    /**
376
     * Sets the listsymbol.
377
     * <P>
378
     * This is a shortcut for <CODE>setListSymbol(Chunk symbol)</CODE>.
379
     *
380
     * @param    symbol        a <CODE>String</CODE>
381
     */
382
    public void setListSymbol(String symbol) {
383
        this.symbol = new Chunk(symbol);
384
    }
385
    
386
    /**
387
     * Sets the indentation of this paragraph on the left side.
388
     *
389
     * @param    indentation        the new indentation
390
     */
391
    public void setIndentationLeft(float indentation) {
392
        this.indentationLeft = indentation;
393
    }
394
    
395
    /**
396
     * Sets the indentation of this paragraph on the right side.
397
     *
398
     * @param    indentation        the new indentation
399
     */
400
    public void setIndentationRight(float indentation) {
401
        this.indentationRight = indentation;
402
    }
403
404
    /**
405
     * @param symbolIndent the symbolIndent to set
406
     */
407
    public void setSymbolIndent(float symbolIndent) {
408
        this.symbolIndent = symbolIndent;
409
    }
410
    
411
    // methods to retrieve information
412
    
413
    /**
414
     * Gets all the items in the list.
415
     *
416
     * @return    an <CODE>ArrayList</CODE> containing <CODE>ListItem</CODE>s.
417
     */
418
    public ArrayList getItems() {
419
        return list;
420
    }
421
    
422
    /**
423
     * Gets the size of the list.
424
     *
425
     * @return    a <CODE>size</CODE>
426
     */
427
    public int size() {
428
        return list.size();
429
    }
430
431
    /**
432
     * Returns <CODE>true</CODE> if the list is empty.
433
     * 
434
     * @return <CODE>true</CODE> if the list is empty
435
     */
436
    public boolean isEmpty() {
437
        return list.isEmpty();
438
    }
439
440
    /**
441
     * Gets the leading of the first listitem.
442
     *
443
     * @return    a <CODE>leading</CODE>
444
     */
445
    public float getTotalLeading() {
446 2 1. getTotalLeading : changed conditional boundary → NO_COVERAGE
2. getTotalLeading : negated conditional → NO_COVERAGE
        if (list.size() < 1) {
447 1 1. getTotalLeading : replaced return of float value with -(x + 1) for com/lowagie/text/List::getTotalLeading → NO_COVERAGE
            return -1;
448
        }
449
        ListItem item = (ListItem) list.get(0);
450 1 1. getTotalLeading : replaced return of float value with -(x + 1) for com/lowagie/text/List::getTotalLeading → NO_COVERAGE
        return item.getTotalLeading();
451
    }
452
    
453
    // getters
454
    
455
    /**
456
     * Checks if the list is numbered.
457
     * @return    <CODE>true</CODE> if the list is numbered, <CODE>false</CODE> otherwise.
458
     */
459
    
460
    public boolean isNumbered() {
461
        return numbered;
462
    }
463
464
    /**
465
     * Checks if the list is lettered.
466
     * @return  <CODE>true</CODE> if the list is lettered, <CODE>false</CODE> otherwise.
467
     */
468
    public boolean isLettered() {
469
        return lettered;
470
    }
471
472
    /**
473
     * Checks if the list lettering is lowercase.
474
     * @return  <CODE>true</CODE> if it is lowercase, <CODE>false</CODE> otherwise.
475
     */
476
    public boolean isLowercase() {
477
        return lowercase;
478
    }
479
    
480
    /**
481
     * Checks if the indentation of list items is done automatically.
482
     * @return the autoindent
483
     */
484
    public boolean isAutoindent() {
485
        return autoindent;
486
    }
487
    
488
    /**
489
     * Checks if all the listitems should be aligned.
490
     * @return the alignindent
491
     */
492
    public boolean isAlignindent() {
493
        return alignindent;
494
    }
495
496
    /**
497
     * Gets the first number        .
498
     * @return a number
499
     */
500
    public int getFirst() {
501
        return first;
502
    }
503
504
    /**
505
     * Gets the Chunk containing the symbol.
506
     * @return a Chunk with a symbol
507
     */
508
    public Chunk getSymbol() {
509
        return symbol;
510
    }
511
512
    /**
513
     * Gets the indentation of this paragraph on the left side.
514
     * @return    the indentation
515
     */
516
    public float getIndentationLeft() {
517
        return indentationLeft;
518
    }
519
520
    /**
521
     * Gets the indentation of this paragraph on the right side.
522
     * @return    the indentation
523
     */
524
    public float getIndentationRight() {
525
        return indentationRight;
526
    }
527
528
    /**
529
     * Gets the symbol indentation.
530
     * @return the symbol indentation
531
     */
532
    public float getSymbolIndent() {
533
        return symbolIndent;
534
    }
535
    /**
536
     * @see com.lowagie.text.Element#isContent()
537
     * @since    iText 2.0.8
538
     */
539
    public boolean isContent() {
540
        return true;
541
    }
542
543
    /**
544
     * @see com.lowagie.text.Element#isNestable()
545
     * @since    iText 2.0.8
546
     */
547
    public boolean isNestable() {
548
        return true;
549
    }
550
551
    /**
552
     * Returns the String that is after a number or letter in the list symbol.
553
     * @return    the String that is after a number or letter in the list symbol
554
     * @since    iText 2.1.1
555
     */
556
    public String getPostSymbol() {
557
        return postSymbol;
558
    }
559
560
    /**
561
     * Sets the String that has to be added after a number or letter in the list symbol.
562
     * @since    iText 2.1.1
563
     * @param    postSymbol the String that has to be added after a number or letter in the list symbol.
564
     */
565
    public void setPostSymbol(String postSymbol) {
566
        this.postSymbol = postSymbol;
567
    }
568
569
    /**
570
     * Returns the String that is before a number or letter in the list symbol.
571
     * @return    the String that is before a number or letter in the list symbol
572
     * @since    iText 2.1.1
573
     */
574
    public String getPreSymbol() {
575
        return preSymbol;
576
    }
577
578
    /**
579
     * Sets the String that has to be added before a number or letter in the list symbol.
580
     * @since    iText 2.1.1
581
     * @param    preSymbol the String that has to be added before a number or letter in the list symbol.
582
     */
583
    public void setPreSymbol(String preSymbol) {
584
        this.preSymbol = preSymbol;
585
    }
586
587
}

Mutations

232

1.1
Location : process
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

235

1.1
Location : process
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

258

1.1
Location : getChunks
Killed by : none
mutated return of Object value for com/lowagie/text/List::getChunks to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

270

1.1
Location : add
Killed by : none
negated conditional → NO_COVERAGE

272

1.1
Location : add
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : add
Killed by : none
negated conditional → NO_COVERAGE

274

1.1
Location : add
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

275

1.1
Location : add
Killed by : none
negated conditional → NO_COVERAGE

280

1.1
Location : add
Killed by : none
removed call to com/lowagie/text/ListItem::setListSymbol → NO_COVERAGE

283

1.1
Location : add
Killed by : none
removed call to com/lowagie/text/ListItem::setListSymbol → NO_COVERAGE

285

1.1
Location : add
Killed by : none
removed call to com/lowagie/text/ListItem::setIndentationLeft → NO_COVERAGE

286

1.1
Location : add
Killed by : none
removed call to com/lowagie/text/ListItem::setIndentationRight → NO_COVERAGE

287

1.1
Location : add
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

289

1.1
Location : add
Killed by : none
negated conditional → NO_COVERAGE

291

1.1
Location : add
Killed by : none
Replaced float addition with subtraction → NO_COVERAGE

2.2
Location : add
Killed by : none
removed call to com/lowagie/text/List::setIndentationLeft → NO_COVERAGE

292

1.1
Location : add
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

293

1.1
Location : add
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

295

1.1
Location : add
Killed by : none
negated conditional → NO_COVERAGE

296

1.1
Location : add
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

298

1.1
Location : add
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

309

1.1
Location : normalizeIndentation
Killed by : none
negated conditional → NO_COVERAGE

315

1.1
Location : normalizeIndentation
Killed by : none
negated conditional → NO_COVERAGE

316

1.1
Location : normalizeIndentation
Killed by : none
removed call to com/lowagie/text/ListItem::setIndentationLeft → NO_COVERAGE

446

1.1
Location : getTotalLeading
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : getTotalLeading
Killed by : none
negated conditional → NO_COVERAGE

447

1.1
Location : getTotalLeading
Killed by : none
replaced return of float value with -(x + 1) for com/lowagie/text/List::getTotalLeading → NO_COVERAGE

450

1.1
Location : getTotalLeading
Killed by : none
replaced return of float value with -(x + 1) for com/lowagie/text/List::getTotalLeading → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.4.2