/*
* ProtocolByIdFinder.java
*
* Created on March 27, 2007, 11:09 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.app;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import org.atomojo.app.db.DB;
import org.atomojo.app.db.Entry;
import org.atomojo.app.db.EntryMedia;
import org.atomojo.app.db.Feed;
import org.atomojo.app.db.Term;
import org.atomojo.app.db.TermInstance;
import org.infoset.xml.DocumentLoader;
import org.infoset.xml.sax.SAXDocumentLoader;
import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.MediaType;
import org.restlet.data.Reference;
import org.restlet.data.Status;
import org.restlet.resource.Finder;
import org.restlet.resource.ServerResource;
/**
*
* @author alex
*/
public class QueryFinder extends Finder {
public static class QuerySpec {
Storage.Query query;
boolean collection;
MediaType mediaType;
QuerySpec(Storage.Query query,boolean collection,MediaType mediaType)
{
this.query = query;
this.collection = collection;
this.mediaType = mediaType;
}
public Storage.Query getQuery() {
return query;
}
public boolean useCollection() {
return collection;
}
public MediaType getMediaType() {
return mediaType;
}
}
DB atomDB;
Application theApp;
Reference resourceBase;
DocumentLoader loader = new SAXDocumentLoader();
Storage storage;
App app;
Map<String,QuerySpec> queries;
long expiration = 60*1000*5;
long loadedAt;
/** Creates a new instance of ProtocolByIdFinder */
public QueryFinder(Context context,Application theApp,Reference resourceBase,DB atomDB,Storage storage) {
super(context);
this.theApp = theApp;
this.atomDB = atomDB;
this.resourceBase = resourceBase;
this.storage = storage;
this.app = new App(context.getLogger(),atomDB,storage,theApp.getMetadataService());
this.queries = new TreeMap<String,QuerySpec>();
this.loadedAt = -1;
setTargetClass(ServerResource.class);
}
protected void loadQueries()
throws SQLException,IOException
{
getContext().getLogger().info("Reloading queries:");
queries.clear();
Term queryTerm = atomDB.findTerm(Categorization.QUERY_TERM);
if (queryTerm==null) {
queryTerm = atomDB.createTerm(Categorization.QUERY_TERM);
}
Term nameTerm = atomDB.findTerm(Categorization.QUERY_NAME_TERM);
if (nameTerm==null) {
nameTerm = atomDB.createTerm(Categorization.QUERY_NAME_TERM);
}
Term collectionTerm = atomDB.findTerm(Categorization.QUERY_USE_COLLECTION_TERM);
if (collectionTerm==null) {
collectionTerm = atomDB.createTerm(Categorization.QUERY_USE_COLLECTION_TERM);
}
Term mediaTypeTerm = atomDB.findTerm(Categorization.QUERY_MEDIA_TYPE_TERM);
if (mediaTypeTerm==null) {
mediaTypeTerm = atomDB.createTerm(Categorization.QUERY_MEDIA_TYPE_TERM);
}
loadedAt = System.currentTimeMillis();
Iterator<TermInstance<Entry>> entries = atomDB.getEntriesByTerm(queryTerm);
while (entries.hasNext()) {
Entry entry = entries.next().getTarget();
getContext().getLogger().info("Query entry: "+entry.getUUID());
Feed feed = entry.getFeed();
Iterator<EntryMedia> media = entry.getResources();
if (media.hasNext()) {
Storage.Query query = storage.getQuery(feed.getPath(),feed.getUUID(),media.next().getName());
if (query!=null) {
getContext().getLogger().info("Query found...");
TermInstance<Entry> nameT = entry.getTerm(nameTerm);
TermInstance<Entry> useCollectionT = entry.getTerm(collectionTerm);
TermInstance<Entry> mediaTypeT = entry.getTerm(mediaTypeTerm);
QuerySpec spec = new QuerySpec(query,useCollectionT!=null,mediaTypeT==null ? MediaType.APPLICATION_ATOM_XML : MediaType.valueOf(mediaTypeT.getValue().toString()));
if (nameT!=null) {
String name = nameT.getValue()!=null ? nameT.getValue().toString() : null;
if (name!=null) {
getContext().getLogger().info("Query found, provided by name at "+name);
queries.put(name,spec);
}
}
queries.put(entry.getUUID().toString(),spec);
}
}
}
}
public ServerResource fine(Request request, Response response) {
String uriPath = request.getResourceRef().getRemainingPart();
int q = uriPath.indexOf("?");
if (q>0) {
uriPath = uriPath.substring(0,q);
}
if (uriPath==null || uriPath.length()==0) {
try {
loadQueries();
response.setStatus(Status.SUCCESS_NO_CONTENT);
return null;
} catch (Exception ex) {
getContext().getLogger().log(Level.SEVERE,"Cannot load queries.",ex);
response.setStatus(Status.SERVER_ERROR_INTERNAL,"Cannot load queries.");
return null;
}
} else {
String [] segments = uriPath.split("/");
String queryName = segments[0];
try {
Feed feed = atomDB.findFeedByPath(segments,1,segments.length-1);
if (feed==null) {
return null;
}
if (loadedAt<0 || System.currentTimeMillis()>(loadedAt+expiration)) {
loadQueries();
}
QuerySpec spec = queries.get(queryName);
if (spec==null) {
return null;
}
return new QueryResource(resourceBase,app,storage,feed,spec);
} catch (Exception ex) {
getContext().getLogger().log(Level.SEVERE,"Cannot load queries.",ex);
response.setStatus(Status.SERVER_ERROR_INTERNAL,"Cannot load queries.");
return null;
}
}
}
}