Java tutorial
/* * Copyright (C) 2012-2013 CloudJee, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.wavemaker.tools.io.mongo; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.Iterator; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import com.mongodb.BasicDBObject; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.gridfs.GridFS; import com.mongodb.gridfs.GridFSDBFile; import com.mongodb.gridfs.GridFSInputFile; import com.wavemaker.tools.io.File; import com.wavemaker.tools.io.Folder; import com.wavemaker.tools.io.JailedResourcePath; import com.wavemaker.tools.io.Resource; import com.wavemaker.tools.io.ResourcePath; import com.wavemaker.tools.io.exception.ResourceException; import com.wavemaker.tools.io.exception.ResourceTypeMismatchException; import com.wavemaker.tools.io.store.FileStore; import com.wavemaker.tools.io.store.FolderStore; import com.wavemaker.tools.io.store.ResourceStore; /** * {@link ResourceStore}s for {@link MongoFile} and {@link MonoFolder}. * * @author Phillip Webb */ abstract class MongoResourceStore implements ResourceStore { private static final String PARENT = "parent"; private static final String RESOURCE_TYPE = "resourceType"; private final GridFS fs; private final JailedResourcePath path; public MongoResourceStore(GridFS fs, JailedResourcePath path) { Assert.notNull(fs, "FS must not be null"); Assert.notNull(path, "Path must not be null"); this.fs = fs; this.path = path; } protected final GridFS getFs() { return this.fs; } protected final GridFSDBFile getGridFSDBFile(JailedResourcePath path, boolean required) { String filename = getFilename(path); GridFSDBFile file = getFs().findOne(filename); if (file == null && required) { throw new ResourceException("Unable to find mogo entry for " + filename); } return file; } protected GridFSInputFile create(Type type, boolean createEmptyFile) { Assert.notNull(type, "Type must not be null"); GridFSInputFile file = this.fs.createFile(getFilename(getPath())); JailedResourcePath parent = this.path.getParent(); if (parent != null) { file.put(PARENT, parent.getUnjailedPath().toString()); } file.put(RESOURCE_TYPE, type.name()); if (createEmptyFile) { try { file.getOutputStream().close(); } catch (IOException e) { throw new ResourceException(e); } } return file; } private String getFilename(JailedResourcePath path) { return path.getUnjailedPath().toString(); } @Override public JailedResourcePath getPath() { return this.path; } @Override public Resource getExisting(JailedResourcePath path) { Type type = getType(path); if (type == null) { return null; } return type == Type.FILE ? getFile(path) : getFolder(path); } /** * Return the file type or <tt>null</tt>. * * @param path the path to test * @return the file type */ protected final Type getType(JailedResourcePath path) { GridFSDBFile file = getGridFSDBFile(path, false); if (file == null) { return null; } Type type = Type.valueOf((String) file.get(RESOURCE_TYPE)); return type; } @Override public Folder getFolder(JailedResourcePath path) { MongoFolderStore store = new MongoFolderStore(getFs(), path); return new MongoFolder(store); } @Override public File getFile(JailedResourcePath path) { MongoFileStore store = new MongoFileStore(getFs(), path); return new MongoFile(store); } @Override public Resource rename(String name) { GridFSDBFile gridFSDBFile = getGridFSDBFile(getPath(), true); JailedResourcePath renamed = getPath().unjail().getParent().get(name); gridFSDBFile.put("filename", getFilename(renamed)); gridFSDBFile.save(); return getRenamedResource(renamed); } protected abstract Resource getRenamedResource(JailedResourcePath path); @Override public boolean exists() { return getGridFSDBFile(getPath(), false) != null; } @Override public void delete() { getFs().remove(getFilename(getPath())); } @Override public int hashCode() { return getPath().getUnjailedPath().hashCode(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } MongoResourceStore other = (MongoResourceStore) obj; boolean rtn = true; rtn &= ObjectUtils.nullSafeEquals(getPath().getUnjailedPath(), other.getPath().getUnjailedPath()); rtn &= ObjectUtils.nullSafeEquals(getFs().getDB(), other.getFs().getDB()); rtn &= ObjectUtils.nullSafeEquals(getFs().getBucketName(), other.getFs().getBucketName()); return rtn; } static class MongoFileStore extends MongoResourceStore implements FileStore { public MongoFileStore(GridFS fs, JailedResourcePath path) { super(fs, path); if (Type.FOLDER.equals(getType(path))) { throw new ResourceTypeMismatchException(path.getUnjailedPath(), false); } } @Override protected Resource getRenamedResource(JailedResourcePath path) { MongoFileStore store = new MongoFileStore(getFs(), path); return new MongoFile(store); } @Override public void create() { create(Type.FILE, true); } @Override public InputStream getInputStream() { return getGridFSDBFile(getPath(), true).getInputStream(); } @Override public OutputStream getOutputStream() { delete(); GridFSInputFile file = create(Type.FILE, false); return file.getOutputStream(); } @Override public long getSize() { return getGridFSDBFile(getPath(), true).getLength(); } @Override public long getLastModified() { return getGridFSDBFile(getPath(), true).getUploadDate().getTime(); } @Override public void touch() { GridFSDBFile gridFSDBFile = getGridFSDBFile(getPath(), true); gridFSDBFile.put("uploadDate", new Date()); gridFSDBFile.save(); } } static class MongoFolderStore extends MongoResourceStore implements FolderStore { public MongoFolderStore(GridFS fs, JailedResourcePath path) { super(fs, path); if (Type.FILE.equals(getType(path))) { throw new ResourceTypeMismatchException(path.getUnjailedPath(), true); } } @Override protected Resource getRenamedResource(JailedResourcePath path) { return getFolder(path); } @Override public void create() { create(Type.FOLDER, true); } @Override public Iterable<String> list() { BasicDBObject query = new BasicDBObject(PARENT, getPath().getUnjailedPath().toString()); final DBCursor list = getFs().getFileList(query); return new FileListIterable(list); } } private static class FileListIterable implements Iterable<String> { private final DBCursor list; public FileListIterable(DBCursor list) { this.list = list; } @Override public Iterator<String> iterator() { return new FileListIterator(this.list.iterator()); } } private static class FileListIterator implements Iterator<String> { private final Iterator<DBObject> iterator; public FileListIterator(Iterator<DBObject> iterator) { this.iterator = iterator; } @Override public boolean hasNext() { return this.iterator.hasNext(); } @Override public String next() { DBObject next = this.iterator.next(); String filename = (String) next.get("filename"); ResourcePath path = new ResourcePath().get(filename); return path.getName(); } @Override public void remove() { throw new UnsupportedOperationException(); } } private static enum Type { FILE, FOLDER } }