1 /*
2  * Copyright (c) 2005, 2016, 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         Iterator<TIFFTag> iter = tags.iterator();
76         while (iter.hasNext()) {
77             Object o = iter.next();
78             if (!(o instanceof TIFFTag)) {
79                 throw new IllegalArgumentException(
80                                                "tags contains a non-TIFFTag!");
81             }
82             TIFFTag tag = (TIFFTag)o;
83 
84             allowedTagsByNumber.put(Integer.valueOf(tag.getNumber()), tag);
85             allowedTagsByName.put(tag.getName(), tag);
86         }
87     }
88 
89     /**
90      * Returns the {@code TIFFTag} from this set that is
91      * associated with the given tag number, or {@code null} if
92      * no tag exists for that number.
93      *
94      * @param tagNumber the number of the tag to be retrieved.
95      *
96      * @return the numbered {@code TIFFTag}, or {@code null}.
97      */
getTag(int tagNumber)98     public TIFFTag getTag(int tagNumber) {
99         return allowedTagsByNumber.get(Integer.valueOf(tagNumber));
100     }
101 
102     /**
103      * Returns the {@code TIFFTag} having the given tag name, or
104      * {@code null} if the named tag does not belong to this tag set.
105      *
106      * @param tagName the name of the tag to be retrieved, as a
107      * {@code String}.
108      *
109      * @return the named {@code TIFFTag}, or {@code null}.
110      *
111      * @throws IllegalArgumentException if {@code tagName} is
112      * {@code null}.
113      */
getTag(String tagName)114     public TIFFTag getTag(String tagName) {
115         if (tagName == null) {
116             throw new IllegalArgumentException("tagName == null!");
117         }
118         return allowedTagsByName.get(tagName);
119     }
120 
121     /**
122      * Retrieves an unmodifiable numerically increasing set of tag numbers.
123      *
124      * <p>The returned object is unmodifiable and contains the tag
125      * numbers of all {@code TIFFTag}s in this {@code TIFFTagSet}
126      * sorted into ascending order according to
127      * {@link Integer#compareTo(Object)}.</p>
128      *
129      * @return All tag numbers in this set.
130      */
getTagNumbers()131     public SortedSet<Integer> getTagNumbers() {
132         Set<Integer> tagNumbers = allowedTagsByNumber.keySet();
133         SortedSet<Integer> sortedTagNumbers;
134         if(tagNumbers instanceof SortedSet) {
135             sortedTagNumbers = (SortedSet<Integer>)tagNumbers;
136         } else {
137             sortedTagNumbers = new TreeSet<Integer>(tagNumbers);
138         }
139 
140         return Collections.unmodifiableSortedSet(sortedTagNumbers);
141     }
142 
143     /**
144      * Retrieves an unmodifiable lexicographically increasing set of tag names.
145      *
146      * <p>The returned object is unmodifiable and contains the tag
147      * names of all {@code TIFFTag}s in this {@code TIFFTagSet}
148      * sorted into ascending order according to
149      * {@link String#compareTo(Object)}.</p>
150      *
151      * @return All tag names in this set.
152      */
getTagNames()153     public SortedSet<String> getTagNames() {
154         Set<String> tagNames = allowedTagsByName.keySet();
155         SortedSet<String> sortedTagNames;
156         if(tagNames instanceof SortedSet) {
157             sortedTagNames = (SortedSet<String>)tagNames;
158         } else {
159             sortedTagNames = new TreeSet<String>(tagNames);
160         }
161 
162         return Collections.unmodifiableSortedSet(sortedTagNames);
163     }
164 }
165