All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.caucho.vfs.Vfs Maven / Gradle / Ivy

There is a newer version: 4.0.66
Show 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 Scott Ferguson
 */

package com.caucho.vfs;

import com.caucho.loader.EnvironmentLocal;
import com.caucho.util.CharBuffer;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Facade to create useful Path and Stream objects.
 *
 * 
 * Path path = Vfs.lookup("foo.html");
 * 
* *

The default scheme is the file scheme. Other schemes are * available using the full url. * *

 * Path mail = Vfs.lookup("mailto:[email protected]?subject='hi'");
 * Stream body = mail.openWrite();
 * body.writeln("How's it going?");
 * body.close();
 * 
*/ public final class Vfs { private static final EnvironmentLocal ENV_PWD = new EnvironmentLocal("caucho.vfs.pwd"); private static final SchemeMap DEFAULT_SCHEME_MAP; private static final EnvironmentLocal _localSchemeMap = new EnvironmentLocal(); static FilesystemPath PWD; private static AtomicBoolean _isInitJNI = new AtomicBoolean(); private Vfs() {} /** * Returns a new path relative to the current directory. * * @param url a relative or absolute url * @return the new path. */ public static Path lookup(String url) { Path pwd = getPwd(); if (! url.startsWith("/")) return pwd.lookup(url, null); else return PWD.lookup(url, null); } public static FilesystemPath getGlobalPwd() { return PWD; } /** * Returns a path for the current directory. */ public static Path getPwd() { Path pwd = ENV_PWD.get(); if (pwd == null) { if (PWD == null) { /* JNI set later PWD = JniFilePath.create(); if (PWD == null) PWD = new FilePath(null); */ PWD = new FilePath(null); } pwd = PWD; ENV_PWD.setGlobal(pwd); } return pwd; } public static SchemeMap getLocalScheme() { synchronized (_localSchemeMap) { SchemeMap map = _localSchemeMap.getLevel(); if (map == null) { map = _localSchemeMap.get().copy(); if (map == null) map = DEFAULT_SCHEME_MAP.copy(); _localSchemeMap.set(map); } return map; } } public static SchemeMap getDefaultScheme() { return DEFAULT_SCHEME_MAP; } /** * Returns a path for the current directory. */ public static Path getPwd(ClassLoader loader) { return ENV_PWD.get(loader); } /** * Sets a path for the current directory in the current environment. */ public static void setPwd(Path pwd) { setPwd(pwd, Thread.currentThread().getContextClassLoader()); } /** * Sets a path for the current directory in the current environment. */ public static void setPwd(Path pwd, ClassLoader loader) { ENV_PWD.set(pwd, loader); } /** * Returns a path for the current directory. */ public static Path lookup() { return getPwd(); } /** * Returns a new path, including attributes. *

For example, an application may want to set locale headers * for an HTTP request. * * @param url the relative url * @param attr attributes used in searching for the url */ public static Path lookup(String url, Map attr) { return getPwd().lookup(url, attr); } /** * Returns a path using the native filesystem conventions. *

For example, on windows * *

   * Path path = Vfs.lookup("d:\\temp\\test.html");
   * 
* * @param url a relative path using the native filesystem conventions. */ public static Path lookupNative(String url) { return getPwd().lookupNative(url, null); } /** * Looks up a URL, decoding '%' * * @param url a relative path using the native filesystem conventions. */ public static Path lookup(URL url) { return getPwd().lookup(url); } /** * Returns a native filesystem path with attributes. * * @param url a relative path using the native filesystem conventions. * @param attr attributes used in searching for the url */ public static Path lookupNative(String url, Map attr) { return getPwd().lookupNative(url, attr); } public static ReadWritePair openReadWrite(InputStream is, OutputStream os) { VfsStream s = new VfsStream(is, os); WriteStream writeStream = new WriteStream(s); ReadStream readStream = new ReadStream(s, writeStream); return new ReadWritePair(readStream, writeStream); } /** * Creates new ReadStream from an InputStream */ public static ReadStream openRead(InputStream is) { if (is instanceof ReadStream) return (ReadStream) is; VfsStream s = new VfsStream(is, null); return new ReadStream(s); } public static ReadStream openRead(InputStream is, WriteStream ws) { VfsStream s = new VfsStream(is, null); return new ReadStream(s, ws); } /** * Creates a ReadStream from a Reader */ public static ReadStream openRead(Reader reader) { if (reader instanceof ReadStream.StreamReader) return ((ReadStream.StreamReader) reader).getStream(); ReaderWriterStream s = new ReaderWriterStream(reader, null); ReadStream is = new ReadStream(s); try { is.setEncoding("utf-8"); } catch (Exception e) { } return is; } /** * Create a ReadStream from a string. utf-8 is used as the encoding */ public static ReadStream openRead(String path) throws IOException { return Vfs.lookup(path).openRead(); } public static ReadStream openString(String string) { return com.caucho.vfs.StringReader.open(string); } public static WriteStream openWrite(OutputStream os) { if (os instanceof WriteStream) return ((WriteStream) os); VfsStream s = new VfsStream(null, os); return new WriteStream(s); } public static WriteStream openWrite(Writer writer) { ReaderWriterStream s = new ReaderWriterStream(null, writer); WriteStream os = new WriteStream(s); try { os.setEncoding("utf-8"); } catch (Exception e) { } return os; } /** * Creates a write stream to a CharBuffer. This is the standard way * to write to a string. */ public static WriteStream openWrite(CharBuffer cb) { com.caucho.vfs.StringWriter s = new com.caucho.vfs.StringWriter(cb); WriteStream os = new WriteStream(s); try { os.setEncoding("utf-8"); } catch (Exception e) { } return os; } public static WriteStream openWrite(String path) throws IOException { return lookup(path).openWrite(); } public static WriteStream openAppend(String path) throws IOException { return lookup(path).openAppend(); } public static String decode(String uri) { StringBuilder sb = new StringBuilder(); int len = uri.length(); for (int i = 0; i < len; i++) { char ch = uri.charAt(i); if (ch != '%' || len <= i + 2) { sb.append(ch); continue; } int d1 = uri.charAt(i + 1); int d2 = uri.charAt(i + 2); int v = 0; if ('0' <= d1 && d1 <= '9') v = 16 * v + d1 - '0'; else if ('a' <= d1 && d1 <= 'f') v = 16 * v + d1 - 'a' + 10; else if ('A' <= d1 && d1 <= 'F') v = 16 * v + d1 - 'A' + 10; else { sb.append('%'); continue; } if ('0' <= d2 && d2 <= '9') v = 16 * v + d2 - '0'; else if ('a' <= d2 && d2 <= 'f') v = 16 * v + d2 - 'a' + 10; else if ('A' <= d2 && d2 <= 'F') v = 16 * v + d2 - 'A' + 10; else { sb.append('%'); continue; } sb.append((char) v); i += 2; } return sb.toString(); } /** * Initialize the JNI. */ public static void initJNI() { if (_isInitJNI.getAndSet(true)) return; // order matters because of static init and license checking FilesystemPath jniFilePath = JniFilePath.create(); if (jniFilePath != null) { DEFAULT_SCHEME_MAP.put("file", jniFilePath); SchemeMap localMap = _localSchemeMap.get(); if (localMap != null) localMap.put("file", jniFilePath); localMap = _localSchemeMap.get(ClassLoader.getSystemClassLoader()); if (localMap != null) localMap.put("file", jniFilePath); Vfs.PWD = jniFilePath; Vfs.setPwd(jniFilePath); } } static { DEFAULT_SCHEME_MAP = new SchemeMap(); Path.setDefaultSchemeMap(DEFAULT_SCHEME_MAP); FilePath pwd = new FilePath(null); PWD = pwd; setPwd(pwd); ENV_PWD.setGlobal(pwd); ENV_PWD.set(pwd); _localSchemeMap.setGlobal(DEFAULT_SCHEME_MAP); DEFAULT_SCHEME_MAP.put("file", pwd); DEFAULT_SCHEME_MAP.put("memory", new MemoryScheme()); DEFAULT_SCHEME_MAP.put("jar", new JarScheme(null)); /* XXX: DEFAULT_SCHEME_MAP.put("mailto", new MailtoPath(null, null, null, null)); */ DEFAULT_SCHEME_MAP.put("classpath", new ClasspathPath(null, "", "")); DEFAULT_SCHEME_MAP.put("http", new HttpPath("127.0.0.1", 0)); DEFAULT_SCHEME_MAP.put("https", new HttpsPath("127.0.0.1", 0)); // DEFAULT_SCHEME_MAP.put("hmux", new HmuxPath("127.0.0.1", 0)); DEFAULT_SCHEME_MAP.put("tcp", new TcpPath(null, null, null, "127.0.0.1", 0)); DEFAULT_SCHEME_MAP.put("tcps", new TcpsPath(null, null, null, "127.0.0.1", 0)); // DEFAULT_SCHEME_MAP.put("log", new LogPath(null, "/", null, "/")); DEFAULT_SCHEME_MAP.put("merge", new MergePath()); StreamImpl stdout = StdoutStream.create(); StreamImpl stderr = StderrStream.create(); DEFAULT_SCHEME_MAP.put("stdout", stdout.getPath()); DEFAULT_SCHEME_MAP.put("stderr", stderr.getPath()); VfsStream nullStream = new VfsStream(null, null); DEFAULT_SCHEME_MAP.put("null", new ConstPath(null, nullStream)); DEFAULT_SCHEME_MAP.put("jndi", new JndiPath()); DEFAULT_SCHEME_MAP.put("datastore", new DatastorePath("/")); /* DEFAULT_SCHEME_MAP.put("config", new ConfigPath()); */ DEFAULT_SCHEME_MAP.put("spy", new SpyScheme()); } }