EMMA Coverage Report (generated Tue Mar 14 21:50:42 EST 2006)
[all classes][org.farng.mp3.filename]

COVERAGE SUMMARY FOR SOURCE FILE [FilenameTagBuilder.java]

nameclass, %method, %block, %line, %
FilenameTagBuilder.java100% (1/1)90%  (9/10)71%  (395/555)77%  (109/142)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FilenameTagBuilder100% (1/1)90%  (9/10)71%  (395/555)77%  (109/142)
FilenameTagBuilder (): void 0%   (0/1)0%   (0/3)0%   (0/2)
parseEndWordDelimiter (String): String [] 100% (1/1)24%  (15/62)36%  (5/14)
parseStartWordDelimiter (String): String [] 100% (1/1)51%  (29/57)64%  (9/14)
createCompositeFromToken (String): AbstractFilenameComposite 100% (1/1)64%  (119/185)67%  (33/49)
parseParenthesis (String): String [] 100% (1/1)85%  (93/109)96%  (23/24)
createEmptyFilenameTag (): FilenameTag 100% (1/1)100% (11/11)100% (3/3)
createFilenameTagFromMP3File (MP3File): FilenameTag 100% (1/1)100% (53/53)100% (16/16)
parseDelimiter (String): String [] 100% (1/1)100% (49/49)100% (12/12)
updateCompositeFromAllOption (AbstractFilenameComposite): void 100% (1/1)100% (13/13)100% (4/4)
updateCompositeFromAllTag (AbstractFilenameComposite, MP3File): void 100% (1/1)100% (13/13)100% (4/4)

1package org.farng.mp3.filename;
2 
3import org.farng.mp3.MP3File;
4import org.farng.mp3.TagException;
5import org.farng.mp3.TagOptionSingleton;
6import org.farng.mp3.TagUtility;
7import org.farng.mp3.id3.ID3v2_4;
8 
9import java.util.Iterator;
10 
11/**
12 * This class builds a <code>FilenameTag</code>. The main method to call is <code>createFilenameTagFromMP3File</code>.
13 * Other methods are public in order to update parts of the tag if needed.
14 *
15 * @author Eric Farng
16 * @version $Revision: 1.2 $
17 */
18public class FilenameTagBuilder {
19 
20    private FilenameTagBuilder() {
21        super();
22    }
23 
24    /**
25     * Creates a FilenameComposite tree with the given string. It is parsed according to the different values that can
26     * be set in <code>TagOptionSingleton</code> class
27     *
28     * @param token filename to parse
29     *
30     * @return FilenameComposite tree representing the given token.
31     *
32     * @throws TagException is thrown if there are unmatched parenthesis
33     */
34    public static AbstractFilenameComposite createCompositeFromToken(final String token) throws TagException {
35        String[] splitToken;
36        AbstractFilenameComposite composite = null;
37        final AbstractFilenameComposite beforeComposite;
38        final AbstractFilenameComposite middleComposite;
39        final AbstractFilenameComposite afterComposite;
40        splitToken = parseParenthesis(token);
41        if (splitToken != null) {
42            composite = new FilenameParenthesis();
43            ((FilenameParenthesis) composite).setOpenDelimiter(splitToken[0]);
44            beforeComposite = createCompositeFromToken(splitToken[2]);
45            ((FilenameParenthesis) composite).setBeforeComposite(beforeComposite);
46            middleComposite = createCompositeFromToken(splitToken[3]);
47            ((FilenameParenthesis) composite).setMiddleComposite(middleComposite);
48            afterComposite = createCompositeFromToken(splitToken[4]);
49            ((FilenameParenthesis) composite).setAfterComposite(afterComposite);
50            composite.setOriginalToken(token);
51            return composite;
52        }
53        splitToken = parseDelimiter(token);
54        if (splitToken != null) {
55            composite = new FilenameDelimiter();
56            ((FilenameDelimiter) composite).setDelimiter(splitToken[0]);
57            beforeComposite = createCompositeFromToken(splitToken[1]);
58            ((FilenameDelimiter) composite).setBeforeComposite(beforeComposite);
59            afterComposite = createCompositeFromToken(splitToken[2]);
60            ((FilenameDelimiter) composite).setAfterComposite(afterComposite);
61            composite.setOriginalToken(token);
62            return composite;
63        }
64        splitToken = parseStartWordDelimiter(token);
65        if (splitToken != null) {
66            composite = new FilenameStartWordDelimiter();
67            ((FilenameDelimiter) composite).setDelimiter(splitToken[0]);
68            beforeComposite = createCompositeFromToken(splitToken[1]);
69            ((FilenameStartWordDelimiter) composite).setBeforeComposite(beforeComposite);
70            afterComposite = createCompositeFromToken(splitToken[2]);
71            ((FilenameStartWordDelimiter) composite).setAfterComposite(afterComposite);
72            composite.setOriginalToken(token);
73            return composite;
74        }
75        splitToken = parseEndWordDelimiter(token);
76        if (splitToken != null) {
77            composite = new FilenameEndWordDelimiter();
78            ((FilenameDelimiter) composite).setDelimiter(splitToken[0]);
79            beforeComposite = createCompositeFromToken(splitToken[1]);
80            ((FilenameEndWordDelimiter) composite).setBeforeComposite(beforeComposite);
81            afterComposite = createCompositeFromToken(splitToken[2]);
82            ((FilenameEndWordDelimiter) composite).setAfterComposite(afterComposite);
83            composite.setOriginalToken(token);
84            return composite;
85        }
86        if (token != null && token.trim().length() > 0) {
87            composite = new FilenameToken();
88            ((FilenameToken) composite).setToken(token.trim());
89            composite.setOriginalToken(token);
90            return composite;
91        }
92        return composite;
93    }
94 
95    public static FilenameTag createEmptyFilenameTag() {
96        final FilenameTag filenameTag = new FilenameTag();
97        filenameTag.setId3tag(new ID3v2_4());
98        return filenameTag;
99    }
100 
101    /**
102     * This method will create a complete FilenameTag from the given mp3File and from the options in
103     * <code>TagOptionSingleton</code>. This will call all other necessary methods in this builder class.
104     *
105     * @param mp3File MP3 file to create the FilenameTag from.
106     *
107     * @return FilenameTag of the mp3File argument
108     *
109     * @throws Exception is thrown on any IO errors, or parsing errors such as unmatched parenthesis
110     */
111    public static FilenameTag createFilenameTagFromMP3File(final MP3File mp3File) throws Exception {
112        FilenameTag filenameTag = null;
113        if (mp3File.getMp3file() != null) {
114            filenameTag = new FilenameTag();
115            final AbstractFilenameComposite composite;
116            final ID3v2_4 id3tag;
117            String filename = mp3File.getMp3file().getName();
118            final int index = filename.lastIndexOf((int) '.');
119            if (index >= 0) {
120                filenameTag.setExtension(filename.substring(index + 1));
121                filename = filename.substring(0, index);
122            }
123 
124            // create composite
125            composite = createCompositeFromToken(filename);
126            updateCompositeFromAllTag(composite, mp3File);
127            updateCompositeFromAllOption(composite);
128 
129            // create tag
130            id3tag = composite.createId3Tag();
131 
132            // assign values;
133            filenameTag.setMp3file(mp3File);
134            filenameTag.setComposite(composite);
135            filenameTag.setId3tag(id3tag);
136        }
137        return filenameTag;
138    }
139 
140    /**
141     * Traverse the composite and set the class field to match keywords found in TagOptionSingleton.
142     *
143     * @param composite composite to update.
144     */
145    public static void updateCompositeFromAllOption(final AbstractFilenameComposite composite) {
146        final Iterator iterator = TagOptionSingleton.getInstance().getKeywordIterator();
147        while (iterator.hasNext()) {
148            composite.matchAgainstKeyword((Class) iterator.next());
149        }
150    }
151 
152    /**
153     * Traverse the composite and set the class field to match frames from all three other tags that are already found
154     * in the MP3 file.
155     *
156     * @param composite composite to update
157     * @param mp3File   mp3file to match all it's tags against.
158     */
159    public static void updateCompositeFromAllTag(final AbstractFilenameComposite composite, final MP3File mp3File) {
160        composite.matchAgainstTag(mp3File.getID3v1Tag());
161        composite.matchAgainstTag(mp3File.getID3v2Tag());
162        composite.matchAgainstTag(mp3File.getLyrics3Tag());
163    }
164 
165    /**
166     * Parses the given token into two halves with the delimiters found in <code> TagOptionSingleton</code>
167     *
168     * @param token token to split
169     *
170     * @return index 0 is the delimiter. index 1 and 2 are the before and after tokens respectively.
171     */
172    private static String[] parseDelimiter(final String token) {
173        String[] tokenArray = null;
174        if (token != null && token.length() > 0) {
175            final Iterator iterator = TagOptionSingleton.getInstance().getFilenameDelimiterIterator();
176            int index;
177            String delimiter;
178            while (iterator.hasNext()) {
179                delimiter = (String) iterator.next();
180                index = token.indexOf(delimiter);
181                if (index >= 0) {
182                    tokenArray = new String[3];
183                    tokenArray[0] = delimiter;
184                    tokenArray[1] = token.substring(0, index);
185                    tokenArray[2] = token.substring(index + delimiter.length());
186                }
187            }
188        }
189        return tokenArray;
190    }
191 
192    /**
193     * Parses the given token into two halves with the delimiters found in <code> TagOptionSingleton</code>
194     *
195     * @param token token to split
196     *
197     * @return index 0 is the delimiter. index 1 and 2 are the before and after tokens respectively.
198     */
199    private static String[] parseEndWordDelimiter(final String token) {
200        String[] tokenArray = null;
201        if (token != null && token.length() > 0) {
202            final Iterator iterator = TagOptionSingleton.getInstance().getEndWordDelimiterIterator();
203            int index;
204            String delimiter;
205            while (iterator.hasNext()) {
206                delimiter = (String) iterator.next();
207                if (token.endsWith(delimiter)) {
208                    index = token.substring(0, token.length() - delimiter.length()).indexOf(delimiter);
209                } else {
210                    index = token.indexOf(delimiter);
211                }
212                if (index > 0) {
213                    tokenArray = new String[3];
214                    tokenArray[0] = delimiter;
215                    tokenArray[1] = token.substring(0, index);
216                    tokenArray[2] = token.substring(index);
217                }
218            }
219        }
220        return tokenArray;
221    }
222 
223    /**
224     * Given a specific token, parse it into halves according to the <code>TagOptionSingleton</code>
225     *
226     * @param token token to split.
227     *
228     * @return index 0 and 1 are the parenthesis delimiters. index 2, 3, 4 are before, middle, and after respectively.
229     */
230    private static String[] parseParenthesis(final String token) throws TagException {
231        String[] tokenArray = null;
232        if (token != null && token.length() > 0) {
233            final TagOptionSingleton option = TagOptionSingleton.getInstance();
234            String tempOpen;
235            String open = "";
236            final String close;
237            int openIndex = token.length();
238            int tempIndex;
239            final int closeIndex;
240            final Iterator iterator = option.getOpenParenthesisIterator();
241 
242            // find first parenthesis
243            while (iterator.hasNext()) {
244                tempOpen = (String) iterator.next();
245                tempIndex = token.indexOf(tempOpen);
246                if (tempIndex >= 0 && tempIndex < openIndex) {
247                    openIndex = tempIndex;
248                    open = tempOpen;
249                }
250            }
251 
252            // we have a parenthesis
253            if (openIndex >= 0 && openIndex < token.length()) {
254                close = option.getCloseParenthesis(open);
255                closeIndex = TagUtility.findMatchingParenthesis(token, openIndex);
256                if (closeIndex < 0) {
257                    throw new TagException("Unmatched parenthesis in \"" + token + "\" at position : " + openIndex);
258                }
259                tokenArray = new String[5];
260                tokenArray[0] = open;
261                tokenArray[1] = close;
262                tokenArray[2] = token.substring(0, openIndex);
263                tokenArray[3] = token.substring(openIndex + open.length(), closeIndex);
264                tokenArray[4] = token.substring(closeIndex + close.length());
265            }
266        }
267        return tokenArray;
268    }
269 
270    /**
271     * Parses the given token into two halves with the delimiters found in <code> TagOptionSingleton</code>
272     *
273     * @param token token to split
274     *
275     * @return index 0 is the delimiter. index 1 and 2 are the before and after tokens respectively.
276     */
277    private static String[] parseStartWordDelimiter(final String token) {
278        String[] tokenArray = null;
279        if (token != null && token.length() > 0) {
280            final Iterator iterator = TagOptionSingleton.getInstance().getStartWordDelimiterIterator();
281            int index;
282            String delimiter;
283            while (iterator.hasNext()) {
284                delimiter = (String) iterator.next();
285                if (token.startsWith(delimiter)) {
286                    index = token.indexOf(delimiter, delimiter.length());
287                } else {
288                    index = token.indexOf(delimiter);
289                }
290                if (index > 0) {
291                    tokenArray = new String[3];
292                    tokenArray[0] = delimiter;
293                    tokenArray[1] = token.substring(0, index);
294                    tokenArray[2] = token.substring(index);
295                }
296            }
297        }
298        return tokenArray;
299    }
300}

[all classes][org.farng.mp3.filename]
EMMA 2.0.5312 (C) Vladimir Roubtsov