package org.qrone.mongo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.WeakHashMap; import org.qrone.r7.resolver.AbstractURIFileSystem; import org.qrone.r7.resolver.AbstractURIResolver; import org.qrone.r7.resolver.URIFileSystem; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; public class MongoResolver extends AbstractURIFileSystem{ private static final String ID = "_id"; private static final String DATA = "data"; private Map<String, byte[]> weakmap = new WeakHashMap<String, byte[]>(); private DBCollection col; public MongoResolver(DB db, String collection){ this.col = db.getCollection(collection); } public void drop(){ col.drop(); } @Override public List<String> list(){ List<String> set = new ArrayList<String>(); BasicDBObject ref = new BasicDBObject(); BasicDBObject keys = new BasicDBObject(); keys.append(ID, true); DBCursor c = col.find(ref, keys); for (; c.hasNext(); ) { DBObject obj = c.next(); set.add((String)obj.get(ID)); } Collections.sort(set); return set; } @Override public boolean exist(String path) { if(weakmap.containsKey(path)){ return false; }else{ InputStream i = null; try { i = getInputStream(new URI(path)); } catch (IOException e) { } catch (URISyntaxException e) { } if(i != null) return true; return false; } } @Override public boolean existPath(String path) { return false; } @Override public boolean remove(URI uri) { BasicDBObject obj = new BasicDBObject(); obj.put(ID, uri.toString()); col.remove(obj); fireUpdate(uri); return false; } @Override public InputStream getInputStream(URI uri) throws IOException { byte[] cache = weakmap.get(uri.toString()); if(cache != null){ return new ByteArrayInputStream(cache); } BasicDBObject obj = new BasicDBObject(); obj.put(ID, uri.toString()); DBObject o = col.findOne(obj); if(o != null){ byte[] v = (byte[])o.get(DATA); weakmap.put(uri.toString(), v); return new ByteArrayInputStream(v); } return null; } @Override public OutputStream getOutputStream(URI uri) throws IOException { return new MongoOutputStream(uri); } private class MongoOutputStream extends ByteArrayOutputStream{ private URI uri; public MongoOutputStream(URI uri) { this.uri = uri; } @Override public void close() throws IOException { super.close(); BasicDBObject obj = new BasicDBObject(); obj.put(ID, uri.toString()); obj.put(DATA, toByteArray()); col.save(obj); fireUpdate(uri); } } @Override public void write(String path, String data) { writeBytes(path, data.getBytes()); } @Override public void writeBytes(String path, byte[] data) { BasicDBObject obj = new BasicDBObject(); obj.put(ID, path); obj.put(DATA, data); col.save(obj); try { fireUpdate(new URI(path)); } catch (URISyntaxException e) {} } @Override public byte[] readBytes(String path) { BasicDBObject obj = new BasicDBObject(); obj.put(ID, path); DBObject o = col.findOne(obj); if(o != null){ return (byte[])o.get(DATA); } return null; } @Override public String read(String path) { try { return new String(readBytes(path),"utf8"); } catch (UnsupportedEncodingException e) { } return null; } }