View Javadoc
1   package ca.uhn.fhir.model.api;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import java.io.Serializable;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.Iterator;
27  import java.util.LinkedHashSet;
28  import java.util.List;
29  import java.util.Set;
30  
31  import org.hl7.fhir.instance.model.api.IBase;
32  
33  import ca.uhn.fhir.util.CoverageIgnore;
34  
35  /**
36   * A collection of tags present on a single resource. TagList is backed by a {@link LinkedHashSet}, so the order of
37   * added tags will be consistent, but duplicates will not be preserved.
38   * 
39   * <p>
40   * <b>Thread safety:</b> This class is not thread safe
41   * </p>
42   */
43  public class TagList implements Set<Tag>, Serializable, IBase {
44  
45  	public static final String ATTR_CATEGORY = "category";
46  	public static final String ELEMENT_NAME = "TagList";
47  
48  	public static final String ELEMENT_NAME_LC = ELEMENT_NAME.toLowerCase();
49  	private static final long serialVersionUID = 1L;
50  	private transient List<Tag> myOrderedTags;
51  	private LinkedHashSet<Tag> myTagSet = new LinkedHashSet<Tag>();
52  
53  	/**
54  	 * Constructor
55  	 */
56  	public TagList() {
57  		super();
58  	}
59  
60  	/**
61  	 * Copy constructor
62  	 */
63  	public TagList(TagList theTags) {
64  		if (theTags != null) {
65  			for (Tag next : theTags) {
66  				add(next);
67  			}
68  		}
69  	}
70  
71  	@Override
72  	public String toString() {
73  		StringBuilder b = new StringBuilder();
74  		b.append("TagList[").append(size()).append(" tag(s)]");
75  		for (Tag next : this) {
76  			b.append("\n * ").append(next.toString());
77  		}
78  		return b.toString();
79  	}
80  
81  	@Override
82  	public boolean add(Tag theE) {
83  		myOrderedTags = null;
84  		return myTagSet.add(theE);
85  	}
86  
87  	@Override
88  	public boolean addAll(Collection<? extends Tag> theC) {
89  		myOrderedTags = null;
90  		return myTagSet.addAll(theC);
91  	}
92  
93  	/**
94  	 * @deprecated Tags wil become immutable in a future release of HAPI, so {@link #addTag(String, String, String)}
95  	 *             should be used instead
96  	 */
97  	@Deprecated
98  	public Tag addTag() {
99  		myOrderedTags = null;
100 		return addTag(null, null, null);
101 	}
102 
103 	/**
104 	 * Add a new tag instance
105 	 * 
106 	 * @param theScheme
107 	 *           The tag scheme (the system)
108 	 * @param theTerm
109 	 *           The tag term (the code)
110 	 * @return Returns the newly created tag instance. Note that the tag is added to the list by this method, so you
111 	 *         generally do not need to interact directly with the added tag.
112 	 */
113 	public Tag addTag(String theScheme, String theTerm) {
114 		Tag retVal = new Tag(theScheme, theTerm);
115 		add(retVal);
116 		myOrderedTags = null;
117 		return retVal;
118 	}
119 
120 	/**
121 	 * Add a new tag instance
122 	 * 
123 	 * @param theScheme
124 	 *           The tag scheme
125 	 * @param theTerm
126 	 *           The tag term
127 	 * @param theLabel
128 	 *           The tag label
129 	 * @return Returns the newly created tag instance. Note that the tag is added to the list by this method, so you
130 	 *         generally do not need to interact directly with the added tag.
131 	 */
132 	public Tag addTag(String theScheme, String theTerm, String theLabel) {
133 		Tag retVal = new Tag(theScheme, theTerm, theLabel);
134 		add(retVal);
135 		myOrderedTags = null;
136 		return retVal;
137 	}
138 
139 	@Override
140 	public void clear() {
141 		myOrderedTags = null;
142 		myTagSet.clear();
143 	}
144 
145 	@Override
146 	public boolean contains(Object theO) {
147 		return myTagSet.contains(theO);
148 	}
149 
150 	@Override
151 	public boolean containsAll(Collection<?> theC) {
152 		return myTagSet.containsAll(theC);
153 	}
154 
155 	@Override
156 	public boolean equals(Object obj) {
157 		if (this == obj)
158 			return true;
159 		if (obj == null)
160 			return false;
161 		if (getClass() != obj.getClass())
162 			return false;
163 		TagList other = (TagList) obj;
164 		if (myTagSet == null) {
165 			if (other.myTagSet != null)
166 				return false;
167 		} else if (!myTagSet.equals(other.myTagSet))
168 			return false;
169 		return true;
170 	}
171 
172 	/**
173 	 * Returns the tag at a given index - Note that the TagList is backed by a {@link LinkedHashSet}, so the order of
174 	 * added tags will be consistent, but duplicates will not be preserved.
175 	 */
176 	public Tag get(int theIndex) {
177 		if (myOrderedTags == null) {
178 			myOrderedTags = new ArrayList<Tag>();
179 			for (Tag next : myTagSet) {
180 				myOrderedTags.add(next);
181 			}
182 		}
183 		return myOrderedTags.get(theIndex);
184 	}
185 
186 	public Tag getTag(String theScheme, String theTerm) {
187 		for (Tag next : this) {
188 			if (theScheme.equals(next.getScheme()) && theTerm.equals(next.getTerm())) {
189 				return next;
190 			}
191 		}
192 		return null;
193 	}
194 
195 	public List<Tag> getTagsWithScheme(String theScheme) {
196 		ArrayList<Tag> retVal = new ArrayList<Tag>();
197 		for (Tag next : this) {
198 			if (theScheme.equals(next.getScheme())) {
199 				retVal.add(next);
200 			}
201 		}
202 		return retVal;
203 	}
204 
205 	@Override
206 	public int hashCode() {
207 		return myTagSet.hashCode();
208 	}
209 
210 	@Override
211 	public boolean isEmpty() {
212 		for (Tag next : myTagSet) {
213 			if (next.isEmpty() == false) {
214 				return false;
215 			}
216 		}
217 		return true;
218 	}
219 
220 	@Override
221 	public Iterator<Tag> iterator() {
222 		return myTagSet.iterator();
223 	}
224 
225 	@Override
226 	public boolean remove(Object theO) {
227 		myOrderedTags = null;
228 		return myTagSet.remove(theO);
229 	}
230 
231 	@Override
232 	public boolean removeAll(Collection<?> theC) {
233 		myOrderedTags = null;
234 		return myTagSet.removeAll(theC);
235 	}
236 
237 	@Override
238 	public boolean retainAll(Collection<?> theC) {
239 		myOrderedTags = null;
240 		return myTagSet.retainAll(theC);
241 	}
242 
243 	@Override
244 	public int size() {
245 		return myTagSet.size();
246 	}
247 
248 	@Override
249 	public Object[] toArray() {
250 		return myTagSet.toArray();
251 	}
252 
253 	@Override
254 	public <T> T[] toArray(T[] theA) {
255 		return myTagSet.toArray(theA);
256 	}
257 
258 	/**
259 	 * Returns false
260 	 */
261 	@Override
262 	@CoverageIgnore
263 	public boolean hasFormatComment() {
264 		return false;
265 	}
266 
267 	/**
268 	 * NOT SUPPORTED - Throws {@link UnsupportedOperationException}
269 	 */
270 	@Override
271 	@CoverageIgnore
272 	public List<String> getFormatCommentsPre() {
273 		throw new UnsupportedOperationException();
274 	}
275 
276 	/**
277 	 * NOT SUPPORTED - Throws {@link UnsupportedOperationException}
278 	 */
279 	@Override
280 	@CoverageIgnore
281 	public List<String> getFormatCommentsPost() {
282 		throw new UnsupportedOperationException();
283 	}
284 
285 }