com.caucho.vfs.DatastorePath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resin-kernel Show documentation
Show all versions of resin-kernel Show documentation
Kernel for Resin Java Application Server
The newest version!
/*
* Copyright (c) 1998-2012 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Nam Nguyen
*/
package com.caucho.vfs;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.caucho.util.CharBuffer;
public class DatastorePath extends Path
{
private static byte []NEWLINE = getNewlineString().getBytes();
public static final boolean IS_USE_HASHMAP = false;
private static HashMap _fileMap
= new HashMap();
private static DatastorePath PWD;
protected DatastorePath _root;
protected BindPath _bindRoot;
private String _pathname;
private DatastoreFile _file;
@PersistenceContext(name="test")
private EntityManager _entityManager;
public DatastorePath(String path)
{
this(null, path);
if (_root == null) {
_root = new DatastorePath(null, "/");
_root._root = _root;
if (PWD == null)
PWD = _root;
}
}
protected DatastorePath(DatastorePath root,
String pathname)
{
super(root);
if (pathname == null)
throw new NullPointerException();
_pathname = pathname;
if (root != null) {
_root = root;
_bindRoot = root._bindRoot;
}
}
public EntityManager getEntityManager()
{
return _entityManager;
}
public static DatastoreFile getFile(String name)
{
if (IS_USE_HASHMAP)
return _fileMap.get(name);
DatastorePath path = new DatastorePath(null, name);
EntityManager em = path._entityManager;
Query query
= em.createQuery("SELECT FROM " + DatastoreFile.class
+ " WHERE _pathname = :name");
query.setParameter("name", name);
List resultList = query.getResultList();
if (resultList.size() == 0)
return null;
DatastoreFile file = (DatastoreFile) resultList.get(0);
file.setPath(path);
return file;
}
public static void dumpFiles()
{
if (IS_USE_HASHMAP) {
System.out.println("DatastorePath->dumpFiles(): " + _fileMap.size());
for (Map.Entry entry : _fileMap.entrySet()) {
System.out.println("\t" + entry.getKey() + " . " + entry.getValue());
}
}
else {
DatastorePath path = PWD;
if (PWD == null)
path = new DatastorePath(null, "/");
Query query = path._entityManager.createQuery("SELECT FROM "
+ DatastoreFile.class);
List resultList = query.getResultList();
System.out.println("DatastorePath->dumpFiles(): " + resultList.size());
for (Object obj : resultList) {
DatastoreFile file = (DatastoreFile) obj;
System.out.println("\t" + file.getPathname());
}
}
}
/**
* Returns the path. e.g. for HTTP, returns the part after the
* host and port.
*/
public String getPath()
{
return _pathname;
}
/**
* Tests if the file exists.
*/
public boolean exists()
{
if (IS_USE_HASHMAP) {
return _fileMap.get(_pathname) != null;
}
else {
EntityManager em = _entityManager;
Query query
= em.createQuery("SELECT FROM " + DatastoreFile.class
+ " WHERE _pathname = :name");
query.setParameter("name", _pathname);
List resultList = query.getResultList();
return resultList.size() > 0;
}
}
/**
* Removes the file or directory named by this path.
*
* @return true if successful
*/
public boolean remove()
throws IOException
{
if (IS_USE_HASHMAP) {
_fileMap.remove(_pathname);
_file = null;
}
else {
EntityManager em = _entityManager;
Query query
= em.createQuery("SELECT FROM " + DatastoreFile.class
+ " WHERE _pathname = :name");
query.setParameter("name", _pathname);
List resultList = query.getResultList();
try {
em.getTransaction().begin();
for (Object obj : resultList) {
_entityManager.remove(obj);
}
} finally {
_entityManager.getTransaction().commit();
}
_file = null;
}
return true;
}
public String getScheme()
{
return "datastore";
}
/**
* Returns the stream implementation for a read stream.
*/
public StreamImpl openReadImpl()
throws IOException
{
DatastoreInputStream is = new DatastoreInputStream(getDatastoreFile());
return new DatastoreReadStream(is, this);
}
public StreamImpl openWriteImpl() throws IOException
{
DatastoreOutputStream os = new DatastoreOutputStream(getDatastoreFile());
DatastoreWriteStream ws = new DatastoreWriteStream(os, this);
ws.setNewline(NEWLINE);
return ws;
}
/**
* Returns the stream implementation for a random-access stream.
*/
public DatastoreRandomAccessStream openRandomAccess()
throws IOException
{
DatastoreRandomAccessFile file
= new DatastoreRandomAccessFile(getDatastoreFile());
return new DatastoreRandomAccessStream(file);
}
public DatastoreFile getDatastoreFile()
{
if (_file != null)
return _file;
if (IS_USE_HASHMAP) {
_file = _fileMap.get(_pathname);
if (_file == null) {
_file = new DatastoreFile(_pathname);
_fileMap.put(_pathname, _file);
}
}
else {
EntityManager em = _entityManager;
Query query = em.createQuery("SELECT FROM " + DatastoreFile.class
+ " WHERE _pathname = :path");
query.setParameter("path", _pathname);
List resultList = query.getResultList();
if (resultList.size() != 0)
_file = (DatastoreFile) resultList.get(0);
else {
em.getTransaction().begin();
try {
_file = new DatastoreFile(_pathname);
em.persist(_file);
} finally {
em.getTransaction().commit();
}
}
}
_file.setPath(this);
return _file;
}
/**
* Lookup the path, handling windows weirdness
*/
@Override
public Path schemeWalk(String userPath,
Map attributes,
String filePath,
int offset)
{
if (! isWindows())
return schemeWalkImpl(userPath, attributes, filePath, offset);
if (filePath.length() < offset + 2)
return schemeWalkImpl(userPath, attributes, filePath, offset);
char ch1 = filePath.charAt(offset + 1);
char ch2 = filePath.charAt(offset);
if ((ch2 == '/' || ch2 == _separatorChar)
&& (ch1 == '/' || ch1 == _separatorChar))
return schemeWalkImpl(userPath, attributes, filePath.substring(offset), 0);
else
return schemeWalkImpl(userPath, attributes, filePath, offset);
}
protected Path schemeWalkImpl(String userPath,
Map attributes,
String filePath,
int offset)
{
String canonicalPath;
if (filePath.length() > offset
&& (filePath.charAt(offset) == '/'
|| filePath.charAt(offset) == _separatorChar))
canonicalPath = normalizePath("/", filePath, offset, _separatorChar);
else
canonicalPath = normalizePath(_pathname, filePath, offset,
_separatorChar);
return fsWalk(userPath, attributes, canonicalPath);
}
public Path fsWalk(String userPath,
Map attributes,
String path)
{
return new DatastorePath(_root, path);
}
static protected String normalizePath(String oldPath,
String newPath,
int offset,
char separatorChar)
{
CharBuffer cb = new CharBuffer();
normalizePath(cb, oldPath, newPath, offset, separatorChar);
return cb.toString();
}
static protected void normalizePath(CharBuffer cb, String oldPath,
String newPath, int offset,
char separatorChar)
{
cb.clear();
cb.append(oldPath);
if (cb.length() == 0 || cb.getLastChar() != '/')
cb.append('/');
int length = newPath.length();
int i = offset;
while (i < length) {
char ch = newPath.charAt(i);
char ch2;
switch (ch) {
default:
if (ch != separatorChar) {
cb.append(ch);
i++;
break;
}
// the separator character falls through to be treated as '/'
case '/':
// "//" -> "/"
if (cb.getLastChar() != '/')
cb.append('/');
i++;
break;
case '.':
if (cb.getLastChar() != '/') {
cb.append('.');
i++;
break;
}
// "/." -> ""
if (i + 1 >= length) {
i += 2;
break;
}
switch (newPath.charAt(i + 1)) {
default:
if (newPath.charAt(i + 1) != separatorChar) {
cb.append('.');
i++;
break;
}
// the separator falls through to be treated as '/'
// "/./" -> "/"
case '/':
i += 2;
break;
// "foo/.." -> ""
case '.':
if ((i + 2 >= length ||
(ch2 = newPath.charAt(i + 2)) == '/' || ch2 == separatorChar) &&
cb.getLastChar() == '/') {
int segment = cb.lastIndexOf('/', cb.length() - 2);
if (segment == -1) {
cb.clear();
cb.append('/');
} else
cb.setLength(segment + 1);
i += 3;
} else {
cb.append('.');
i++;
}
break;
}
}
}
}
public String toString()
{
return "DatastorePath[" + _pathname + "," + _file + "]";
}
}