[Arakhnę-Dev] [110] Add URLStreamHandler for file protocol which is supporting output stream.

[ Thread Index | Date Index | More arakhne.org/dev Archives ]


Revision: 110
Author:   galland
Date:     2010-01-13 16:46:50 +0100 (Wed, 13 Jan 2010)
Log Message:
-----------
Add URLStreamHandler for file protocol which is supporting output stream.

Added Paths:
-----------
    trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java
    trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java
    trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java
    trunk/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java

Added: trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java
===================================================================
--- trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java	                        (rev 0)
+++ trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLConnection.java	2010-01-13 15:46:50 UTC (rev 110)
@@ -0,0 +1,203 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, Stéphane GALLAND
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownServiceException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimetypesFileTypeMap;
+
+/**
+ * The class <code>FileURLConnection</code> is implementing
+ * connection between an URL and a local file.
+ * Instances of this class can be used both to
+ * read from and to write to the resource referenced by the file URL.
+ * <p>
+ * Supported header fields are:
+ * <ul>
+ * <li><code>content-type</code></li>
+ * <li><code>content-length</code></li>
+ * <li><code>last-modified</code></li>
+ * </ul>
+ * 
+ * @author Alexandre WILLAUME &lt;willaume@xxxxxxxxxxx&gt;
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @version $Name$ $Revision$ $Date$
+ * @see URLConnection
+ */
+class FileURLConnection extends URLConnection {
+
+	private File file = null;
+	
+	private String contentType = null;
+	
+	/**
+	 * @param url is the "file"-protocol url to use.
+	 */
+	protected FileURLConnection(URL url) {
+		super(url);
+	}
+	
+	/**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderField(int n) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	switch(n) {
+    	case 0: // content-type
+    		return this.contentType;
+    	case 1: // content-length
+    		return Long.toString(this.file.length());
+    	case 2: // last-modified
+    		return Long.toString(this.file.lastModified());
+    	}
+    	return null;
+    }
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderField(String name) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	if ("content-type".equals(name)) { //$NON-NLS-1$
+    		return this.contentType;
+    	}
+    	if ("content-length".equals(name)) { //$NON-NLS-1$
+    		return Long.toString(this.file.length());
+    	}
+    	if ("last-modified".equals(name)) { //$NON-NLS-1$
+    		return Long.toString(this.file.lastModified());
+    	}
+    	return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderFieldKey(int n) {
+    	switch(n) {
+    	case 0:
+    		return "content-type"; //$NON-NLS-1$
+    	case 1:
+    		return "content-length"; //$NON-NLS-1$
+    	case 2:
+    		return "last-modified"; //$NON-NLS-1$
+    	}
+    	return null;
+    }
+		
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public Map<String,List<String>> getHeaderFields() {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+		Map<String, List<String>> flds = new HashMap<String, List<String>>();
+    	flds.put("content-type", singletonList(this.contentType)); //$NON-NLS-1$
+    	flds.put("content-length", singletonList(Long.toString(this.file.length()))); //$NON-NLS-1$
+    	flds.put("last-modified", singletonList(Long.toString(this.file.lastModified()))); //$NON-NLS-1$
+        return flds;
+    }
+	
+	private List<String> singletonList(String value) {
+		if (value==null) return null;
+		return Collections.singletonList(value);
+	}
+
+    /**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void connect() throws IOException {
+		if (!this.connected) {
+			this.file = FileSystem.convertUrlToFile(this.url);
+			if (this.file==null)
+				throw new FileNotFoundException(this.url.toExternalForm());
+			this.contentType = new MimetypesFileTypeMap().getContentType(this.file);
+			this.connected = true;
+		}
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OutputStream getOutputStream() throws IOException {
+        connect();
+		if (getDoOutput()) {
+			OutputStream os = new FileOutputStream(this.file);
+			if (getUseCaches()) {
+				os = new BufferedOutputStream(os);
+			}
+			return os;
+		}
+		throw new UnknownServiceException("URL connection cannot do output"); //$NON-NLS-1$
+    }
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public InputStream getInputStream() throws IOException {
+        connect();
+		if (getDoInput()) {
+			InputStream is = new FileInputStream(this.file);
+			if (getUseCaches()) {
+				is = new BufferedInputStream(is);
+			}
+			return is;
+		}
+		throw new UnknownServiceException("URL connection cannot do input"); //$NON-NLS-1$
+    }
+	
+}

Added: trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java
===================================================================
--- trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java	                        (rev 0)
+++ trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandler.java	2010-01-13 15:46:50 UTC (rev 110)
@@ -0,0 +1,61 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, St&eacute;phane GALLAND
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+/**
+ * The class <code>FileURLStreamHandler</code> is supporting file protocol
+ * for URL streams. This stream protocol
+ * handler knows how to make a connection for "file" protocol.
+ * <p>
+ * In most cases, an instance of a <code>URLStreamHandler</code>
+ * subclass is not created directly by an application. Rather, the
+ * first time a protocol name is encountered when constructing a
+ * <code>URL</code>, the appropriate stream protocol handler is
+ * automatically loaded.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());</code>.
+ * 
+ * @author Alexandre WILLAUME &lt;willaume@xxxxxxxxxxx&gt;
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandler
+ * @see FileURLStreamHandlerFactory
+ */
+class FileURLStreamHandler extends URLStreamHandler {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected URLConnection openConnection(URL url) throws IOException {
+		if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+			return new FileURLConnection(url);
+		}
+		throw new UnsupportedOperationException("Unsupported protocol: "+url); //$NON-NLS-1$
+	}
+
+}

Added: trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java
===================================================================
--- trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java	                        (rev 0)
+++ trunk/arakhneVmutils/java/src/main/java/org/arakhne/vmutil/FileURLStreamHandlerFactory.java	2010-01-13 15:46:50 UTC (rev 110)
@@ -0,0 +1,57 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, St&eacute;phane GALLAND
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * This class defines a factory for <code>URL</code> stream
+ * "file" protocol handlers.
+ * <p>
+ * It is used by the <code>URL</code> class to create a
+ * <code>URLStreamHandler</code> for a "file" protocol.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());</code>.
+ * 
+ * @author Alexandre WILLAUME &lt;willaume@xxxxxxxxxxx&gt;
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @version $Name$ $Revision$ $Date$
+ * @see URLStreamHandlerFactory
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ */
+public class FileURLStreamHandlerFactory
+implements URLStreamHandlerFactory {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public URLStreamHandler createURLStreamHandler(String protocol) {
+		if ("file".equalsIgnoreCase(protocol)) //$NON-NLS-1$
+            return new FileURLStreamHandler();
+		// Force the default factory to retreive stream handler.
+		return null;
+	}
+
+}

Added: trunk/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java
===================================================================
--- trunk/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/java/src/test/java/org/arakhne/vmutil/FileURLConnectionTest.java	2010-01-13 15:46:50 UTC (rev 110)
@@ -0,0 +1,144 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 St&eacute;phane GALLAND
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collections;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @version $Name$ $Revision$ $Date$
+ */
+public class FileURLConnectionTest extends TestCase {
+
+	private FileURLConnection connection;
+	
+	static {
+		URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		URL resourceUrl = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+		assertNotNull(resourceUrl);
+		this.connection = new FileURLConnection(resourceUrl);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void tearDown() throws Exception {
+		this.connection = null;
+		super.tearDown();
+	}
+
+    /**
+     */
+    public void testGetHeaderFieldKeyInt() {
+    	assertEquals("content-type", this.connection.getHeaderFieldKey(0)); //$NON-NLS-1$
+    	assertEquals("content-length", this.connection.getHeaderFieldKey(1)); //$NON-NLS-1$
+    	assertEquals("last-modified", this.connection.getHeaderFieldKey(2)); //$NON-NLS-1$
+    	assertNull(this.connection.getHeaderFieldKey(3));
+    }
+
+    /**
+     */
+    public void testGetHeaderFieldInt() {
+    	assertEquals("text/plain", this.connection.getHeaderField(0)); //$NON-NLS-1$
+    	assertEquals("19", this.connection.getHeaderField(1)); //$NON-NLS-1$
+    	assertNotNull(this.connection.getHeaderField(2));
+    	assertNull(this.connection.getHeaderField(3));
+    }
+	
+    /**
+     */
+    public void testGetHeaderFieldString() {
+    	assertEquals("text/plain", this.connection.getHeaderField("content-type")); //$NON-NLS-1$ //$NON-NLS-2$
+    	assertEquals("19", this.connection.getHeaderField("content-length")); //$NON-NLS-1$ //$NON-NLS-2$
+    	assertNotNull(this.connection.getHeaderField("last-modified")); //$NON-NLS-1$
+    	assertNull(this.connection.getHeaderField("expires")); //$NON-NLS-1$
+    }
+		
+    /**
+     */
+    public void testGetHeaderFields() {
+    	Map<?,?> map = this.connection.getHeaderFields();
+    	assertNotNull(map);
+    	assertEquals(3, map.size());
+    	assertEquals(Collections.singletonList("text/plain"), map.get("content-type")); //$NON-NLS-1$ //$NON-NLS-2$
+    	assertEquals(Collections.singletonList("19"), map.get("content-length")); //$NON-NLS-1$ //$NON-NLS-2$
+    	assertNotNull(map.get("last-modified")); //$NON-NLS-1$
+    	assertNull(map.get("expires")); //$NON-NLS-1$
+    }
+	
+	/**
+	 * @throws IOException
+	 */
+	public void testGetInputStream() throws IOException {
+		InputStream is = this.connection.getInputStream();
+		BufferedReader br = new BufferedReader(new InputStreamReader(is));
+		String line = br.readLine();
+		br.close();
+		assertEquals("FOR UNIT TEST ONLY ", line); //$NON-NLS-1$
+    }
+
+	/**
+	 * @throws IOException
+	 */
+	public void testGetOutputStream() throws IOException {
+		File tmpFile = File.createTempFile("unittest", ".txt"); //$NON-NLS-1$ //$NON-NLS-2$
+		tmpFile.deleteOnExit();
+
+		URLConnection con = new FileURLConnection(tmpFile.toURI().toURL());
+		con.setDoOutput(true);
+		
+		OutputStream os = con.getOutputStream();
+		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
+		bw.write("HELLO WORLD!"); //$NON-NLS-1$
+		bw.close();
+		
+		assertEquals(12, tmpFile.length());
+		
+		BufferedReader br = new BufferedReader(new FileReader(tmpFile));
+		String line = br.readLine();
+		br.close();
+		assertEquals("HELLO WORLD!", line); //$NON-NLS-1$
+    }
+		
+}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/