Skip to content

Commit 2ec9154

Browse files
committed
Improve PdfDictionary#entrySet() and PdfDictionary#values().
The returned #values() and #entrySet() is not a static copy. Therefore, changes to the PdfDictionary continue to be reflected in the #values() and #entrySet(). DEVSIX-728
1 parent fc7a4f4 commit 2ec9154

File tree

5 files changed

+1043
-21
lines changed

5 files changed

+1043
-21
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfDictionary.java

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ This file is part of the iText (R) project.
4343
*/
4444
package com.itextpdf.kernel.pdf;
4545

46-
import com.itextpdf.kernel.PdfException;
4746
import com.itextpdf.kernel.geom.Rectangle;
4847

4948
import java.util.*;
@@ -370,16 +369,7 @@ public Collection<PdfObject> values(boolean asDirects) {
370369
* @return a Collection holding all the values
371370
*/
372371
public Collection<PdfObject> values() {
373-
Collection<PdfObject> directValues = new ArrayList<>();
374-
for (PdfObject value : map.values()) {
375-
if (value.isIndirectReference()) {
376-
directValues.add(((PdfIndirectReference)value).getRefersTo());
377-
} else {
378-
directValues.add(value);
379-
}
380-
}
381-
382-
return directValues;
372+
return new PdfDictionaryValues(map.values());
383373
}
384374

385375
/**
@@ -413,16 +403,7 @@ public Collection<PdfObject> directValues() {
413403
* @return a Set of Map.Entry objects
414404
*/
415405
public Set<Map.Entry<PdfName, PdfObject>> entrySet() {
416-
Map<PdfName, PdfObject> directMap = new TreeMap<>();
417-
for(Map.Entry<PdfName, PdfObject> entry : map.entrySet()) {
418-
PdfObject value = entry.getValue();
419-
if (value.isIndirectReference()) {
420-
directMap.put(entry.getKey(), ((PdfIndirectReference)value).getRefersTo());
421-
} else {
422-
directMap.put(entry.getKey(), value);
423-
}
424-
}
425-
return directMap.entrySet();
406+
return new PdfDictionaryEntrySet(map.entrySet());
426407
}
427408

428409
/**
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.itextpdf.kernel.pdf;
2+
3+
import java.util.AbstractSet;
4+
import java.util.Iterator;
5+
import java.util.Map;
6+
import java.util.Objects;
7+
import java.util.Set;
8+
9+
class PdfDictionaryEntrySet extends AbstractSet<Map.Entry<PdfName, PdfObject>> {
10+
11+
private final Set<Map.Entry<PdfName, PdfObject>> set;
12+
13+
PdfDictionaryEntrySet(Set<Map.Entry<PdfName, PdfObject>> set) {
14+
this.set = set;
15+
}
16+
17+
@Override
18+
public Iterator<Map.Entry<PdfName, PdfObject>> iterator() {
19+
return new DirectIterator();
20+
}
21+
22+
@Override
23+
public int size() {
24+
return set.size();
25+
}
26+
27+
@Override
28+
public void clear() {
29+
set.clear();
30+
}
31+
32+
private class DirectIterator implements Iterator<Map.Entry<PdfName, PdfObject>> {
33+
Iterator<Map.Entry<PdfName, PdfObject>> parentIterator = set.iterator();
34+
35+
@Override
36+
public boolean hasNext() {
37+
return parentIterator.hasNext();
38+
}
39+
40+
@Override
41+
public Map.Entry<PdfName, PdfObject> next() {
42+
return new DirectEntry(parentIterator.next());
43+
}
44+
45+
@Override
46+
public void remove() {
47+
parentIterator.remove();
48+
}
49+
}
50+
51+
private class DirectEntry implements Map.Entry<PdfName, PdfObject> {
52+
53+
Map.Entry<PdfName, PdfObject> entry;
54+
55+
public DirectEntry(Map.Entry<PdfName, PdfObject> entry) {
56+
this.entry = entry;
57+
}
58+
59+
@Override
60+
public PdfName getKey() {
61+
return entry.getKey();
62+
}
63+
64+
@Override
65+
public PdfObject getValue() {
66+
PdfObject obj = entry.getValue();
67+
if (obj.isIndirectReference()) {
68+
obj = ((PdfIndirectReference) obj).getRefersTo(true);
69+
}
70+
return obj;
71+
}
72+
73+
@Override
74+
public PdfObject setValue(PdfObject value) {
75+
return entry.setValue(value);
76+
}
77+
78+
@Override
79+
public boolean equals(Object o) {
80+
if (!(o instanceof Map.Entry))
81+
return false;
82+
Map.Entry e = (Map.Entry)o;
83+
Object k1 = getKey();
84+
Object k2 = e.getKey();
85+
if (k1 != null && k1.equals(k2)) {
86+
Object v1 = getValue();
87+
Object v2 = e.getValue();
88+
if (v1 != null && v1.equals(v2))
89+
return true;
90+
}
91+
return false;
92+
}
93+
94+
@Override
95+
public int hashCode() {
96+
return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
97+
}
98+
}
99+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.itextpdf.kernel.pdf;
2+
3+
import java.util.AbstractCollection;
4+
import java.util.Collection;
5+
import java.util.Iterator;
6+
7+
class PdfDictionaryValues extends AbstractCollection<PdfObject> {
8+
9+
private final Collection<PdfObject> collection;
10+
11+
PdfDictionaryValues(Collection<PdfObject> collection) {
12+
this.collection = collection;
13+
}
14+
15+
@Override
16+
public boolean add(PdfObject object) {
17+
return collection.add(object);
18+
}
19+
20+
@Override
21+
public boolean contains(Object o) {
22+
if (collection.contains(o))
23+
return true;
24+
if (o != null) {
25+
if (((PdfObject) o).getIndirectReference() != null
26+
&& collection.contains(((PdfObject) o).getIndirectReference())) {
27+
return true;
28+
} else if (((PdfObject) o).isIndirectReference()
29+
&& collection.contains(((PdfIndirectReference) o).getRefersTo())) {
30+
return true;
31+
}
32+
}
33+
return false;
34+
35+
}
36+
37+
@Override
38+
public boolean remove(Object o) {
39+
if (collection.remove(o))
40+
return true;
41+
if (o != null) {
42+
if (((PdfObject) o).getIndirectReference() != null
43+
&& collection.remove(((PdfObject) o).getIndirectReference())) {
44+
return true;
45+
} else if (((PdfObject) o).isIndirectReference()
46+
&& collection.remove(((PdfIndirectReference) o).getRefersTo())) {
47+
return true;
48+
}
49+
}
50+
return false;
51+
}
52+
53+
@Override
54+
public int size() {
55+
return collection.size();
56+
}
57+
58+
@Override
59+
public void clear() {
60+
collection.clear();
61+
}
62+
63+
@Override
64+
public Iterator<PdfObject> iterator() {
65+
return new DirectIterator();
66+
}
67+
68+
private class DirectIterator implements Iterator<PdfObject> {
69+
Iterator<PdfObject> parentIterator = collection.iterator();
70+
71+
@Override
72+
public boolean hasNext() {
73+
return parentIterator.hasNext();
74+
}
75+
76+
@Override
77+
public PdfObject next() {
78+
PdfObject obj = parentIterator.next();
79+
if (obj.isIndirectReference()) {
80+
obj = ((PdfIndirectReference) obj).getRefersTo(true);
81+
}
82+
return obj;
83+
}
84+
85+
@Override
86+
public void remove() {
87+
parentIterator.remove();
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)