Coverage Report - org.jaudiotagger.tag.id3.framebody.AbstractFrameBodyTextInfo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractFrameBodyTextInfo
97%
33/34
75%
3/4
1.25
 
 1  
 /**
 2  
  *  @author : Paul Taylor
 3  
  *  @author : Eric Farng
 4  
  *
 5  
  *  Version @version:$Id: AbstractFrameBodyTextInfo.java,v 1.19 2008/07/21 10:45:42 paultaylor Exp $
 6  
  *
 7  
  *  MusicTag Copyright (C)2003,2004
 8  
  *
 9  
  *  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
 10  
  *  General Public  License as published by the Free Software Foundation; either version 2.1 of the License,
 11  
  *  or (at your option) any later version.
 12  
  *
 13  
  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 14  
  *  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 15  
  *  See the GNU Lesser General Public License for more details.
 16  
  *
 17  
  *  You should have received a copy of the GNU Lesser General Public License along with this library; if not,
 18  
  *  you can get a copy from http://www.opensource.org/licenses/lgpl-license.php or write to the Free Software
 19  
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 20  
  *
 21  
  * Description:
 22  
  */
 23  
 package org.jaudiotagger.tag.id3.framebody;
 24  
 
 25  
 import org.jaudiotagger.logging.ErrorMessage;
 26  
 import org.jaudiotagger.tag.InvalidTagException;
 27  
 import org.jaudiotagger.tag.datatype.DataTypes;
 28  
 import org.jaudiotagger.tag.datatype.NumberHashMap;
 29  
 import org.jaudiotagger.tag.datatype.TextEncodedStringSizeTerminated;
 30  
 import org.jaudiotagger.tag.id3.ID3TextEncodingConversion;
 31  
 import org.jaudiotagger.tag.id3.valuepair.TextEncoding;
 32  
 
 33  
 import java.io.ByteArrayOutputStream;
 34  
 import java.nio.ByteBuffer;
 35  
 
 36  
 /**
 37  
  * Abstract representation of a Text Frame
 38  
  * <p/>
 39  
  * The text information frames are often the most important frames, containing information like artist, album and
 40  
  * more. There may only be  one text information frame of its kind in an tag. In ID3v24 All text information frames
 41  
  * supports multiple strings, stored as a null separated list, where null is represented by the termination code
 42  
  * for the character encoding. All text frame identifiers begin with "T". Only text frame identifiers begin with "T",
 43  
  * with the exception of the "TXXX" frame. All the text information frames have the following  format:
 44  
  * <Header for 'Text information frame', ID: "T000" - "TZZZ",
 45  
  * excluding "TXXX" described in 4.2.6.>
 46  
  * Text encoding                $xx
 47  
  * Information                  <text string(s) according to encoding>
 48  
  * <p/>
 49  
  * The list of valid text encodings increaded from two in ID3v23 to four in ID3v24
 50  
  * <p/>
 51  
  * iTunes incorrectly writes null terminators at the end of every String, even though it only writes one String.
 52  
  * <p/>
 53  
  * You can retrieve the first value without the null terminator using {@link #getFirstTextValue}
 54  
  */
 55  
 public abstract class AbstractFrameBodyTextInfo extends AbstractID3v2FrameBody
 56  
 {
 57  
 
 58  
     /**
 59  
      * Creates a new FrameBodyTextInformation datatype. The super.super
 60  
      * Constructor sets up the Object list for the frame.
 61  
      */
 62  
     protected AbstractFrameBodyTextInfo()
 63  
     {
 64  305
         super();
 65  305
         setObjectValue(DataTypes.OBJ_TEXT_ENCODING, TextEncoding.ISO_8859_1);
 66  305
         setObjectValue(DataTypes.OBJ_TEXT, "");
 67  305
     }
 68  
 
 69  
     /**
 70  
      * Copy Constructor
 71  
      *
 72  
      * @param body AbstractFrameBodyTextInformation
 73  
      */
 74  
     protected AbstractFrameBodyTextInfo(AbstractFrameBodyTextInfo body)
 75  
     {
 76  937
         super(body);
 77  937
     }
 78  
 
 79  
     /**
 80  
      * Creates a new FrameBodyTextInformation datatype. This is used when user
 81  
      * wants to create a new frame based on data in a user interface.
 82  
      *
 83  
      * @param textEncoding Specifys what encoding should be used to write
 84  
      *                     text to file.
 85  
      * @param text         Specifies the text String.
 86  
      */
 87  
     protected AbstractFrameBodyTextInfo(byte textEncoding, String text)
 88  
     {
 89  48
         super();
 90  48
         setObjectValue(DataTypes.OBJ_TEXT_ENCODING, textEncoding);
 91  48
         setObjectValue(DataTypes.OBJ_TEXT, text);
 92  48
     }
 93  
 
 94  
     /**
 95  
      * Creates a new FrameBodyTextInformation datatype from file.
 96  
      * <p/>
 97  
      * <p>The super.super Constructor sets up the Object list for the frame.
 98  
      *
 99  
      * @throws InvalidTagException if unable to create framebody from buffer
 100  
      */
 101  
     protected AbstractFrameBodyTextInfo(ByteBuffer byteBuffer, int frameSize) throws InvalidTagException
 102  
     {
 103  1206
         super(byteBuffer, frameSize);
 104  1206
     }
 105  
 
 106  
     /**
 107  
      * Set the Full Text String.
 108  
      * <p/>
 109  
      * <p>If this String contains null terminator characters these are parsed as value
 110  
      * seperators, allowing you to hold multiple strings within one text frame. This functionality is only
 111  
      * officially support in ID3v24.
 112  
      *
 113  
      * @param text to set
 114  
      */
 115  
     public void setText(String text)
 116  
     {
 117  130
         if (text == null)
 118  
         {
 119  0
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 120  
         }
 121  130
         setObjectValue(DataTypes.OBJ_TEXT, text);
 122  130
     }
 123  
 
 124  
 
 125  
     /**
 126  
      * Retrieve the complete Text String.
 127  
      *
 128  
      * @return the text string
 129  
      */
 130  
     public String getText()
 131  
     {
 132  669
         return (String) getObjectValue(DataTypes.OBJ_TEXT);
 133  
     }
 134  
 
 135  
     /**
 136  
      * Get first value
 137  
      *
 138  
      * @return value at index 0
 139  
      */
 140  
     public String getFirstTextValue()
 141  
     {
 142  155
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 143  155
         return text.getValueAtIndex(0);
 144  
     }
 145  
 
 146  
     /**
 147  
      * Get value at index
 148  
      *
 149  
      * @param index
 150  
      * @return value at index
 151  
      */
 152  
     public String getValueAtIndex(int index)
 153  
     {
 154  3
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 155  3
         return text.getValueAtIndex(index);
 156  
     }
 157  
 
 158  
     /**
 159  
      * Add additional value to value
 160  
      *
 161  
      * @param value at index
 162  
      */
 163  
     public void addTextValue(String value)
 164  
     {
 165  1
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 166  1
         text.addValue(value);
 167  1
     }
 168  
 
 169  
     /**
 170  
      * @return number of text values, usually one
 171  
      */
 172  
     public int getNumberOfValues()
 173  
     {
 174  4
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 175  4
         return text.getNumberOfValues();
 176  
     }
 177  
 
 178  
     /**
 179  
      * Because Text frames have a text encoding we need to check the text
 180  
      * String does not contain characters that cannot be encoded in
 181  
      * current encoding before we write data. If there are change the text
 182  
      * encoding.
 183  
      */
 184  
     public void write(ByteArrayOutputStream tagBuffer)
 185  
     {
 186  
         //Ensure valid for type
 187  743
         setTextEncoding(ID3TextEncodingConversion.getTextEncoding(getHeader(), getTextEncoding()));
 188  
 
 189  
         //Ensure valid for data
 190  743
         if (((TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT)).canBeEncoded() == false)
 191  
         {
 192  6
             this.setTextEncoding(ID3TextEncodingConversion.getUnicodeTextEncoding(getHeader()));
 193  
         }
 194  743
         super.write(tagBuffer);
 195  743
     }
 196  
 
 197  
     /**
 198  
      * Setup the Object List. All text frames contain a text encoding
 199  
      * and then a text string.
 200  
      * <p/>
 201  
      * TODO:would like to make final but cannnot because overriden by FrameBodyTXXX
 202  
      */
 203  
     protected void setupObjectList()
 204  
     {
 205  1277
         objectList.add(new NumberHashMap(DataTypes.OBJ_TEXT_ENCODING, this, TextEncoding.TEXT_ENCODING_FIELD_SIZE));
 206  1277
         objectList.add(new TextEncodedStringSizeTerminated(DataTypes.OBJ_TEXT, this));
 207  1277
     }
 208  
 }