1 /*
2  * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package javax.imageio.plugins.tiff;
26 
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.SortedMap;
32 import java.util.SortedSet;
33 import java.util.TreeMap;
34 import java.util.TreeSet;
35 
36 /**
37  * A class representing a set of TIFF tags.  Each tag in the set must have
38  * a unique number (this is a limitation of the TIFF specification itself).
39  *
40  * <p> This class and its subclasses are responsible for mapping
41  * between raw tag numbers and {@code TIFFTag} objects, which
42  * contain additional information about each tag, such as the tag's
43  * name, legal data types, and mnemonic names for some or all of its
44  * data values.
45  *
46  * @since 9
47  * @see   TIFFTag
48  */
49 public class TIFFTagSet {
50 
51     private SortedMap<Integer,TIFFTag> allowedTagsByNumber = new TreeMap<Integer,TIFFTag>();
52 
53     private SortedMap<String,TIFFTag> allowedTagsByName = new TreeMap<String,TIFFTag>();
54 
55     /**
56      * Constructs a TIFFTagSet.
57      */
TIFFTagSet()58     private TIFFTagSet() {}
59 
60     /**
61      * Constructs a {@code TIFFTagSet}, given a {@code List}
62      * of {@code TIFFTag} objects.
63      *
64      * @param tags a {@code List} object containing
65      * {@code TIFFTag} objects to be added to this tag set.
66      *
67      * @throws IllegalArgumentException if {@code tags} is
68      * {@code null}, or contains objects that are not instances
69      * of the {@code TIFFTag} class.
70      */
TIFFTagSet(List<TIFFTag> tags)71     public TIFFTagSet(List<TIFFTag> tags) {
72         if (tags == null) {
73             throw new IllegalArgumentException("tags == null!");
74         }
75         for (Object o : tags) {
76             if (!(o instanceof TIFFTag)) {
77                 throw new IllegalArgumentException(
78                                                "tags contains a non-TIFFTag!");
79             }
80             TIFFTag tag = (TIFFTag)o;
81 
82             allowedTagsByNumber.put(Integer.valueOf(tag.getNumber()), tag);
83             allowedTagsByName.put(tag.getName(), tag);
84         }
85     }
86 
87     /**
88      * Returns the {@code TIFFTag} from this set that is
89      * associated with the given tag number, or {@code null} if
90      * no tag exists for that number.
91      *
92      * @param tagNumber the number of the tag to be retrieved.
93      *
94      * @return the numbered {@code TIFFTag}, or {@code null}.
95      */
getTag(int tagNumber)96     public TIFFTag getTag(int tagNumber) {
97         return allowedTagsByNumber.get(Integer.valueOf(tagNumber));
98     }
99 
100     /**
101      * Returns the {@code TIFFTag} having the given tag name, or
102      * {@code null} if the named tag does not belong to this tag set.
103      *
104      * @param tagName the name of the tag to be retrieved, as a
105      * {@code String}.
106      *
107      * @return the named {@code TIFFTag}, or {@code null}.
108      *
109      * @throws IllegalArgumentException if {@code tagName} is
110      * {@code null}.
111      */
getTag(String tagName)112     public TIFFTag getTag(String tagName) {
113         if (tagName == null) {
114             throw new IllegalArgumentException("tagName == null!");
115         }
116         return allowedTagsByName.get(tagName);
117     }
118 
119     /**
120      * Retrieves an unmodifiable numerically increasing set of tag numbers.
121      *
122      * <p>The returned object is unmodifiable and contains the tag
123      * numbers of all {@code TIFFTag}s in this {@code TIFFTagSet}
124      * sorted into ascending order according to
125      * {@link Integer#compareTo(Object)}.</p>
126      *
127      * @return All tag numbers in this set.
128      */
getTagNumbers()129     public SortedSet<Integer> getTagNumbers() {
130         Set<Integer> tagNumbers = allowedTagsByNumber.keySet();
131         SortedSet<Integer> sortedTagNumbers;
132         if(tagNumbers instanceof SortedSet) {
133             sortedTagNumbers = (SortedSet<Integer>)tagNumbers;
134         } else {
135             sortedTagNumbers = new TreeSet<Integer>(tagNumbers);
136         }
137 
138         return Collections.unmodifiableSortedSet(sortedTagNumbers);
139     }
140 
141     /**
142      * Retrieves an unmodifiable lexicographically increasing set of tag names.
143      *
144      * <p>The returned object is unmodifiable and contains the tag
145      * names of all {@code TIFFTag}s in this {@code TIFFTagSet}
146      * sorted into ascending order according to
147      * {@link String#compareTo(Object)}.</p>
148      *
149      * @return All tag names in this set.
150      */
getTagNames()151     public SortedSet<String> getTagNames() {
152         Set<String> tagNames = allowedTagsByName.keySet();
153         SortedSet<String> sortedTagNames;
154         if(tagNames instanceof SortedSet) {
155             sortedTagNames = (SortedSet<String>)tagNames;
156         } else {
157             sortedTagNames = new TreeSet<String>(tagNames);
158         }
159 
160         return Collections.unmodifiableSortedSet(sortedTagNames);
161     }
162 }
163