/*
* 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.demo.mp3;
// Java 2 standard packages
import java.net.URI;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.jrdf.graph.Node;
import org.jrdf.graph.ObjectNode;
import org.jrdf.graph.PredicateNode;
import org.jrdf.graph.Triple;
import org.jrdf.graph.URIReference;
import org.jrdf.util.ClosableIterator;
import org.jrdf.vocabulary.RDF;
import org.mulgara.demo.mp3.id3.Id3Tag;
import org.mulgara.query.QueryException;
/**
* Implementation of Mp3Model using iTQL. init() must be called after
* FileSystemModel is set.
*
* @created 2004-12-03
*
* @author <a href="mailto:robert.turner@tucanatech.com">Robert Turner </a>
*
* @version $Revision: 1.4 $
*
* @modified $Date: 2005/04/20 19:02:50 $
*
* @maintenanceAuthor $Author: newmana $
*
* @company <A href="mailto:info@PIsoftware.com">Plugged In Software </A>
*
* @copyright ©2001 <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 Mp3ModelImpl extends AbstractModel implements Mp3Model {
/**
* Logger. This is named after the class.
*/
private final static Logger log = Logger.getLogger(Mp3ModelImpl.class
.getName());
/** Listener used to notify caller of events */
private Mp3ModelListener listener = null;
/** Graph where Schema information is stored */
private SchemaModel schemaModel = null;
/**
* init
*
* @param context
* ModelContext
* @throws Exception
*/
public void init(ModelContext context) throws Exception {
super.init(context);
if (schemaModel == null) {
throw new IllegalStateException("SchemaModel must be set before "
+ "calling init()");
}
}
/**
* Discover mp3's from the FileSystemModel and loads them.
*
* @param fsModel
* FileSystemModel
* @throws IllegalArgumentException
* @throws QueryException
*/
public void loadMp3s(FileSystemModel fsModel)
throws IllegalArgumentException, QueryException {
if (fsModel == null) {
throw new IllegalArgumentException("FileSystemModel is null");
}
try {
checkInitialized();
//get all files from the filesystem with an extension of mp3
ClosableIterator<Triple> files = fsModel.findFiles(
FileSystemModel.FILE_EXT, Mp3Model.MP3_EXT);
Mp3Iterator mp3s = new Mp3IteratorImpl(files, newMp3Context());
loadMp3s(mp3s);
} catch (Exception exception) {
throw new QueryException("Failed to retrieve Mp3Files.", exception);
}
}
/**
* Sets the Graph used to store Schema Information.
*
* @param schemaModel
* SchemaModel
* @throws IllegalArgumentException
*/
public void setSchemaModel(SchemaModel schemaModel)
throws IllegalArgumentException {
if (schemaModel == null) {
throw new IllegalArgumentException("SchemaModel is null");
}
this.schemaModel = schemaModel;
}
/**
* Returns the Graph used to store Schema Information.
*
* @return SchemaModel
*/
public SchemaModel getSchemaModel() {
checkInitialized();
return schemaModel;
}
/**
* Returns all Mp3Files from the filesystem (FileSystemModel)
*
* @return Mp3Iterator
* @throws QueryException
*/
public Mp3Iterator getMp3s() throws QueryException {
try {
checkInitialized();
String query = getMp3sQuery();
ClosableIterator<Triple> mp3s = query(query);
return new Mp3IteratorImpl(mp3s, newMp3Context());
} catch (Exception exception) {
throw new QueryException("Failed to retrieve Mp3Files.", exception);
}
}
/**
* Returns an Iterator (of Triples) that match any of the properties for the
* specified mp3.
*
* @param mp3
* URIReference
* @param properties
* Iterator
* @return ClosableIterator
* @throws QueryException
*/
public ClosableIterator<Triple> getPropertyStatements(URIReference mp3,
Iterator<Triple> properties) throws QueryException {
try {
checkInitialized();
String query = getPropertiesQuery(mp3, properties);
return query(query);
} catch (Exception exception) {
throw new QueryException("Failed to find property statements for: "
+ mp3, exception);
}
}
/**
* Returns an Iterator containing all the Mp3s (as URIReferenece's) that
* have the specified metadata properties and values.
*
* @param properties
* Iterator metadata predicates (eg. "mulgara:title")
* @param values
* Iterator metadata objects (eg. "Vertigo")
* @return Mp3Iterator
* @throws QueryException
*/
public Mp3Iterator findMp3s(Iterator<PredicateNode> properties, Iterator<ObjectNode> values)
throws QueryException {
try {
checkInitialized();
//query for mp3s with the specified property
String query = getFindMp3Query(properties, values);
ClosableIterator<Triple> mp3s = query(query);
return new Mp3IteratorImpl(mp3s, newMp3Context());
} catch (Exception exception) {
throw new QueryException("Failed to retrieve Mp3Files.", exception);
}
}
/**
* hasInitialized
*
* @return boolean
*/
public boolean hasInitialized() {
return (super.hasInitialized()) && (schemaModel != null);
}
/**
* Returns a query in the following format:
* <p>
*
* <pre>
*
*
*
* select $s $p $o
* from <getResource()>
* where $s $p $o
* and $s <rdf:type> <mulgara:mp3>;
*
*
*
* </pre>
*
* @return String
*/
private String getMp3sQuery() {
StringBuffer query = new StringBuffer();
query
.append("select $s <" + RDF.TYPE + ">" + Mp3File.MULGARA_MP3
+ NEWLINE);
query.append("from <" + getResource() + "> " + NEWLINE);
query.append("where $x" + Id3Tag.ID3_URI + " $s" + NEWLINE);
query.append("and $x $p $o " + NEWLINE);
query.append("order by $s ; ");
return query.toString();
}
/**
* Returns a query in the following format:
* <p>
*
* <pre>
*
*
*
* select $s $p $o
* from <getResource()>
* where $s $p $o
* and $s <property-1> <value-1>
* and $s <property-2> <value-2>
* ...
* and $s <property-n> <value-n> ;
*
*
*
* </pre>
*
* Where n is the number of statements in the shortest iterator.
*
* @param properties
* Iterator containing PredicateNodes
* @param values
* Iterator containing ObjectNodes
* @return String
*/
private String getFindMp3Query(Iterator<PredicateNode> properties, Iterator<ObjectNode> values) {
//if there are no constraints, return all.
if ((properties == null) || (values == null) || (!properties.hasNext())
|| (!values.hasNext())) {
return getMp3sQuery();
}
String currentProperty = null;
String currentValue = null;
StringBuffer query = new StringBuffer();
query
.append("select $s <" + RDF.TYPE + ">" + Mp3File.MULGARA_MP3
+ NEWLINE);
query.append("from <" + getResource() + "> " + NEWLINE);
query.append("where $x" + Id3Tag.ID3_URI + " $s" + NEWLINE);
while (properties.hasNext() && values.hasNext()) {
currentProperty = asString(" $p", properties.next());
currentValue = asString(" $o", values.next());
query.append("and $x" + currentProperty + currentValue + NEWLINE);
}
query.append("order by $s ;");
return query.toString();
}
/**
* Returns a queryString in the following format:
*
* <p>
*
* <pre>
*
*
*
* select $s $p $o
* from <getResource()>
* where $s $p $o
* and $s <mulgara:is> <mp3>
* and ($p <mulgara:is> <schemaProperty-1>
* or $p <mulgara:is> <schemaProperty-2>
* ...
* or $p <mulgara:is> <schemaProperty-n>) ;
*
*
*
* </pre>
*
* where <schemaProperty>is a property of the ID3Tags schema.
*
* @return String
* @param mp3
* URIReference
* @param properties
* Iterator of Triples where the SubjectNode's represent the
* schemaProperties.
*/
private String getPropertiesQuery(URIReference mp3, Iterator<Triple> properties) {
//if there are no properties, there should be no statements.
if ((properties == null) || !(properties.hasNext())) {
return ";";
}
Node currentProperty = properties.next().getPredicate();
StringBuffer query = new StringBuffer("select $s $p $o" + NEWLINE);
query.append("from <" + getResource().getURI() + ">" + NEWLINE);
query.append("where $s $p $o" + NEWLINE);
query.append("and " + getMulgaraIsConstraint("$s", mp3));
query.append("and ( "
+ getMulgaraIsConstraint("$p", (URIReference) currentProperty));
while (properties.hasNext()) {
currentProperty = properties.next().getSubject();
query.append(" or "
+ getMulgaraIsConstraint("$p", (URIReference) currentProperty));
}
//results must be ordered
query.append(") order by $s $p $o ; ");
return query.toString();
}
/**
* Returns an iTQL constraint in the form of: $var <mulgara:is><value>
*
* @param var
* String
* @param value
* Node
* @return String
*/
private String getMulgaraIsConstraint(String var, Node value) {
if (var == null) {
throw new IllegalArgumentException("'var' is null");
}
if (value == null) {
throw new IllegalArgumentException("'value' is null");
}
return var + MULGARA_IS + asString(value) + " " + NEWLINE;
}
/**
* Loads all the mp3s Files in the FileSystemModel.
*
* @throws Exception
* @param mp3s
* Mp3Iterator
*/
private void loadMp3s(Mp3Iterator mp3s) throws Exception {
checkInitialized();
if (mp3s == null) {
throw new IllegalArgumentException("Mp3Iterator is null");
}
//load each Mp3 individually
Mp3File mp3 = null;
while (mp3s.hasNext()) {
mp3 = mp3s.nextMp3();
try {
loadMp3(mp3);
} catch (Exception e) {
getListener().loadExceptionOccurred(mp3, e);
}
}
}
/**
* Loads the Mp3.
*
* @param mp3
* Mp3File
* @throws Exception
*/
private void loadMp3(Mp3File mp3) throws Exception {
if (mp3 == null) {
throw new IllegalArgumentException("Mp3File is null.");
}
checkInitialized();
//construct insert query
URI mp3Uri = mp3.getResource().getURI();
StringBuffer query = new StringBuffer();
query.append("load <" + mp3Uri + "> " + NEWLINE);
query.append("into <" + getResource().getURI() + "> ;");
//execute
if (log.isDebugEnabled()) {
log.debug("Loading: " + mp3Uri + " into " + getResource().getURI());
}
getBean().executeUpdate(query.toString());
}
/**
* Creates a new Context for creating Mp3Files.
*
* @return Mp3Context
*/
private Mp3Context newMp3Context() {
Mp3ContextImpl context = new Mp3ContextImpl();
context.setBean(getBean());
context.setMp3Model(this);
context.setSchemaModel(schemaModel);
return context;
}
/**
* Returns the registered Mp3ModelListener or a default (no-op) listener if
* one has not been set.
*
* @return
*/
private Mp3ModelListener getListener() {
if (listener == null) {
listener = new Mp3ModelListener() {
public void loadExceptionOccurred(Mp3File file, Exception e) {
//no-op
}
};
}
return listener;
}
/**
* Sets the listener that is notified of Mp3Model events.
*
* @param listener
*/
public void setMp3ModelListener(Mp3ModelListener listener) {
this.listener = listener;
}
}