/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): N/A. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.content.mp3.parser; // Standard Java import java.io.*; // Apache logging import org.apache.log4j.*; // Mp3 Library import org.blinkenlights.id3.*; import org.blinkenlights.id3.v1.*; // JRDF import org.jrdf.graph.mem.*; import org.jrdf.graph.*; import org.jrdf.util.ClosableIterator; import org.jrdf.vocabulary.RDF; // JUnit import junit.framework.TestCase; import junit.framework.TestSuite; // Internal packages import org.mulgara.content.mp3.parser.api.*; import org.mulgara.content.mp3.parser.exception.*; /** * Unit testing for the ID3 tag parsing classes. * * @created 2004-08-19 * * @author Mark Ludlow * * @version $Revision: 1.9 $ * * @modified $Date: 2005/01/11 07:02:24 $ by $Author: newmana $ * * @company <a href="mailto:info@PIsoftware.com">Plugged In Software</a> * * @copyright © 2004 <a href="http://www.PIsoftware.com/">Plugged In * Software Pty Ltd</a> * * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class ID3ParsersUnitTest extends TestCase { /** The category to log to. */ private static Logger log = Logger.getLogger(ID3ParsersUnitTest.class); /** * Constructor as required by JUnit's TestCase. */ public ID3ParsersUnitTest(String name) { super(name); // load the logging configuration // BasicConfigurator.configure(); // try { // // DOMConfigurator.configure(new URL(System.getProperty( // "log4j.configuration"))); // } // catch (MalformedURLException mue) { // // log.error( // "Unable to configure logging service from XML configuration " + // "file", mue); // } } /** * Setup data which will be used by all the test cases in this class. * Overrides TestCase.setUp(). */ protected void setUp() { } /** * Clean up data set up by setUp(). * Overrides TestCase.tearDown(). */ protected void tearDown() { } /** * Creates a test suite with various different output and compares the output. */ public static TestSuite suite() { TestSuite suite = new TestSuite(); // The test cases we want run during testing suite.addTest(new ID3ParsersUnitTest("testProcessID3v1")); suite.addTest(new ID3ParsersUnitTest("testProcessID3v2")); return suite; } /** * Test the process method of an MP3ToRdf entity extraction to XML conversion. */ public void testProcessID3v1() { if (log.isDebugEnabled()) { log.debug("// Starting processing ID3v1 test"); } try { // Initialise the parser factory ParserFactory.getInstance().initialiseFactory(); } catch (FactoryException factoryException) { // If we can't initialise the factory log the error log.error("Unable to initialise factory for ID3v1 parsing.", factoryException); // Fail the test fail("Unable to initialise factory for ID3v1 parsing."); } // Create a file pointing to an mp3 File mp3File = new File(System.getProperty("cvs.root") + "/tmp/mp3/kp068-karaoke-tundra-02-green-parrot.mp3"); // Container for an MP3 file MP3File file = null; ID3V1Tags id3v1 = null; try { // Create an MP3File out of the file file = new MP3File(mp3File); // Get the v1 tag of the file id3v1 = file.getID3V1Tags(); } catch (ID3Exception tagException) { // Log the error log.error("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath(), tagException); // Fail the test fail("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath()); } if (id3v1 == null) { // If the tag does not exist then create a new one id3v1 = new ID3V1_0Tags(); } // Set the tag values id3v1.setAlbum("Residence"); id3v1.setArtist("Karaoke Tundra"); id3v1.setComment("http://www.kikapu.com"); id3v1.setGenre(ID3V1Tags.Genre.Electronic); id3v1.setTitle("Green & Parrot"); id3v1.setYear("2004"); // Store the tag in the mp3 try { file.sync(); } catch (ID3Exception tagException) { // Log the error log.error("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath(), tagException); // Fail the test fail("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath()); } try { // Delete the v2 tag if (log.isDebugEnabled()) { try { log.debug("-- " + file.getID3V2Tags()); } catch (ID3Exception tagException) { // Log the error log.error("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath(), tagException); // Fail the test fail("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath()); } } file.removeID3V2Tags(); } catch (ID3Exception tagException) { // Log the error log.error("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath(), tagException); // Fail the test fail("Invalid tags were found in MP3 file: " + mp3File.getAbsolutePath()); } try { // Store the changes file.sync(); } catch (ID3Exception tagException) { // Log the error log.error("Unable to save MP3 file: " + mp3File.getAbsolutePath(), tagException); // Fail the test fail("Unable to save MP3 file: " + mp3File.getAbsolutePath()); } // Container for our graph Graph model = null; try { // Create a model to store our statements in model = new GraphImpl(); } catch (GraphException graphException) { // Log the error log.error("Unable to create a new graph to store parsed RDF in.", graphException); // Fail the test fail("Unable to create a new graph to store parsed RDF in."); } // Container for the parsing results MP3Conversion conversion = new MP3Conversion(file, model, mp3File.toURI()); // Container for our parser ID3Parser parser = null; try { // Create a parser for our test parser = ParserFactory.getInstance().createID3Parser(); } catch (FactoryException factoryException) { // If we cannot create a parser then log the error log.error("Unable to create an ID3 Parser from the factory.", factoryException); // Fail the test fail("Unable to create an ID3 Parser from the factory."); } try { // Parse the tags into a model parser.parseTags(conversion); } catch (ParserException parserException) { // Log the error log.error("Unable to parse the ID3v1 tags to a model.", parserException); // Fail the test fail("Unable to parse the ID3v1 tags to a model."); } if (log.isDebugEnabled()) { try { // Get all statements in the graph ClosableIterator<Triple> iterator = model.find(null, null, null); while (iterator.hasNext()) { // Obtain the next triple Triple triple = (Triple) iterator.next(); log.debug(">> Graph triple [" + triple.getSubject() + ", " + triple.getPredicate() + ", " + triple.getObject() + "]"); } } catch (GraphException graphException) { // Log the error log.error("Unable to debug statements of graph.", graphException); // Fail the test fail("Unable to debug statements of graph."); } } // Container for our processor instance IdentifierProcessor processor = new IdentifierProcessor(); try { // Populate the processor processor.createMappings(model); } catch (IdentifierException identifierException) { // Log the error log.error("Unable to initialise the identifier processor.", identifierException); // Fail the test fail("Unable to initialise the identifier processor."); } try { // Create a resource object to match the resource name we gave the mp3 data // plus the id3 v1 tag information model.getElementFactory().createResource(); // Create a property to signify the type PredicateNode property = model.getElementFactory().createResource(RDF.TYPE); // create a resource to represent the ID3v1 type ObjectNode typeResource = (ObjectNode) processor.resolveIdentifier( IdentifierProcessor.MP3_TYPE); // Check that we have the correct type assertTrue("Type was not MP3 as expected for id3v1 resource.", model.contains(null, property, typeResource)); // Create a property to signify the album property = processor.resolveIdentifier(IdentifierProcessor.TALB); // Check that we have the correct album assertTrue("Album was not 'Residence' as expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "Residence"))); // Create a property to signify the artist property = processor.resolveIdentifier(IdentifierProcessor.TCOM); // Check that we have the correct artist assertTrue( "Artist was not 'Karaoke Tundra' as expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "Karaoke Tundra"))); // Create a property to signify the comment property = processor.resolveIdentifier(IdentifierProcessor.COMM); // Check that we have the correct comment assertTrue( "Comment was not 'http://www.kikapu.com' as expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "http://www.kikapu.com"))); // Create a property to signify the genre property = processor.resolveIdentifier(IdentifierProcessor.MCDI); // Check that we have the correct genre assertTrue("Genre was not " + ID3V1Tags.Genre.Electronic + " as " + "expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createLiteral(ID3V1Tags.Genre.Electronic.toString()))); // Create a property to signify the title property = processor.resolveIdentifier(IdentifierProcessor.TOAL); // Check that we have the correct title assertTrue( "Title was not 'Green & Parrot' as expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "Green & Parrot"))); // Create a property to signify the release year property = processor.resolveIdentifier(IdentifierProcessor.TYER); // Check that we have the correct release year assertTrue("Title was not '2004' as expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createLiteral("2004"))); // Create a property to signify the uri property = processor.resolveIdentifier(IdentifierProcessor.MP3_URI); // Check that we have the correct uri assertTrue("Uri was not '" + mp3File.toURI() + "' as expected for id3v1 resource.", model.contains(null, property, model.getElementFactory().createResource( mp3File.toURI()))); } catch (GraphException graphException) { // Log the error log.error("Unable to perform contains for graph content comparison.", graphException); // Fail the test fail("Unable to perform contains for graph content comparison."); } catch (GraphElementFactoryException graphElementFactoryException) { // Log the error log.error("Unable to create node for graph element comparison.", graphElementFactoryException); // Fail the test fail("Unable to create node for graph element comparison."); } if (log.isDebugEnabled()) { log.debug("// Finished processing test"); } } /** * Test the process method of an MP3ToRdf entity extraction to XML conversion. */ public void testProcessID3v2() { if (log.isDebugEnabled()) { log.debug("// Starting processing ID3v2 test"); } try { // Initialise the parser factory ParserFactory.getInstance().initialiseFactory(); } catch (FactoryException factoryException) { // If we can't initialise the factory log the error log.error("Unable to initialise factory for ID3v2 parsing.", factoryException); // Fail the test fail("Unable to initialise factory for ID3v2 parsing."); } // Create a file pointing to an mp3 File mp3File = new File(System.getProperty("cvs.root") + "/tmp/mp3/Chrono_Trigger_600_AD_in_Piano.mp3"); // Container for an MP3 file MP3File file = null; // Create an MP3File out of the file file = new MP3File(mp3File); // Container for our graph Graph model = null; try { // Create a model to store our statements in model = new GraphImpl(); } catch (GraphException graphException) { // Log the error log.error("Unable to create a new graph to store parsed RDF in.", graphException); // Fail the test fail("Unable to create a new graph to store parsed RDF in."); } // Container for the parsing results MP3Conversion conversion = new MP3Conversion(file, model, mp3File.toURI()); // Container for our parser ID3Parser parser = null; try { // Create a parser for our test parser = ParserFactory.getInstance().createID3Parser(); } catch (FactoryException factoryException) { // If we cannot create a parser then log the error log.error("Unable to create an ID3 Parser from the factory.", factoryException); // Fail the test fail("Unable to create an ID3 Parser from the factory."); } try { // Parse the tags into a model parser.parseTags(conversion); } catch (ParserException parserException) { // Log the error log.error("Unable to parse the ID3v2 tags to a model.", parserException); // Fail the test fail("Unable to parse the ID3v2 tags to a model."); } // if (log.isDebugEnabled()) { try { // Get all statements in the graph ClosableIterator<Triple> iterator = model.find(null, null, null); while (iterator.hasNext()) { // Get the next triple Triple triple = (Triple) iterator.next(); System.err.println(">> Graph triple [" + triple.getSubject() + ", " + triple.getPredicate() + ", " + triple.getObject() + "]"); } } catch (GraphException graphException) { // Log the error log.error("Unable to debug statements of graph.", graphException); // Fail the test fail("Unable to debug statements of graph."); } // } // Container for our processor instance IdentifierProcessor processor = new IdentifierProcessor(); try { // Populate the processor processor.createMappings(model); } catch (IdentifierException identifierException) { // Log the error log.error("Unable to initialise the identifier processor.", identifierException); // Fail the test fail("Unable to initialise the identifier processor."); } try { // Create a property to signify the type PredicateNode property = model.getElementFactory().createResource(RDF. TYPE); // Create a resource to represent the MP3 type ObjectNode typeResource = (ObjectNode) processor.resolveIdentifier( IdentifierProcessor.MP3_TYPE); // Check that we have the correct type assertTrue("Type was not MP3 as expected for id3v2 resource.", model.contains(null, property, typeResource)); // Create a property to signify the artist property = processor.resolveIdentifier(IdentifierProcessor.TCOM); // Check that we have the correct artist assertTrue( "Artist was not 'Yasunori Mitsuda' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "Yasunori Mitsuda"))); // Create a property to signify the title description property = processor.resolveIdentifier(IdentifierProcessor.TIT2); // Check that we have the correct title description assertTrue("Title description was not 'Chrono Trigger 600 A.D. in Piano OC Remix' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "Chrono Trigger 600 A.D. in Piano OC Remix"))); // // Create a property to signify the tagging time // property = processor.resolveIdentifier(processor.TDTG); // // // Check that we have the correct tagging time // assertTrue( // "Tagging time was not '2003-09-16T22:20:22' as expected for id3v2 resource.", // model.contains(null, property, // model.getElementFactory().createLiteral( // "2003-09-16T22:20:22"))); // Create a property to signify the copyright message property = processor.resolveIdentifier(IdentifierProcessor.TCOP); // Check that we have the correct copyright message assertTrue( "Copyright message was not 'Squaresoft' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral("Squaresoft"))); // // Create a property to signify the unknown // property = processor.resolveIdentifier("unknown"); // // // Check that we have the correct unknown // assertTrue("Unknown was not 'Helium12ID' as expected for id3v2 resource.", // model.contains(null, property, // model.getElementFactory().createLiteral("Helium12ID"))); // // Create a property to signify the subtitle // property = processor.resolveIdentifier(processor.TIT3); // // // Check that we have the correct subtitle // assertTrue("Subtitle was not 'OCR01040' as expected for id3v2 resource.", // model.contains(null, property, // model.getElementFactory().createLiteral( // "OCR01040"))); // Create a property to signify the release type property = processor.resolveIdentifier(IdentifierProcessor.TCON); // Check that we have the correct release type assertTrue("Release type was not 'Game' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral("Game"))); // Create a property to signify the BPM property = processor.resolveIdentifier(IdentifierProcessor.TBPM); // Check that we have the correct BPM assertTrue("BPM was not '00000' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral("0"))); // Create a property to signify the lead performer property = processor.resolveIdentifier(IdentifierProcessor.TPE1); if (log.isDebugEnabled()) { log.debug(">> Searching for triple [blank_node, " + property + ", " + model.getElementFactory().createLiteral( "kLuTz") + "]"); } // Check that we have the correct lead performer assertTrue( "Lead performer was not 'kLuTz' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral("kLuTz"))); // Create a property to signify the original performer property = processor.resolveIdentifier(IdentifierProcessor.TOPE); // Check that we have the correct original performer assertTrue( "Original performer was not 'SNES' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral("SNES"))); // Create a property to signify the album property = processor.resolveIdentifier(IdentifierProcessor.TALB); // Check that we have the correct album assertTrue( "Album was not 'http://www.ocremix.org' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "http://www.ocremix.org"))); // // Create a property to signify the recording time // property = processor.resolveIdentifier(processor.TDRC); // // // Check that we have the correct recording time // assertTrue( // "Recording time was not '2003-09-16' as expected for id3v2 resource.", // model.contains(null, property, // model.getElementFactory().createLiteral("2003-09-16"))); // Create a property to signify the original title property = processor.resolveIdentifier(IdentifierProcessor.TOAL); // Check that we have the correct original title assertTrue( "Original title was not 'Chrono Trigger' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createLiteral( "Chrono Trigger"))); // Create a property to signify the uri property = processor.resolveIdentifier(IdentifierProcessor.MP3_URI); // Check that we have the correct uri assertTrue("Uri was not '" + mp3File.toURI() + "' as expected for id3v2 resource.", model.contains(null, property, model.getElementFactory().createResource( mp3File.toURI()))); } catch (GraphException graphException) { // Log the error log.error("Unable to perform contains for graph content comparison.", graphException); // Fail the test fail("Unable to perform contains for graph content comparison."); } catch (GraphElementFactoryException graphElementFactoryException) { // Log the error log.error("Unable to create node for graph element comparison.", graphElementFactoryException); // Fail the test fail("Unable to create node for graph element comparison."); } if (log.isDebugEnabled()) { log.debug("// Finished processing test"); } } /** * Default text runner. * * @param args The command line arguments */ public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } }