PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/dependencies/jaudiotagger/src/main/java/org/jaudiotagger/audio/generic/AbstractTag.java

http://github.com/tulskiy/musique
Java | 421 lines | 180 code | 53 blank | 188 comment | 33 complexity | e3c2f110254fba65c227a2350b2588a9 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, BSD-3-Clause
  1. /*
  2. * jaudiotagger library
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. package org.jaudiotagger.audio.generic;
  19. import org.jaudiotagger.tag.*;
  20. import org.jaudiotagger.tag.datatype.Artwork;
  21. import java.util.*;
  22. /**
  23. * This class is the default implementation for
  24. * {@link org.jaudiotagger.tag.Tag} and introduces some more useful
  25. * functionality to be implemented.<br>
  26. *
  27. * @author Raphaƫl Slinckx
  28. */
  29. public abstract class AbstractTag implements Tag {
  30. /**
  31. * Stores the amount of {@link TagField} with {@link TagField#isCommon()}
  32. * <code>true</code>.
  33. */
  34. protected int commonNumber = 0;
  35. /**
  36. * This map stores the {@linkplain TagField#getId() ids} of the stored
  37. * fields to the {@linkplain TagField fields} themselves. Because a linked hashMap is used the order
  38. * that they are added in is preserved, the only exception to this rule is when two fields of the same id
  39. * exist, both will be returned according to when the first item was added to the file. <br>
  40. */
  41. protected Map<String, List<TagField>> fields = new LinkedHashMap<String, List<TagField>>();
  42. /**
  43. * Add field
  44. *
  45. * @see org.jaudiotagger.tag.Tag#addField(org.jaudiotagger.tag.TagField)
  46. * <p/>
  47. * Changed so add empty fields
  48. */
  49. public void addField(TagField field) {
  50. if (field == null) {
  51. return;
  52. }
  53. List<TagField> list = fields.get(field.getId());
  54. // There was no previous item
  55. if (list == null) {
  56. list = new ArrayList<TagField>();
  57. list.add(field);
  58. fields.put(field.getId(), list);
  59. if (field.isCommon()) {
  60. commonNumber++;
  61. }
  62. } else {
  63. // We append to existing list
  64. list.add(field);
  65. }
  66. }
  67. /**
  68. * Get list of fields within this tag with the specified id
  69. *
  70. * @see org.jaudiotagger.tag.Tag#getFields(java.lang.String)
  71. */
  72. public List<TagField> getFields(String id) {
  73. List<TagField> list = fields.get(id);
  74. if (list == null) {
  75. return new ArrayList<TagField>();
  76. }
  77. return list;
  78. }
  79. /**
  80. * @param id
  81. * @return
  82. */
  83. //Needs to be overridden
  84. //TODO remove
  85. public List<TagField> getFields(FieldKey id) throws KeyNotFoundException {
  86. List<TagField> list = fields.get(id.name());
  87. if (list == null) {
  88. return new ArrayList<TagField>();
  89. }
  90. return list;
  91. }
  92. /**
  93. * @param id
  94. * @param index
  95. * @return
  96. */
  97. public String getItem(String id, int index) {
  98. List<TagField> l = getFields(id);
  99. return (l.size() > index) ? l.get(index).toString() : "";
  100. }
  101. /**
  102. * Retrieve the first value that exists for this generic key
  103. *
  104. * @param genericKey
  105. * @return
  106. */
  107. public String getFirst(FieldKey genericKey) throws KeyNotFoundException {
  108. return getValue(genericKey, 0);
  109. }
  110. /**
  111. * @param id
  112. * @return
  113. */
  114. public String getFirst(String id) {
  115. List<TagField> l = getFields(id);
  116. return (l.size() != 0) ? l.get(0).toString() : "";
  117. }
  118. /**
  119. * @param id audio specific key
  120. * @return
  121. */
  122. public TagField getFirstField(String id) {
  123. List<TagField> l = getFields(id);
  124. return (l.size() != 0) ? l.get(0) : null;
  125. }
  126. /**
  127. * @see org.jaudiotagger.tag.Tag#getFields()
  128. */
  129. public Iterator<TagField> getFields() {
  130. final Iterator<Map.Entry<String, List<TagField>>> it = this.fields.entrySet().iterator();
  131. return new Iterator<TagField>() {
  132. private Iterator<TagField> fieldsIt;
  133. private void changeIt() {
  134. if (!it.hasNext()) {
  135. return;
  136. }
  137. Map.Entry<String, List<TagField>> e = it.next();
  138. List<TagField> l = e.getValue();
  139. fieldsIt = l.iterator();
  140. }
  141. public boolean hasNext() {
  142. if (fieldsIt == null) {
  143. changeIt();
  144. }
  145. return it.hasNext() || (fieldsIt != null && fieldsIt.hasNext());
  146. }
  147. public TagField next() {
  148. if (!fieldsIt.hasNext()) {
  149. changeIt();
  150. }
  151. return fieldsIt.next();
  152. }
  153. public void remove() {
  154. fieldsIt.remove();
  155. }
  156. };
  157. }
  158. /**
  159. * Return field count
  160. * <p/>
  161. * TODO:There must be a more efficient way to do this.
  162. *
  163. * @return field count
  164. */
  165. public int getFieldCount() {
  166. Iterator it = getFields();
  167. int count = 0;
  168. while (it.hasNext()) {
  169. count++;
  170. it.next();
  171. }
  172. return count;
  173. }
  174. public int getFieldCountIncludingSubValues() {
  175. return getFieldCount();
  176. }
  177. /**
  178. * Does this tag contain any comon fields
  179. *
  180. * @see org.jaudiotagger.tag.Tag#hasCommonFields()
  181. */
  182. public boolean hasCommonFields() {
  183. return commonNumber != 0;
  184. }
  185. /**
  186. * Does this tag contain a field with the specified id
  187. *
  188. * @see org.jaudiotagger.tag.Tag#hasField(java.lang.String)
  189. */
  190. public boolean hasField(String id) {
  191. return getFields(id).size() != 0;
  192. }
  193. /**
  194. * Determines whether the given charset encoding may be used for the
  195. * represented tagging system.
  196. *
  197. * @param enc charset encoding.
  198. * @return <code>true</code> if the given encoding can be used.
  199. */
  200. protected abstract boolean isAllowedEncoding(String enc);
  201. /**
  202. * Is this tag empty
  203. *
  204. * @see org.jaudiotagger.tag.Tag#isEmpty()
  205. */
  206. public boolean isEmpty() {
  207. return fields.size() == 0;
  208. }
  209. /**
  210. * Create new field and set it in the tag
  211. *
  212. * @param genericKey
  213. * @param value
  214. * @throws KeyNotFoundException
  215. * @throws FieldDataInvalidException
  216. */
  217. public void setField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException {
  218. TagField tagfield = createField(genericKey, value);
  219. setField(tagfield);
  220. }
  221. /**
  222. * Create new field and add it to the tag
  223. *
  224. * @param genericKey
  225. * @param value
  226. * @throws KeyNotFoundException
  227. * @throws FieldDataInvalidException
  228. */
  229. public void addField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException {
  230. TagField tagfield = createField(genericKey, value);
  231. addField(tagfield);
  232. }
  233. /**
  234. * Set field
  235. * <p/>
  236. * Changed:Just because field is empty it doesn't mean it should be deleted. That should be the choice
  237. * of the developer. (Or does this break things)
  238. *
  239. * @see org.jaudiotagger.tag.Tag#setField(org.jaudiotagger.tag.TagField)
  240. */
  241. public void setField(TagField field) {
  242. if (field == null) {
  243. return;
  244. }
  245. // If there is already an existing field with same id
  246. // and both are TextFields, we replace the first element
  247. List<TagField> list = fields.get(field.getId());
  248. if (list != null) {
  249. list.set(0, field);
  250. return;
  251. }
  252. // Else we put the new field in the fields.
  253. list = new ArrayList<TagField>();
  254. list.add(field);
  255. fields.put(field.getId(), list);
  256. if (field.isCommon()) {
  257. commonNumber++;
  258. }
  259. }
  260. /**
  261. * The m parameter is effectively ignored
  262. *
  263. * @param id
  264. * @param n
  265. * @param m
  266. * @return
  267. */
  268. public String getSubValue(FieldKey id, int n, int m) {
  269. return getValue(id, n);
  270. }
  271. /**
  272. * Set or add encoding
  273. *
  274. * @see org.jaudiotagger.tag.Tag#setEncoding(java.lang.String)
  275. */
  276. public boolean setEncoding(String enc) {
  277. if (!isAllowedEncoding(enc)) {
  278. return false;
  279. }
  280. Iterator it = getFields();
  281. while (it.hasNext()) {
  282. TagField field = (TagField) it.next();
  283. if (field instanceof TagTextField) {
  284. ((TagTextField) field).setEncoding(enc);
  285. }
  286. }
  287. return true;
  288. }
  289. /**
  290. * (overridden)
  291. *
  292. * @see java.lang.Object#toString()
  293. */
  294. public String toString() {
  295. StringBuffer out = new StringBuffer();
  296. out.append("Tag content:\n");
  297. Iterator it = getFields();
  298. while (it.hasNext()) {
  299. TagField field = (TagField) it.next();
  300. out.append("\t");
  301. out.append(field.getId());
  302. out.append(":");
  303. out.append(field.toString());
  304. out.append("\n");
  305. }
  306. return out.toString().substring(0, out.length() - 1);
  307. }
  308. /**
  309. * @param genericKey
  310. * @param value
  311. * @return
  312. * @throws KeyNotFoundException
  313. * @throws FieldDataInvalidException
  314. */
  315. public abstract TagField createField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException;
  316. /**
  317. * @param genericKey
  318. * @return
  319. * @throws KeyNotFoundException
  320. */
  321. public abstract TagField getFirstField(FieldKey genericKey) throws KeyNotFoundException;
  322. /**
  323. * @param fieldKey
  324. * @throws KeyNotFoundException
  325. */
  326. public abstract void deleteField(FieldKey fieldKey) throws KeyNotFoundException;
  327. /**
  328. * Delete all occurrences of field with this id.
  329. *
  330. * @param key
  331. */
  332. public void deleteField(String key) {
  333. fields.remove(key);
  334. }
  335. public Artwork getFirstArtwork() {
  336. List<Artwork> artwork = getArtworkList();
  337. if (artwork.size() > 0) {
  338. return artwork.get(0);
  339. }
  340. return null;
  341. }
  342. /**
  343. * Create field and then set within tag itself
  344. *
  345. * @param artwork
  346. * @throws FieldDataInvalidException
  347. */
  348. public void setField(Artwork artwork) throws FieldDataInvalidException {
  349. this.setField(createField(artwork));
  350. }
  351. /**
  352. * Create field and then add within tag itself
  353. *
  354. * @param artwork
  355. * @throws FieldDataInvalidException
  356. */
  357. public void addField(Artwork artwork) throws FieldDataInvalidException {
  358. this.addField(createField(artwork));
  359. }
  360. /**
  361. * Delete all instance of artwork Field
  362. *
  363. * @throws KeyNotFoundException
  364. */
  365. public void deleteArtworkField() throws KeyNotFoundException {
  366. this.deleteField(FieldKey.COVER_ART);
  367. }
  368. }