You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2012/01/21 08:28:36 UTC

svn commit: r1234278 [29/29] - in /river/tck: ./ configs/ doc/ doc/api/ doc/api/com/ doc/api/com/sun/ doc/api/com/sun/jini/ doc/api/com/sun/jini/compat/ doc/api/com/sun/jini/compat/admin1/ doc/api/com/sun/jini/compat/admin2/ doc/api/com/sun/jini/compat...

Added: river/tck/src/com/sun/jini/compat/tool/ClassServer.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/tool/ClassServer.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/tool/ClassServer.java (added)
+++ river/tck/src/com/sun/jini/compat/tool/ClassServer.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,508 @@
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * 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.sun.jini.compat.tool;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * A simple HTTP server, for serving up JAR and class files.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+public class ClassServer extends Thread {
+    /** Default HTTP port */
+    private static int DEFAULT_PORT = 8080;
+    /** Default directory to serve files from on non-Windows OS */
+    private static String DEFAULT_DIR = "/vob/jive/lib";
+    /** Default directory to serve files from on Windows */
+    private static String DEFAULT_WIN_DIR = "J:";
+
+    /** Server socket to accept connections on */
+    private ServerSocket server;
+    /** Directory to serve from */
+    private String dir;
+    /** Map from String (JAR root) to JarFile[] (JAR class path) */
+    private HashMap map;
+    /** Verbosity flag */
+    private boolean verbose;
+    /** Read permission on dir and all subdirs */
+    private FilePermission perm;
+
+    /**
+     * Construct a server.  Use the start method to run it.
+     *
+     * @param port the port to use
+     * @param dir the directory to serve files from
+     * @param trees true if files within JAR files should be served up
+     * @param verbose true if downloads should be logged
+     */
+    public ClassServer(int port, String dir, boolean trees, boolean verbose)
+	throws IOException
+    {
+	if (!dir.endsWith(File.separator))
+	    dir = dir + File.separatorChar;
+	this.dir = dir;
+	this.verbose = verbose;
+	server = new ServerSocket(port);
+	perm = new FilePermission(dir + '-', "read");
+	if (!trees)
+	    return;
+	map = new HashMap();
+	File fdir = new File(dir);
+	String[] files = fdir.list();
+	if (files == null)
+	    return;
+	URL base = fdir.toURL();
+	for (int i = 0; i < files.length; i++) {
+	    String jar = files[i];
+	    if (!jar.endsWith(".jar") && !jar.endsWith(".zip"))
+		continue;
+	    ArrayList jfs = new ArrayList(1);
+	    addJar(jar, jfs, base);
+	    map.put(jar.substring(0, jar.length() - 4),
+		    jfs.toArray(new JarFile[jfs.size()]));
+	}
+    }
+
+    /** Add transitive Class-Path JARs to jfs. */
+    private void addJar(String jar, ArrayList jfs, URL base)
+	throws IOException
+    {
+	base = new URL(base, jar);
+	jar = base.getFile().replace('/', File.separatorChar);
+	for (int i = jfs.size(); --i >= 0; ) {
+	    if (jar.equals(((JarFile) jfs.get(i)).getName()))
+		return;
+	}
+	if (verbose)
+	    print("classserver.jar", jar);
+	JarFile jf = new JarFile(jar);
+	jfs.add(jf);
+	Manifest man = jf.getManifest();
+	if (man == null)
+	    return;
+	Attributes attrs = man.getMainAttributes();
+	if (attrs == null)
+	    return;
+	String val = attrs.getValue(Attributes.Name.CLASS_PATH);
+	if (val == null)
+	    return;
+	for (StringTokenizer st = new StringTokenizer(val);
+	     st.hasMoreTokens(); )
+	{
+	    addJar(st.nextToken(), jfs, base);
+	}
+    }
+
+    /** Just keep looping, spawning a new thread for each incoming request. */
+    public void run() {
+	try {
+	    while (true) {
+		new Task(server.accept()).start();
+	    }
+	} catch (IOException e) {
+	    e.printStackTrace();
+	}
+    }
+
+    /** Simple task thread */
+    private class Task extends Thread {
+	/** Socket for the incoming request */
+	private Socket sock;
+
+	/** Simple constructor */
+	public Task(Socket sock) {
+	    this.sock = sock;
+	}
+
+	/** Read up to CRLF, return false if EOF */
+	private boolean readLine(InputStream in, StringBuffer buf)
+	    throws IOException
+	{
+	    while (true) {
+		int c = in.read();
+		if (c < 0)
+		    return buf.length() > 0;
+		if (c == '\r') {
+		    in.mark(1);
+		    c = in.read();
+		    if (c != '\n')
+			in.reset();
+		    return true;
+		}
+		if (c == '\n')
+		    return true;
+		buf.append((char) c);
+	    }
+	}
+
+	/** Read the request and return the initial request line. */
+	private String getRequest() throws IOException {
+	    BufferedInputStream in =
+		new BufferedInputStream(sock.getInputStream(), 256);
+	    StringBuffer buf = new StringBuffer(80);
+	    do {
+		if (!readLine(in, buf))
+		    return null;
+	    } while (buf.length() == 0);
+	    String req = buf.toString();
+	    do {
+		buf.setLength(0);
+	    } while (readLine(in, buf) && buf.length() > 0);
+	    return req;
+	}
+
+	/** Read specified number of bytes and always close the stream. */
+	private byte[] getBytes(InputStream in, long length)
+	    throws IOException
+	{
+	    DataInputStream din = new DataInputStream(in);
+	    byte[] bytes = new byte[(int)length];
+	    try {
+		din.readFully(bytes);
+	    } finally {
+		din.close();
+	    }
+	    return bytes;
+	}
+
+	/** Parse % HEX HEX from s starting at i */
+	private char decode(String s, int i) {
+	    return (char) Integer.parseInt(s.substring(i + 1, i + 3), 16);
+	}
+
+	/** Canonicalize the path */
+	private String canon(String path) {
+	    try {
+		if (path.regionMatches(true, 0, "http://", 0, 7)) {
+		    int i = path.indexOf('/', 7);
+		    if (i < 0)
+			path = "/";
+		    else
+			path = path.substring(i);
+		}
+		for (int i = path.indexOf('%');
+		     i >= 0;
+		     i = path.indexOf('%', i + 1))
+		{
+		    char c = decode(path, i);
+		    int n = 3;
+		    if ((c & 0x80) != 0) {
+			switch (c >> 4) {
+			case 0xC:
+			case 0xD:
+			    n = 6;
+			    c = (char)(((c & 0x1F) << 6) |
+				       (decode(path, i + 3) & 0x3F));
+			    break;
+			case 0xE:
+			    n = 9;
+			    c = (char)(((c & 0x0f) << 12) |
+				       ((decode(path, i + 3) & 0x3F) << 6) |
+				       (decode(path, i + 6) & 0x3F));
+			    break;
+			default:
+			    return null;
+			}
+		    }
+		    path = path.substring(0, i) + c + path.substring(i + n);
+		}
+	    } catch (Exception e) {
+		return null;
+	    }
+	    if (path.length() == 0 || path.charAt(0) != '/')
+		return null;
+	    return path.substring(1);
+	}
+
+	/** Return the bytes of the requested file, or null if not found. */
+	private byte[] getBytes(String path) throws IOException {
+	    if (map != null) {
+		int i = path.indexOf('/');
+		if (i > 0) {
+		    JarFile[] jfs = (JarFile[])map.get(path.substring(0, i));
+		    if (jfs != null) {
+			String jpath = path.substring(i + 1);
+			for (i = 0; i < jfs.length; i++) {
+			    JarEntry je = jfs[i].getJarEntry(jpath);
+			    if (je != null)
+				return getBytes(jfs[i].getInputStream(je),
+						je.getSize());
+			}
+		    }
+		}
+	    }
+	    File f = new File(dir + path.replace('/', File.separatorChar));
+	    if (perm.implies(new FilePermission(f.getPath(), "read"))) {
+		try {
+		    return getBytes(new FileInputStream(f), f.length());
+		} catch (FileNotFoundException e) {
+		}
+	    }
+	    return null;
+	}
+
+	/** Process the request */
+	public void run() {
+	    try {
+		DataOutputStream out =
+		    new DataOutputStream(sock.getOutputStream());
+		String req;
+		try {
+		    req = getRequest();
+		} catch (Exception e) {
+		    if (verbose) {
+			print("classserver.inputerror",
+			      new String[]{sock.getInetAddress().getHostName(),
+					   Integer.toString(sock.getPort())});
+			e.printStackTrace();
+		    }
+		    return;
+		}
+		if (req == null)
+		    return;
+		if (req.startsWith("SHUTDOWN *")) {
+		    if (verbose)
+			print("classserver.shutdown",
+			      new String[]{sock.getInetAddress().getHostName(),
+					   Integer.toString(sock.getPort())});
+		    try {
+			new ServerSocket(0, 1, sock.getInetAddress());
+		    } catch (IOException e) {
+			out.writeBytes("HTTP/1.0 403 Forbidden\r\n\r\n");
+			out.flush();
+			return;
+		    }
+		    System.exit(0);
+		}
+		String[] args = null;
+		if (verbose)
+		    args = new String[]{req,
+					sock.getInetAddress().getHostName(),
+					Integer.toString(sock.getPort())};
+		boolean get = req.startsWith("GET ");
+		if (!get && !req.startsWith("HEAD ")) {
+		    if (verbose)
+			print("classserver.badrequest", args);
+		    out.writeBytes("HTTP/1.0 400 Bad Request\r\n\r\n");
+		    out.flush();
+		    return;
+		}
+		String path = req.substring(get ? 4 : 5);
+		int i = path.indexOf(' ');
+		if (i > 0)
+		    path = path.substring(0, i);
+		path = canon(path);
+		if (path == null) {
+		    if (verbose)
+			print("classserver.badrequest", args);
+		    out.writeBytes("HTTP/1.0 400 Bad Request\r\n\r\n");
+		    out.flush();
+		    return;
+		}
+		if (verbose) {
+		    args[0] = path;
+		    print(get ? "classserver.request" : "classserver.probe",
+			  args);
+		}
+		byte[] bytes;
+		try {
+		    bytes = getBytes(path);
+		} catch (Exception e) {
+		    if (verbose)
+			e.printStackTrace();
+		    out.writeBytes("HTTP/1.0 500 Internal Error\r\n\r\n");
+		    out.flush();
+		    return;
+		}
+		if (bytes == null) {
+		    if (verbose)
+			print("classserver.notfound", path);
+		    out.writeBytes("HTTP/1.0 404 Not Found\r\n\r\n");
+		    out.flush();
+		    return;
+		}
+		out.writeBytes("HTTP/1.0 200 OK\r\n");
+		out.writeBytes("Content-Length: " + bytes.length + "\r\n");
+		out.writeBytes("Content-Type: application/java\r\n\r\n");
+		if (get)
+		    out.write(bytes);
+		out.flush();
+		if (get)
+		    fileDownloaded(path, sock.getInetAddress());
+	    } catch (Exception e) {
+		if (verbose)
+		    e.printStackTrace();
+	    } finally {
+		try {
+		    sock.close();
+		} catch (IOException e) {
+		}
+	    }
+	}
+    }
+
+    private static ResourceBundle resources;
+    private static boolean resinit = false;
+
+    private static String getString(String key) {
+	if (!resinit) {
+	    try {
+		resources = ResourceBundle.getBundle("com.sun.jini.compat.tool.resources.classserver");
+		resinit = true;
+	    } catch (MissingResourceException e) {
+		e.printStackTrace();
+	    }
+	}
+	try {
+	    return resources.getString(key);
+	} catch (MissingResourceException e) {
+	    return null;
+	}
+    }
+
+    private static void print(String key, String val) {
+	String fmt = getString(key);
+	if (fmt == null)
+	    fmt = "no text found: \"" + key + "\" {0}";
+	System.out.println(MessageFormat.format(fmt, new String[]{val}));
+    }
+
+    private static void print(String key, String[] vals) {
+	String fmt = getString(key);
+	if (fmt == null)
+	    fmt = "no text found: \"" + key + "\" {0} {1} {2}";
+	System.out.println(MessageFormat.format(fmt, vals));
+    }
+
+    /**
+     * This method provides a way for subclasses to be notified when a
+     * file has been completely downloaded.
+     * 
+     * @param fp The path to the file that was downloaded.
+     */
+    protected void fileDownloaded(String fp, InetAddress addr) {
+    }
+
+    /**
+     * Command line interface for creating an HTTP server.
+     * The command line options are:
+     * <pre>
+     * [-port <var>port</var>] [-dir <var>dir</var>] [-trees] [-verbose]
+     * </pre>
+     * The default port is 8080; the default can be overridden with
+     * the -port option.  The default directory on Windows is J:
+     * and the default on other systems is /vob/jive/lib; the default
+     * can be overridden with the -dir option.  By default, all files
+     * under this directory (including all subdirectories) are served
+     * up via HTTP.  If the pathname of a file is <var>path</var> relative
+     * to the top-level directory, then the file can be downloaded using
+     * the URL
+     * <pre>
+     * http://<var>host</var>:<var>port</var>/<var>path</var>
+     * </pre>
+     * No caching of directory contents or file contents is performed.
+     * If the -verbose option is given, then all attempts to download files
+     * are output. <p>
+     * 
+     * The -trees option can be used to serve up individual files stored
+     * within JAR files in addition to the files that are served up by
+     * default.  If the option is used, the server finds all JAR files
+     * in the top-level directory (not in subdirectories).  For each
+     * JAR file, if the name of the JAR file is <var>name</var>.jar, then any
+     * individual file named <var>file</var> within that JAR file (or within
+     * the JAR or zip files referenced transitively in the Class-Path manifest
+     * attribute, can be downloaded using a URL of the form:
+     * <pre>
+     * http://<var>host</var>:<var>port</var>/<var>name</var>/<var>file</var>
+     * </pre>
+     * When this option is used, an open file descriptor and cached
+     * information is held for each JAR file, for the life of the process.
+     */
+    public static void main(String[] args) {
+	int port = DEFAULT_PORT;
+	String dir = DEFAULT_DIR;
+	if (File.separatorChar == '\\')
+	    dir = DEFAULT_WIN_DIR;
+	boolean trees = false;
+	boolean verbose = false;
+	boolean stop = false;
+	for (int i = 0; i < args.length ; i++ ) {
+	    String arg = args[i];
+	    if (arg.equals("-port")) {
+		i++;
+		port = Integer.parseInt(args[i]);
+	    } else if (arg.equals("-dir")) {
+		i++;
+		dir = args[i];
+	    } else if (arg.equals("-verbose")) {
+		verbose = true;
+	    } else if (arg.equals("-trees")) {
+		trees = true;
+	    } else if (arg.equals("-stop")) {
+		stop = true;
+	    } else {
+		print("classserver.usage", (String)null);
+		return;
+	    }
+	}
+	try {
+	    if (stop) {
+		Socket sock = new Socket(InetAddress.getLocalHost(), port);
+		try {
+		    DataOutputStream out =
+			new DataOutputStream(sock.getOutputStream());
+		    out.writeBytes("SHUTDOWN *\r\n\r\n");
+		    out.flush();
+		} finally {
+		    try {
+			sock.close();
+		    } catch (IOException e) {
+		    }
+		}
+	    } else {
+		new ClassServer(port, dir, trees, verbose).start();
+	    }
+	} catch (IOException e) {
+	    e.printStackTrace();
+	}
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/tool/ClassServer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/debug/Debug.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/debug/Debug.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/debug/Debug.java (added)
+++ river/tck/src/com/sun/jini/debug/Debug.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,38 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.jini.debug;
+
+import java.io.PrintWriter;
+import java.security.PrivilegedAction;
+
+/**
+ * Another missing dependency
+ * @author peter
+ */
+public class Debug {
+    
+    /**
+     * This appears to be a static method that returns an PrivilegedAction that
+     * returns a Debug instance.
+     * 
+     * @param string
+     * @return 
+     */
+    public static PrivilegedAction<Debug> getDebugAction(String string){
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+    
+    /**
+     * I've got no idea what this does.  I imagine it gets the output stream
+     * or error stream PrintWriter.
+     * 
+     * @param string
+     * @return 
+     */
+    public PrintWriter getWriter(String string) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+    
+}

Propchange: river/tck/src/com/sun/jini/debug/Debug.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/mahout/KillVMAdmin.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/mahout/KillVMAdmin.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/mahout/KillVMAdmin.java (added)
+++ river/tck/src/com/sun/jini/mahout/KillVMAdmin.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,17 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.jini.mahout;
+
+import java.rmi.RemoteException;
+
+/**
+ * Missing dependency
+ * @author peter
+ */
+public interface KillVMAdmin {
+    
+    public long killVM() throws RemoteException;
+    
+}

Propchange: river/tck/src/com/sun/jini/mahout/KillVMAdmin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/start/ServiceDestroyer.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/start/ServiceDestroyer.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/start/ServiceDestroyer.java (added)
+++ river/tck/src/com/sun/jini/start/ServiceDestroyer.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,19 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.jini.start;
+
+import java.rmi.activation.ActivationException;
+
+/**
+ * Created to fulfil missing class.
+ * @author peter
+ */
+public class ServiceDestroyer {
+    
+    public static void destroy(Object service) throws ActivationException{
+        throw new ActivationException("Not yet implemented");
+    }
+    
+}

Propchange: river/tck/src/com/sun/jini/start/ServiceDestroyer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/start/SharedActivation.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/start/SharedActivation.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/start/SharedActivation.java (added)
+++ river/tck/src/com/sun/jini/start/SharedActivation.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,20 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.jini.start;
+
+import java.rmi.MarshalledObject;
+import java.rmi.activation.ActivationID;
+
+/**
+ * Missing class dependency
+ * @author peter
+ */
+public class SharedActivation {
+
+    public void setInitializationData(ActivationID activationID, MarshalledObject data) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+    
+}

Propchange: river/tck/src/com/sun/jini/start/SharedActivation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/start/SharedGroup.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/start/SharedGroup.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/start/SharedGroup.java (added)
+++ river/tck/src/com/sun/jini/start/SharedGroup.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,17 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.jini.start;
+
+/**
+ *
+ * @author peter
+ */
+public class SharedGroup {
+
+    public void destroyVM() {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+    
+}

Propchange: river/tck/src/com/sun/jini/start/SharedGroup.java
------------------------------------------------------------------------------
    svn:eol-style = native