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