PdfPageLabels.java

1
/* $Id$ $Name$ Copyright 2001, 2002 Paulo Soares The contents of this file are subject to the
2
 * Mozilla Public License Version 1.1 (the "License"); you may not use this file except in
3
 * compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
4
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5
 * ANY KIND, either express or implied. See the License for the specific language governing rights
6
 * and limitations under the License. The Original Code is 'iText, a free JAVA-PDF library'. The
7
 * Initial Developer of the Original Code is Bruno Lowagie. Portions created by the Initial
8
 * Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. All Rights Reserved.
9
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer are Copyright (C)
10
 * 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. Contributor(s): all the names of the
11
 * contributors are added in the source code where applicable. Alternatively, the contents of this
12
 * file may be used under the terms of the LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"),
13
 * in which case the provisions of LGPL are applicable instead of those above. If you wish to allow
14
 * use of your version of this file only under the terms of the LGPL License and not to allow others
15
 * to use your version of this file under the MPL, indicate your decision by deleting the provisions
16
 * above and replace them with the notice and other provisions required by the LGPL. If you do not
17
 * delete the provisions above, a recipient may use your version of this file under either the MPL
18
 * or the GNU LIBRARY GENERAL PUBLIC LICENSE. This library is free software; you can redistribute it
19
 * and/or modify it under the terms of the MPL as stated above or under the terms of the GNU Library
20
 * General Public License as published by the Free Software Foundation; either version 2 of the
21
 * License, or any later version. This library is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
23
 * PARTICULAR PURPOSE. See the GNU Library general Public License for more details. If you didn't
24
 * download this code from the following link, you should check if you aren't using an obsolete
25
 * version: http://www.lowagie.com/iText/ */
26
27
package com.lowagie.text.pdf;
28
29
30
import com.lowagie.text.error_messages.MessageLocalization;
31
import com.lowagie.text.ExceptionConverter;
32
import com.lowagie.text.factories.RomanAlphabetFactory;
33
import com.lowagie.text.factories.RomanNumberFactory;
34
35
import java.io.IOException;
36
import java.util.Arrays;
37
import java.util.HashMap;
38
39
/**
40
 * Page labels are used to identify each page visually on the screen or in print.
41
 * 
42
 * @author Paulo Soares (psoares@consiste.pt)
43
 */
44
public class PdfPageLabels {
45
46
    /**
47
     * Logical pages will have the form 1,2,3,...
48
     */
49
    public static final int DECIMAL_ARABIC_NUMERALS = 0;
50
51
    /**
52
     * Logical pages will have the form I,II,III,IV,...
53
     */
54
    public static final int UPPERCASE_ROMAN_NUMERALS = 1;
55
56
    /**
57
     * Logical pages will have the form i,ii,iii,iv,...
58
     */
59
    public static final int LOWERCASE_ROMAN_NUMERALS = 2;
60
61
    /**
62
     * Logical pages will have the form of uppercase letters (A to Z for the first 26 pages, AA to
63
     * ZZ for the next 26, and so on)
64
     */
65
    public static final int UPPERCASE_LETTERS = 3;
66
67
    /**
68
     * Logical pages will have the form of uppercase letters (a to z for the first 26 pages, aa to
69
     * zz for the next 26, and so on)
70
     */
71
    public static final int LOWERCASE_LETTERS = 4;
72
73
    /**
74
     * No logical page numbers are generated but fixed text may still exist
75
     */
76
    public static final int EMPTY = 5;
77
78
    /**
79
     * Dictionary values to set the logical page styles
80
     */
81
    static PdfName[] numberingStyle = new PdfName[]
82
            {
83
                    PdfName.D, PdfName.R, new PdfName("r"), PdfName.A, new PdfName("a")
84
            };
85
86
    /**
87
     * The sequence of logical pages. Will contain at least a value for page 1
88
     */
89
    private HashMap map;
90
91
    /**
92
     * Creates a new PdfPageLabel with a default logical page 1
93
     */
94
    public PdfPageLabels() {
95
        map = new HashMap();
96 1 1. : removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE
        addPageLabel(1, PdfPageLabels.DECIMAL_ARABIC_NUMERALS, null, 1);
97
    }
98
99
    /**
100
     * Adds or replaces a page label.
101
     * 
102
     * @param page
103
     *            the real page to start the numbering. First page is 1
104
     * @param numberStyle
105
     *            the numbering style such as LOWERCASE_ROMAN_NUMERALS
106
     * @param text
107
     *            the text to prefix the number. Can be <CODE>null</CODE> or empty
108
     * @param firstPage
109
     *            the first logical page number
110
     */
111
    public void addPageLabel(int page, int numberStyle, String text, int firstPage) {
112 4 1. addPageLabel : changed conditional boundary → NO_COVERAGE
2. addPageLabel : changed conditional boundary → NO_COVERAGE
3. addPageLabel : negated conditional → NO_COVERAGE
4. addPageLabel : negated conditional → NO_COVERAGE
        if (page < 1 || firstPage < 1) {
113
            throw new IllegalArgumentException(
114
                        MessageLocalization.getComposedMessage("in.a.page.label.the.page.numbers.must.be.greater.or.equal.to.1"));
115
        }
116
        PdfDictionary dic = new PdfDictionary();
117 4 1. addPageLabel : changed conditional boundary → NO_COVERAGE
2. addPageLabel : changed conditional boundary → NO_COVERAGE
3. addPageLabel : negated conditional → NO_COVERAGE
4. addPageLabel : negated conditional → NO_COVERAGE
        if (numberStyle >= 0 && numberStyle < PdfPageLabels.numberingStyle.length) {
118 1 1. addPageLabel : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE
            dic.put(PdfName.S, PdfPageLabels.numberingStyle[numberStyle]);
119
        }
120 1 1. addPageLabel : negated conditional → NO_COVERAGE
        if (text != null) {
121 1 1. addPageLabel : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE
            dic.put(PdfName.P, new PdfString(text, PdfObject.TEXT_UNICODE));
122
        }
123 1 1. addPageLabel : negated conditional → NO_COVERAGE
        if (firstPage != 1) {
124 1 1. addPageLabel : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE
            dic.put(PdfName.ST, new PdfNumber(firstPage));
125
        }
126 1 1. addPageLabel : Replaced integer subtraction with addition → NO_COVERAGE
        map.put(page - 1, dic);
127
    }
128
129
    /**
130
     * Adds or replaces a page label. The first logical page has the default of 1.
131
     * 
132
     * @param page
133
     *            the real page to start the numbering. First page is 1
134
     * @param numberStyle
135
     *            the numbering style such as LOWERCASE_ROMAN_NUMERALS
136
     * @param text
137
     *            the text to prefix the number. Can be <CODE>null</CODE> or empty
138
     */
139
    public void addPageLabel(int page, int numberStyle, String text) {
140 1 1. addPageLabel : removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE
        addPageLabel(page, numberStyle, text, 1);
141
    }
142
143
    /**
144
     * Adds or replaces a page label. There is no text prefix and the first logical page has the
145
     * default of 1.
146
     * 
147
     * @param page
148
     *            the real page to start the numbering. First page is 1
149
     * @param numberStyle
150
     *            the numbering style such as LOWERCASE_ROMAN_NUMERALS
151
     */
152
    public void addPageLabel(int page, int numberStyle) {
153 1 1. addPageLabel : removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE
        addPageLabel(page, numberStyle, null, 1);
154
    }
155
156
    /**
157
     * Adds or replaces a page label.
158
     */
159
    public void addPageLabel(PdfPageLabelFormat format) {
160 1 1. addPageLabel : removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE
        addPageLabel(format.physicalPage, format.numberStyle, format.prefix, format.logicalPage);
161
    }
162
163
    /**
164
     * Removes a page label. The first page label can not be removed, only changed.
165
     * 
166
     * @param page
167
     *            the real page to remove
168
     */
169
    public void removePageLabel(int page) {
170 2 1. removePageLabel : changed conditional boundary → NO_COVERAGE
2. removePageLabel : negated conditional → NO_COVERAGE
        if (page <= 1) {
171
            return;
172
        }
173 1 1. removePageLabel : Replaced integer subtraction with addition → NO_COVERAGE
        map.remove(page - 1);
174
    }
175
176
    /**
177
     * Gets the page label dictionary to insert into the document.
178
     * 
179
     * @return the page label dictionary
180
     */
181
    PdfDictionary getDictionary(PdfWriter writer) {
182
        try {
183 1 1. getDictionary : mutated return of Object value for com/lowagie/text/pdf/PdfPageLabels::getDictionary to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return PdfNumberTree.writeTree(map, writer);
184
        } catch (IOException e) {
185
            throw new ExceptionConverter(e);
186
        }
187
    }
188
189
    /**
190
     * Retrieves the page labels from a PDF as an array of String objects.
191
     * 
192
     * @param reader
193
     *            a PdfReader object that has the page labels you want to retrieve
194
     * @return a String array or <code>null</code> if no page labels are present
195
     */
196
    public static String[] getPageLabels(PdfReader reader) {
197
198
        int n = reader.getNumberOfPages();
199
200
        PdfDictionary dict = reader.getCatalog();
201
        PdfDictionary labels = (PdfDictionary) PdfReader.getPdfObjectRelease(dict.get(PdfName.PAGELABELS));
202 1 1. getPageLabels : negated conditional → NO_COVERAGE
        if (labels == null) {
203 1 1. getPageLabels : mutated return of Object value for com/lowagie/text/pdf/PdfPageLabels::getPageLabels to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return null;
204
        }
205
206
        String[] labelstrings = new String[n];
207
208
        HashMap numberTree = PdfNumberTree.readTree(labels);
209
210
        int pagecount = 1;
211
        Integer current;
212
        char type = 'D';
213
        String prefix = "";
214 3 1. getPageLabels : changed conditional boundary → NO_COVERAGE
2. getPageLabels : Changed increment from 1 to -1 → NO_COVERAGE
3. getPageLabels : negated conditional → NO_COVERAGE
        for (int i = 0; i < n; i++ ) {
215
            current = i;
216 1 1. getPageLabels : negated conditional → NO_COVERAGE
            if (numberTree.containsKey(current)) {
217
                PdfDictionary d = (PdfDictionary) PdfReader.getPdfObjectRelease((PdfObject) numberTree.get(current));
218 1 1. getPageLabels : negated conditional → NO_COVERAGE
                if (d.contains(PdfName.ST)) {
219
                    pagecount = ((PdfNumber) d.get(PdfName.ST)).intValue();
220
                } else {
221
                    pagecount = 1;
222
                }
223 1 1. getPageLabels : negated conditional → NO_COVERAGE
                if (d.contains(PdfName.P)) {
224
                    prefix = ((PdfString) d.get(PdfName.P)).toUnicodeString();
225
                } else {
226
                    prefix = "";
227
                }
228 1 1. getPageLabels : negated conditional → NO_COVERAGE
                if (d.contains(PdfName.S)) {
229
                    type = d.get(PdfName.S).toString()
230
                                                        .charAt(1);
231
                }
232
            }
233
            switch (type) {
234
                default:
235
                    labelstrings[i] = prefix + pagecount;
236
                break;
237
                case 'R':
238
                    labelstrings[i] = prefix + RomanNumberFactory.getUpperCaseString(pagecount);
239
                break;
240
                case 'r':
241
                    labelstrings[i] = prefix + RomanNumberFactory.getLowerCaseString(pagecount);
242
                break;
243
                case 'A':
244
                    labelstrings[i] = prefix + RomanAlphabetFactory.getUpperCaseString(pagecount);
245
                break;
246
                case 'a':
247
                    labelstrings[i] = prefix + RomanAlphabetFactory.getLowerCaseString(pagecount);
248
                break;
249
            }
250 1 1. getPageLabels : Changed increment from 1 to -1 → NO_COVERAGE
            pagecount++ ;
251
        }
252 1 1. getPageLabels : mutated return of Object value for com/lowagie/text/pdf/PdfPageLabels::getPageLabels to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return labelstrings;
253
    }
254
255
    /**
256
     * Retrieves the page labels from a PDF as an array of {@link PdfPageLabelFormat} objects.
257
     * 
258
     * @param reader
259
     *            a PdfReader object that has the page labels you want to retrieve
260
     * @return a PdfPageLabelEntry array, containing an entry for each format change or
261
     *         <code>null</code> if no page labels are present
262
     */
263
    public static PdfPageLabelFormat[] getPageLabelFormats(PdfReader reader) {
264
        PdfDictionary dict = reader.getCatalog();
265
        PdfDictionary labels = (PdfDictionary) PdfReader.getPdfObjectRelease(dict.get(PdfName.PAGELABELS));
266 1 1. getPageLabelFormats : negated conditional → NO_COVERAGE
        if (labels == null) {
267 1 1. getPageLabelFormats : mutated return of Object value for com/lowagie/text/pdf/PdfPageLabels::getPageLabelFormats to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return null;
268
        }
269
        HashMap numberTree = PdfNumberTree.readTree(labels);
270
        Integer[] numbers = new Integer[numberTree.size()];
271
        numbers = (Integer[]) numberTree.keySet()
272
                                        .toArray(numbers);
273 1 1. getPageLabelFormats : removed call to java/util/Arrays::sort → NO_COVERAGE
        Arrays.sort(numbers);
274
        PdfPageLabelFormat[] formats = new PdfPageLabelFormat[numberTree.size()];
275
        String prefix;
276
        int numberStyle;
277
        int pagecount;
278 3 1. getPageLabelFormats : changed conditional boundary → NO_COVERAGE
2. getPageLabelFormats : Changed increment from 1 to -1 → NO_COVERAGE
3. getPageLabelFormats : negated conditional → NO_COVERAGE
        for (int k = 0; k < numbers.length; ++k) {
279
            Integer key = numbers[k];
280
            PdfDictionary d = (PdfDictionary) PdfReader.getPdfObjectRelease((PdfObject) numberTree.get(key));
281 1 1. getPageLabelFormats : negated conditional → NO_COVERAGE
            if (d.contains(PdfName.ST)) {
282
                pagecount = ((PdfNumber) d.get(PdfName.ST)).intValue();
283
            } else {
284
                pagecount = 1;
285
            }
286 1 1. getPageLabelFormats : negated conditional → NO_COVERAGE
            if (d.contains(PdfName.P)) {
287
                prefix = ((PdfString) d.get(PdfName.P)).toUnicodeString();
288
            } else {
289
                prefix = "";
290
            }
291 1 1. getPageLabelFormats : negated conditional → NO_COVERAGE
            if (d.contains(PdfName.S)) {
292
                char type = d.get(PdfName.S).toString()
293
                                                        .charAt(1);
294
                switch (type) {
295
                    case 'R':
296
                        numberStyle = PdfPageLabels.UPPERCASE_ROMAN_NUMERALS;
297
                    break;
298
                    case 'r':
299
                        numberStyle = PdfPageLabels.LOWERCASE_ROMAN_NUMERALS;
300
                    break;
301
                    case 'A':
302
                        numberStyle = PdfPageLabels.UPPERCASE_LETTERS;
303
                    break;
304
                    case 'a':
305
                        numberStyle = PdfPageLabels.LOWERCASE_LETTERS;
306
                    break;
307
                    default:
308
                        numberStyle = PdfPageLabels.DECIMAL_ARABIC_NUMERALS;
309
                    break;
310
                }
311
            } else {
312
                numberStyle = PdfPageLabels.EMPTY;
313
            }
314 1 1. getPageLabelFormats : Replaced integer addition with subtraction → NO_COVERAGE
            formats[k] = new PdfPageLabelFormat(key + 1, numberStyle, prefix, pagecount);
315
        }
316 1 1. getPageLabelFormats : mutated return of Object value for com/lowagie/text/pdf/PdfPageLabels::getPageLabelFormats to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return formats;
317
    }
318
319
    public static class PdfPageLabelFormat {
320
321
        public int physicalPage;
322
323
        public int numberStyle;
324
325
        public String prefix;
326
327
        public int logicalPage;
328
329
        /**
330
         * Creates a page label format.
331
         * 
332
         * @param physicalPage
333
         *            the real page to start the numbering. First page is 1
334
         * @param numberStyle
335
         *            the numbering style such as LOWERCASE_ROMAN_NUMERALS
336
         * @param prefix
337
         *            the text to prefix the number. Can be <CODE>null</CODE> or empty
338
         * @param logicalPage
339
         *            the first logical page number
340
         */
341
        public PdfPageLabelFormat(    int physicalPage,
342
                                    int numberStyle,
343
                                    String prefix,
344
                                    int logicalPage) {
345
            this.physicalPage = physicalPage;
346
            this.numberStyle = numberStyle;
347
            this.prefix = prefix;
348
            this.logicalPage = logicalPage;
349
        }
350
    }
351
}

Mutations

96

1.1
Location :
Killed by : none
removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE

112

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

2.2
Location : addPageLabel
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : addPageLabel
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : addPageLabel
Killed by : none
negated conditional → NO_COVERAGE

117

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

2.2
Location : addPageLabel
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : addPageLabel
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : addPageLabel
Killed by : none
negated conditional → NO_COVERAGE

118

1.1
Location : addPageLabel
Killed by : none
removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE

120

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

121

1.1
Location : addPageLabel
Killed by : none
removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE

123

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

124

1.1
Location : addPageLabel
Killed by : none
removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE

126

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

140

1.1
Location : addPageLabel
Killed by : none
removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE

153

1.1
Location : addPageLabel
Killed by : none
removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE

160

1.1
Location : addPageLabel
Killed by : none
removed call to com/lowagie/text/pdf/PdfPageLabels::addPageLabel → NO_COVERAGE

170

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

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

173

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

183

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

202

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

203

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

214

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

2.2
Location : getPageLabels
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : getPageLabels
Killed by : none
negated conditional → NO_COVERAGE

216

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

218

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

223

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

228

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

250

1.1
Location : getPageLabels
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

252

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

266

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

267

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

273

1.1
Location : getPageLabelFormats
Killed by : none
removed call to java/util/Arrays::sort → NO_COVERAGE

278

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

2.2
Location : getPageLabelFormats
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : getPageLabelFormats
Killed by : none
negated conditional → NO_COVERAGE

281

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

286

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

291

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

314

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

316

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

Active mutators

Tests examined


Report generated by PIT 1.4.2