You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by do...@apache.org on 2008/03/14 10:52:31 UTC

svn commit: r637026 - in /felix/sandbox/donsez/junitrunner: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/felix/ src/main/java/org/apache/felix/sandbox/ src/main/java/org/apache/felix/sandbox/htt...

Author: donsez
Date: Fri Mar 14 02:52:26 2008
New Revision: 637026

URL: http://svn.apache.org/viewvc?rev=637026&view=rev
Log:
Creation of the junitrunner bundle : JUnit Runner provides a felix command and a servlet to test registered services according to the JUnit pattern.

Added:
    felix/sandbox/donsez/junitrunner/
    felix/sandbox/donsez/junitrunner/pom.xml   (with props)
    felix/sandbox/donsez/junitrunner/src/
    felix/sandbox/donsez/junitrunner/src/main/
    felix/sandbox/donsez/junitrunner/src/main/java/
    felix/sandbox/donsez/junitrunner/src/main/java/org/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/GenericHttpContext.java   (with props)
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/MIMETypeUtil.java   (with props)
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JUnitRunnerServlet.java   (with props)
    felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JunitCommandImpl.java   (with props)
    felix/sandbox/donsez/junitrunner/src/main/resources/
    felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/
    felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.cmd.xml   (with props)
    felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.servlet.xml   (with props)
    felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/
    felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/mimetype.txt   (with props)
    felix/sandbox/donsez/junitrunner/src/main/resources/webroot/
    felix/sandbox/donsez/junitrunner/src/main/resources/webroot/icons/
    felix/sandbox/donsez/junitrunner/src/main/resources/webroot/logofelix.png   (with props)
    felix/sandbox/donsez/junitrunner/src/main/resources/webroot/style.css   (with props)
    felix/sandbox/donsez/junitrunner/src/site/
    felix/sandbox/donsez/junitrunner/src/site/readme.html   (with props)
    felix/sandbox/donsez/junitrunner/src/site/script.txt   (with props)

Added: felix/sandbox/donsez/junitrunner/pom.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/pom.xml?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/pom.xml (added)
+++ felix/sandbox/donsez/junitrunner/pom.xml Fri Mar 14 02:52:26 2008
@@ -0,0 +1,90 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you 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.
+-->
+<project>
+	<properties>
+		<repositoryLocation>http://www-adele.imag.fr/users/Didier.Donsez/dev/felix/sandbox/</repositoryLocation>
+	</properties>  
+
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <packaging>bundle</packaging>
+  <name>Apache Felix JUnit Runner</name>
+  <artifactId>org.apache.felix.sandbox.junitrunner</artifactId>
+
+  <description>provides a command and a servlet to launch tests on Test services.</description>
+    
+  <dependencies>
+
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>0.9.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+	<dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>provided</scope>
+    </dependency>
+    
+  </dependencies>
+
+  <build>
+    <plugins>
+       <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Import-Service>org.osgi.service.http.HttpService</Import-Service>
+            <Export-Service>org.apache.felix.shell.Command</Export-Service>
+            <Private-Package>org.apache.felix.sandbox.junitrunner.impl,org.apache.felix.sandbox.http.util</Private-Package>
+            <!-- <Export-Package>org.junit.*</Export-Package> -->
+            <Import-Package>*</Import-Package>
+            <Service-Component>OSGI-INF/component.servlet.xml, OSGI-INF/component.cmd.xml</Service-Component>
+           </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  
+</project>

Propchange: felix/sandbox/donsez/junitrunner/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/GenericHttpContext.java
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/GenericHttpContext.java?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/GenericHttpContext.java (added)
+++ felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/GenericHttpContext.java Fri Mar 14 02:52:26 2008
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.sandbox.http.util;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.osgi.service.http.HttpContext;
+
+/**
+ * provides a generic Http Context to register servlets and static docs
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class GenericHttpContext implements HttpContext {
+
+	
+	private Map extensionToMimeTypeMap;
+	// TODO 
+	private Map credentials;
+	
+	/**
+	 * @param is
+	 */
+	public GenericHttpContext(InputStream is){
+		extensionToMimeTypeMap=MIMETypeUtil.getExtensionToMimeTypeMap(is);
+	}
+
+	public GenericHttpContext(){
+		extensionToMimeTypeMap=MIMETypeUtil.getExtensionToMimeTypeMap();
+	}
+
+
+	public void resetExtensionToMimeTypeMap() {
+		extensionToMimeTypeMap=MIMETypeUtil.getExtensionToMimeTypeMap();
+	}
+
+	public void setExtensionToMimeTypeMap(InputStream stream) {
+		Map temp=MIMETypeUtil.getExtensionToMimeTypeMap(stream);
+		if(temp==null) return; // do nothing
+		extensionToMimeTypeMap=temp;
+	}
+
+	public void addExtensionToMimeType(String extension, String mimetype) {
+		extensionToMimeTypeMap.put(extension,mimetype);
+	}
+
+	public void removeExtensionToMimeType(String extension) {
+		extensionToMimeTypeMap.remove(extension);
+	}
+
+	public void removeAllExtensionToMimeTypes() {
+		extensionToMimeTypeMap=new HashMap();
+	}
+
+	
+	public String getMimeType(String name) {
+		int pos=name.lastIndexOf('.');
+		if(pos==-1 || pos==0 || pos==name.length()-1)
+			return null;
+		String extension=name.substring(pos+1);
+		return (String)extensionToMimeTypeMap.get(extension);
+		
+	}
+
+	/**
+	 * TODO add a simple textfile security realm 
+	 * for instance http://httpd.apache.org/docs/2.0/howto/htaccess.html
+	 */
+	public boolean handleSecurity(
+		HttpServletRequest req,
+		HttpServletResponse resp) {
+		return true;
+	}
+
+	public URL getResource(String name) {
+		URL u = this.getClass().getResource(name);
+		return u;
+	}
+}

Propchange: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/GenericHttpContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/MIMETypeUtil.java
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/MIMETypeUtil.java?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/MIMETypeUtil.java (added)
+++ felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/MIMETypeUtil.java Fri Mar 14 02:52:26 2008
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.sandbox.http.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * TODO
+ * <p>For more information about MIME types
+ * please read RFC 2045, 2046, 2047, 2048, and 2077. 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class MIMETypeUtil {
+
+	static public Map getExtensionToMimeTypeMap(InputStream inputStream){
+		// TODO skip #, "", ...
+		Map map=new HashMap();
+		BufferedReader bf=null;
+		try {
+			bf= new BufferedReader(new InputStreamReader(inputStream) );
+			String line;
+			while ((line = bf.readLine())!=null){
+				// TODO skip #, "", ...
+				if(line.length()==0 || line.startsWith("#") || line.startsWith(" "))
+					continue;
+				StringTokenizer st=new StringTokenizer(line," \t");
+				if(st.countTokens()==1)
+					continue;
+				String mimetype=st.nextToken();
+				while(st.hasMoreTokens()){
+					map.put(st.nextToken(),mimetype);
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace(System.err);
+			return null;
+		} finally {
+			try {
+				bf.close();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		return map;
+	}
+
+	static public Map getExtensionToMimeTypeMap(){
+		Map map=new HashMap();
+		map.put("htm","text/html");
+		map.put("html","text/html");
+		map.put("xml","text/xml");
+		map.put("xsl","text/xml");
+		map.put("css","text/css");
+		map.put("js","text/javascript");
+		map.put("jpg","image/jpeg");
+		map.put("jpeg","image/jpeg");
+		map.put("png","image/png");
+		map.put("gif","image/gif");
+		return map;
+	}
+}

Propchange: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/http/util/MIMETypeUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JUnitRunnerServlet.java
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JUnitRunnerServlet.java?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JUnitRunnerServlet.java (added)
+++ felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JUnitRunnerServlet.java Fri Mar 14 02:52:26 2008
@@ -0,0 +1,458 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.sandbox.junitrunner.impl;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.net.URLEncoder;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import org.apache.felix.sandbox.http.util.GenericHttpContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.log.LogService;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * Servlet to manage the framework. It is also a SCR component.
+ * @todo improve CSS default style
+ * @todo set synchro on tests, logService and httpService
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class JUnitRunnerServlet extends HttpServlet {
+	private static final String TESTPATH_SEPARATOR="/";
+
+	private static final String TITLE = "JUnit Runner";
+
+	private static final boolean TRACE=true;
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	private final static String WEBROOT = "/webroot";
+	private final static String WEBROOT_ALIAS = "/junit/";
+	private final static String SERVLET_ALIAS = "/junit";
+
+	
+	// set in activate() !!
+	private BundleContext bundleContext;
+	
+    private HttpService httpService=null;
+    private Servlet myServlet=null;
+    private Dictionary myServletInitParams=null;
+
+    private HttpContext myHttpContext=null;
+
+    // set in init()
+    private ServletConfig servletConfig=null;    
+    
+    public JUnitRunnerServlet() {
+        myServlet=this;
+
+        myServletInitParams=new Hashtable();
+        // there are only samples !
+        myServletInitParams.put("webinf.dir","/WEB-INF");
+        myServletInitParams.put("webroot.dir","/webroot");
+        myServletInitParams.put("mimetype.file","/WEB-INF/mimetype.txt");
+        myServletInitParams.put("htaccess.file","/WEB-INF/.htaccess");
+        myServletInitParams.put("icons.uri","icons");
+        
+        myHttpContext = new GenericHttpContext();
+        // MIME types defined in /WEB-INF/mimetype.txt are loaded 
+        // during activate() call just after bindHttpService() calls   	
+    }
+    
+    // callback methods for <requires service="org.osgi.service.http.HttpService" ...
+    
+    public synchronized void bindHttpService(HttpService ref){
+    	httpService=ref;
+    	try {    		
+    		// remark: before activate() invocation, myHttpContext does not deal
+    		// with the MIME type defined in /WEB-INF/mimetype.txt
+    		// This is a limit of the SCR !
+	    	httpService.registerServlet(SERVLET_ALIAS, myServlet, myServletInitParams, myHttpContext);
+	    	httpService.registerResources(WEBROOT_ALIAS, WEBROOT, myHttpContext);
+    	} catch (Exception e) {
+    		if(logService!=null) {
+    			logService.log(LogService.LOG_ERROR,"error while servlet registration",e);
+    		} else {
+    			e.printStackTrace(System.err);
+    		}
+    	}
+    }
+
+    public synchronized void unbindHttpService(HttpService ref){
+    	httpService.unregister(SERVLET_ALIAS);
+    	httpService.unregister(WEBROOT_ALIAS);
+    	httpService=null;
+    }
+
+    // callback methods for <requires service="org.osgi.service.log.LogService" ...
+    private LogService logService = null;
+
+    public synchronized void bindLogService(LogService ref){
+    	logService=ref;
+    }
+
+    public synchronized void unbindLogService(LogService ref){
+    	logService=null;
+    }
+
+    // callback methods for <requires service="org.junit.Test" ...
+    private Vector/*<junit.framework.Test>*/ tests=new Vector();
+
+    public synchronized void bindTest(Test ref){
+    	tests.add(ref);
+    }
+
+    public synchronized void unbindTest(Test ref){
+    	tests.remove(ref);
+    }
+    
+    
+	/**
+	 * @param componentContext
+	 */
+	public void activate(ComponentContext componentContext) {
+		trace(this.toString()+": call activate()");
+		bundleContext=componentContext.getBundleContext();
+		try {
+			((GenericHttpContext)myHttpContext).setExtensionToMimeTypeMap(bundleContext.getBundle().getResource("/WEB-INF/mimetype.txt").openStream());
+		} catch(Exception e) {
+			// do nothing
+		}
+	}
+
+	/**
+	 * @param componentContext
+	 */
+	public void deactivate(ComponentContext componentContext) {
+		trace(this.toString()+": call desactivate()");
+	}
+	
+	/** 
+	 * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
+	 */
+	public void init(ServletConfig servletConfig){
+		trace(this.toString()+": call init()");
+		Enumeration enumeration=servletConfig.getInitParameterNames();
+		if(!enumeration.hasMoreElements())
+			trace(this.toString()+": no init parameters");
+		else {
+			trace(this.toString()+": init parameters are :");
+			while(enumeration.hasMoreElements()){
+				String name=(String) enumeration.nextElement();
+				trace(name+"="+servletConfig.getInitParameter(name));				
+			}
+		}
+	}
+	
+	/**
+	 * @see javax.servlet.Servlet#destroy()
+	 */
+	public void destroy(){
+		trace(this.toString()+": call destroy()");
+		// make persistent some variables by using bundleContext.getDataFile("/STATE-INF/state.save.txt") !
+		// here or in deactivate()
+	}
+	
+	/**
+	 *  Handle a GET call from the client
+	 *
+	 * @param request HTTP request information from the client
+	 * @param response HTTP channel back to the client browser
+	 * @throws IOException If there is an IO problem
+	 * @throws ServletException if there is a proble with the servlet processing
+	 **/
+	public void doGet(HttpServletRequest request, HttpServletResponse response)
+		throws IOException, ServletException {
+		trace(this.toString()+": call doGet()");
+		doPostGet(request, response);
+	}
+
+	/**
+	 *  Handle a POST call from the client
+	 *
+	 * @param request HTTP request information from the client
+	 * @param response HTTP channel back to the client browser
+	 * @throws IOException If there is an IO problem
+	 * @throws ServletException if there is a proble with the servlet processing
+	 **/
+	public void doPost(
+			HttpServletRequest request,
+			HttpServletResponse response)
+			throws IOException, ServletException {
+		trace(this.toString()+": call doPost()");
+		doPostGet(request, response);
+	}
+	
+	/**
+	 *  Handle a POST and GET call from the client
+	 *
+	 * @param request HTTP request information from the client
+	 * @param response HTTP channel back to the client browser
+	 * @throws IOException If there is an IO problem
+	 * @throws ServletException if there is a proble with the servlet processing
+	 **/
+	protected void doPostGet(
+		HttpServletRequest request,
+		HttpServletResponse response)
+		throws IOException, ServletException {
+
+		final String mimetype="text/html";
+		String xslt = request.getParameter("xslt"); // TODO: only with text/xml
+	
+		String css = request.getParameter("css"); // only with text/html
+		if(css==null) css=WEBROOT_ALIAS+"/style.css";
+
+		String title = request.getParameter("title");
+		if(title==null){
+			title=TITLE;
+		}
+		
+		response.setContentType("text/html");
+
+		PrintStream out = new PrintStream(response.getOutputStream());
+		response.setContentType("text/html");
+		PrintWriter pw = response.getWriter();
+		pw.println("<html>");
+		pw.println("<head>");
+		pw.print("<title>");
+		pw.print(title);
+		pw.println("</title>");
+		if (css != null)
+			pw.println(
+				"<link rel='stylesheet' type='text/css' href='"
+					+ css
+					+ "'>");
+		pw.println("</head>");
+		out.println("<body>");
+		String run= (String) request.getParameter("run");
+		String browse = (String) request.getParameter("browse");
+		String servletcontextpath=request.getRequestURI();
+		String menu=	"<a href=\""+servletcontextpath+"?run=all\">Run all tests</a>"
+		             +"| <a href=\""+servletcontextpath+"?browse=all\">Browse all tests</a>"
+		             +"<hr>";
+
+		if (run == null) {
+			// list all tests
+			// content links to particular test
+
+			boolean recursiveEnumeration=false;
+			if(browse!=null && browse.equals("all")) recursiveEnumeration=true;
+			Enumeration e = tests.elements();
+			if(e.hasMoreElements()){
+				out.println("<h1>"+TITLE+": List of available tests</h1>");
+			out.println(menu);
+				enumerate(out,e,"",recursiveEnumeration,servletcontextpath);
+			} else {
+				out.println("<h1>"+TITLE+": No available test</h1><hr>");
+			out.println(menu);
+			}
+		} else {
+			out.println("<h1>"+TITLE+": Run tests</h1>");
+			out.println(menu);
+
+			if(run.equals("all")){
+				for (Enumeration e = tests.elements() ; e.hasMoreElements() ;) {
+					Test t=(Test) e.nextElement();
+					String name=getTestName(t);
+					out.println("<h2>Results for test: "+name+"</h2><pre>");
+					run(out,t);
+					out.println("</pre><hr>");
+				}
+			} else {
+				Vector matchedtests=new Vector();
+				for (Enumeration e = tests.elements() ; e.hasMoreElements() ;) {
+					matchedtests.addAll(lookFor((Test) e.nextElement(),run));
+				}
+				Enumeration em = matchedtests.elements();
+				if(!em.hasMoreElements()) {
+					out.println("<h2>No test matched "+run+"</h2>");
+				}
+				while(em.hasMoreElements()) {
+					Test t=(Test) em.nextElement();
+					String name=getTestName(t);
+					out.println("<h2>Results for test: "+name+"</h2><pre>");
+					run(out,t);
+					out.println("</pre><hr>");
+				}
+			}
+		}
+
+		out.println("</body>");
+		out.println("</html>");
+	}
+
+	void run(PrintStream out, Test ts) {
+		junit.textui.TestRunner aTestRunner= new junit.textui.TestRunner(out);
+		try {
+			TestResult r= aTestRunner.doRun(ts,false);
+			if (!r.wasSuccessful())
+				out.println("Erroneous");
+		} catch(Exception e) {
+			out.println(e.getMessage());
+		}
+	}
+
+	void enumerate(PrintStream out, Enumeration testenum, String parentPath, boolean recursiveEnumeration, String servletcontextpath) {
+
+		out.println("<ul>");
+		while (testenum.hasMoreElements()) {
+			Test test=(Test) testenum.nextElement();
+			String tname=getTestName(test);
+			String myPath=parentPath+TESTPATH_SEPARATOR+tname;
+			String myEncodedPath=URLEncoder.encode(myPath);
+			out.println("<li>"+tname);
+			try {
+				TestSuite testsuite=(TestSuite)test;
+				out.println("<a href=\""+servletcontextpath+"?run="+myEncodedPath+"\">Run</a>");
+				//out.println("| <a href=\""+getContextPath()+"?browse="+myEncodedPath+"\">Browse</a>");
+				if(recursiveEnumeration) enumerate(out, testsuite.tests(), myPath, recursiveEnumeration,servletcontextpath); // recursive call in nested TestSuite
+			} catch (Exception ex) {}
+			try {
+				TestCase testcase=(TestCase)test;
+				out.println("<a href=\""+servletcontextpath+"?run="+myEncodedPath+"\">Run</a>");
+			} catch (Exception ex) {}
+			out.println("</li>");
+		}
+		out.println("</ul>");
+	}
+
+
+	Vector/*<Test>*/ lookFor(Test test, String testrelativepath){
+		Vector matchedtests=new Vector();
+		int startsep;
+		int endsep;
+		String tname;
+		String tailpath;
+		trace("lookFor("+test+","+testrelativepath+")");
+		if(testrelativepath.length()==0) { // testrelativepath starts with '/'
+			return matchedtests;
+		}
+		startsep=testrelativepath.indexOf(TESTPATH_SEPARATOR);
+		if(startsep==-1) { // no separator
+			tname=testrelativepath;
+			tailpath=null;
+		} else {
+			if(startsep==0) { // testrelativepath starts with '/'
+				startsep=1;
+				endsep=testrelativepath.indexOf(TESTPATH_SEPARATOR,startsep+1);
+			} else {
+				endsep=startsep;
+			}
+			if(endsep==-1){
+				tname=testrelativepath.substring(startsep);
+				tailpath=null;
+			} else {
+				tname=testrelativepath.substring(startsep, endsep);
+				tailpath=testrelativepath.substring(endsep);
+			}
+		}
+		try {
+			TestSuite testsuite=(TestSuite)test;
+			trace("lookFor TestSuite:"+testsuite.toString()+":"+tname);
+			if(!testsuite.getName().equals(tname)) return matchedtests;
+			Enumeration en=testsuite.tests();
+			while(en.hasMoreElements()){
+				Test t=(Test)en.nextElement();
+				if(tailpath!=null){
+					matchedtests.addAll(
+					        lookFor(t,tailpath)
+					);
+				} else {
+					matchedtests.add(t);
+				}
+			}
+		} catch (Exception ex) {}
+		try {
+			TestCase testcase=(TestCase)test;
+			trace("lookFor TestCase:"+testcase.toString()+":"+tname);
+			if(!testcase.getName().equals(tname)) return matchedtests;
+			matchedtests.add(testcase);
+		} catch (Exception ex) {}
+
+		// TO CONTINUE
+		return matchedtests;
+	}
+
+	String getTestName(Test test){
+		String name="noname";
+
+		try {
+			name=((TestCase)test).getName();
+		} catch (Exception e) {}
+
+		try {
+			name=((TestSuite)test).getName();
+		} catch (Exception e) {}
+
+		/*
+		if(test instanceof TestCase){
+			return ((TestCase)test).getName();
+	}
+		if(test instanceof TestSuite){
+			return ((TestSuite)test).getName();
+	}
+		*/
+
+		/*
+		Class clazz=test.getClass();
+		try {
+			Method method=clazz.getMethod("getName",null);
+			String tmpname=(String) method.invoke(test,null);
+			if(tmpname!=null) name=tmpname;
+	} catch (Exception e) {
+	}
+		*/
+
+		if(name==null) name="noname";
+		return name;
+	}
+	
+	// should be replaced by the log !!
+	private void trace(String message){
+		if(TRACE)
+			System.out.println(message);
+	}
+}
+

Propchange: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JUnitRunnerServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JunitCommandImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JunitCommandImpl.java?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JunitCommandImpl.java (added)
+++ felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JunitCommandImpl.java Fri Mar 14 02:52:26 2008
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.felix.sandbox.junitrunner.impl;
+
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import org.apache.felix.shell.Command;
+
+/**
+ * This class creates a shell command to run/inspect tests
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class JunitCommandImpl implements Command {
+	//private BundleContext					context;
+
+	private static final boolean TRACE=true;
+
+	private static final String TITLE = "JUnit Runner";
+	
+    // callback methods for <requires service="org.junit.Test" ...
+    private Vector/*<junit.framework.Test>*/ tests=new Vector();
+
+    public synchronized void bindTest(Test ref){
+    	tests.add(ref);
+    }
+
+    public synchronized void unbindTest(Test ref){
+    	tests.remove(ref);
+    }
+    
+	public JunitCommandImpl(/*BundleContext context*/) {
+		super(/*BundleContext context*/);
+	}
+
+	public String getName()
+	{
+		return "junit";
+	}
+
+	public String getUsage()
+	{
+		return "junit <-b|-r> <testname>";
+	}
+
+	public String getShortDescription()
+	{
+		return "browse and run registered JUNIT services.";
+	}
+
+	public void execute(String s, PrintStream out, PrintStream err)
+	{
+		StringTokenizer st = new StringTokenizer(s, " ");
+
+		// Ignore the command name.
+		st.nextToken();
+
+		boolean optionIsRun=false;
+		boolean optionIsBrowse=false;
+		String testname=null;
+
+		if(st.hasMoreTokens()){
+			String args1=st.nextToken();
+			if(args1.equals("-r")) {
+				optionIsRun=true;
+			} else if(args1.equals("-b")) {
+				optionIsBrowse=true;
+			} else {
+				err.println(getUsage());
+				return;
+			}
+
+			if(st.hasMoreTokens()){
+				testname=st.nextToken();
+			}
+		} else {
+			optionIsBrowse=true;
+		}
+
+		if(optionIsRun){
+			if(true) {for (Enumeration e = tests.elements() ; e.hasMoreElements() ;) {
+					Test t=(Test) e.nextElement();
+					String name=getTestName(t);
+					out.println("Results for test: "+name+"");
+					run(out,t);
+				}
+			} else {
+				Vector matchedtests=new Vector();
+				for (Enumeration e = tests.elements() ; e.hasMoreElements() ;) {
+					matchedtests.addAll(lookFor((Test) e.nextElement(),testname));
+				}
+				Enumeration em = matchedtests.elements();
+				if(!em.hasMoreElements()) {
+					out.println("No test matched "+testname);
+				}
+				while(em.hasMoreElements()) {
+					Test t=(Test) em.nextElement();
+					String name=getTestName(t);
+					out.println("Results for test: "+name);
+					run(out,t);
+				}
+			}
+
+		} else {
+			boolean recursiveEnumeration=false;
+			if(testname!=null) recursiveEnumeration=true;
+			Enumeration e = tests.elements();
+			if(e.hasMoreElements()){
+				out.println(TITLE+": List of available tests");
+				enumerate(out,e,"",recursiveEnumeration);
+			} else {
+				out.println(TITLE+": No available test");
+			}
+
+		}
+	}
+
+	private static final String TESTPATH_SEPARATOR="/";
+
+	void enumerate(PrintStream out, Enumeration testenum, String parentPath, boolean recursiveEnumeration) {
+
+		while (testenum.hasMoreElements()) {
+			Test test=(Test) testenum.nextElement();
+			String tname=getTestName(test);
+			String myPath="  "+parentPath+TESTPATH_SEPARATOR+tname;
+			out.println(myPath);
+			try {
+				TestSuite testsuite=(TestSuite)test;
+				if(recursiveEnumeration) enumerate(out, testsuite.tests(), myPath, recursiveEnumeration); // recursive call in nested TestSuite
+			} catch (Exception ex) {}
+		}
+	}
+
+	void run(PrintStream out, Test ts) {
+		junit.textui.TestRunner aTestRunner= new junit.textui.TestRunner(out);
+		try {
+			TestResult r= aTestRunner.doRun(ts,false);
+			if (!r.wasSuccessful())
+				out.println("Erroneous");
+		} catch(Exception e) {
+			out.println(e.getMessage());
+		}
+	}
+
+
+	Vector/*<Test>*/ lookFor(Test test, String testrelativepath){
+		Vector matchedtests=new Vector();
+		int startsep;
+		int endsep;
+		String tname;
+		String tailpath;
+		trace("lookFor("+test+","+testrelativepath+")");
+		if(testrelativepath.length()==0) { // testrelativepath starts with '/'
+			return matchedtests;
+		}
+		startsep=testrelativepath.indexOf(TESTPATH_SEPARATOR);
+		if(startsep==-1) { // no separator
+			tname=testrelativepath;
+			tailpath=null;
+		} else {
+			if(startsep==0) { // testrelativepath starts with '/'
+				startsep=1;
+				endsep=testrelativepath.indexOf(TESTPATH_SEPARATOR,startsep+1);
+			} else {
+				endsep=startsep;
+			}
+			if(endsep==-1){
+				tname=testrelativepath.substring(startsep);
+				tailpath=null;
+			} else {
+				tname=testrelativepath.substring(startsep, endsep);
+				tailpath=testrelativepath.substring(endsep);
+			}
+		}
+		try {
+			TestSuite testsuite=(TestSuite)test;
+			trace("lookFor TestSuite:"+testsuite.toString()+":"+tname);
+			if(!testsuite.getName().equals(tname)) return matchedtests;
+			Enumeration en=testsuite.tests();
+			while(en.hasMoreElements()){
+				Test t=(Test)en.nextElement();
+				if(tailpath!=null){
+					matchedtests.addAll(
+					        lookFor(t,tailpath)
+					);
+				} else {
+					matchedtests.add(t);
+				}
+			}
+		} catch (Exception ex) {}
+		try {
+			TestCase testcase=(TestCase)test;
+			trace("lookFor TestCase:"+testcase.toString()+":"+tname);
+			if(!testcase.getName().equals(tname)) return matchedtests;
+			matchedtests.add(testcase);
+		} catch (Exception ex) {}
+
+		// TO CONTINUE
+		return matchedtests;
+	}
+
+	String getTestName(Test test){
+		String name="noname";
+
+		try {
+			name=((TestCase)test).getName();
+		} catch (Exception e) {}
+
+		try {
+			name=((TestSuite)test).getName();
+		} catch (Exception e) {}
+
+		/*
+		if(test instanceof TestCase){
+			return ((TestCase)test).getName();
+	}
+		if(test instanceof TestSuite){
+			return ((TestSuite)test).getName();
+	}
+		*/
+
+		/*
+		Class clazz=test.getClass();
+		try {
+			Method method=clazz.getMethod("getName",null);
+			String tmpname=(String) method.invoke(test,null);
+			if(tmpname!=null) name=tmpname;
+	} catch (Exception e) {
+	}
+		*/
+
+		if(name==null) name="noname";
+		return name;
+	}
+
+	// should be replaced by the log !!
+	private void trace(String message){
+		if(TRACE)
+			System.out.println(message);
+	}
+	
+}
+

Propchange: felix/sandbox/donsez/junitrunner/src/main/java/org/apache/felix/sandbox/junitrunner/impl/JunitCommandImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.cmd.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.cmd.xml?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.cmd.xml (added)
+++ felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.cmd.xml Fri Mar 14 02:52:26 2008
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component name="junit.cmd" immediate="true">
+  <!-- xmlns="http://www.osgi.org/xmlns/scr/v1.0.0" -->
+	<implementation class="org.apache.felix.sandbox.junitrunner.impl.JunitCommandImpl"/>
+		
+	<service>
+		<provide interface="org.apache.felix.shell.Command"/>
+	</service>
+	
+	<reference name="TEST"
+	    interface="junit.framework.Test"
+	    cardinality="0..n"
+	    policy="dynamic"
+	    bind="bindTestService"
+	    unbind="unbindTestService"
+	/>
+	
+	<reference name="LOG"
+	    interface="org.osgi.service.log.LogService"
+	    cardinality="0..1"
+	    policy="dynamic"
+	    bind="bindLogService"
+	    unbind="unbindLogService"
+	/>
+	
+</component>

Propchange: felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.cmd.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.servlet.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.servlet.xml?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.servlet.xml (added)
+++ felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.servlet.xml Fri Mar 14 02:52:26 2008
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component name="junit.servlet" immediate="true">
+  <!-- xmlns="http://www.osgi.org/xmlns/scr/v1.0.0" -->
+  
+	<implementation class="org.apache.felix.sandbox.junitrunner.impl.JUnitRunnerServlet"/>
+
+	<reference name="HTTP"
+	    interface="org.osgi.service.http.HttpService"
+	    cardinality="1..1"
+	    policy="static"
+	    bind="bindHttpService"
+	    unbind="unbindHttpService"
+	/>
+
+	<reference name="TEST"
+	    interface="junit.framework.Test"
+	    cardinality="0..n"
+	    policy="dynamic"
+	    bind="bindTestService"
+	    unbind="unbindTestService"
+	/>
+
+	<reference name="LOG"
+	    interface="org.osgi.service.log.LogService"
+	    cardinality="0..1"
+	    policy="dynamic"
+	    bind="bindLogService"
+	    unbind="unbindLogService"
+	/>
+	
+</component>

Propchange: felix/sandbox/donsez/junitrunner/src/main/resources/OSGI-INF/component.servlet.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/mimetype.txt
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/mimetype.txt?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/mimetype.txt (added)
+++ felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/mimetype.txt Fri Mar 14 02:52:26 2008
@@ -0,0 +1,135 @@
+# This is a dump of a typical MIME type file on a Linux/Unix server. This file controls what MIME types are sent to the client for the given file extensions. Sending the correct MIME type to the client is important so they know how to handle the content of the file. Extra types can either be added here or by using an AddType directive in your config files.
+# For more information about MIME types
+# please read RFC 2045, 2046, 2047, 2048, and 2077. 
+
+# see http://fr.selfhtml.org/divers/typesmime.htm
+
+# MIME type Extension
+application/activemessage
+application/andrew-inset
+application/applefile
+application/atomicmail
+application/dca-rft
+application/dec-dx
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/octet-stream bin dms lha lzh exe class
+application/oda oda
+application/pdf pdf
+application/postscript ai eps ps
+application/powerpoint ppt
+application/remote-printing
+application/rtf rtf
+application/slate
+application/smil smi smil sml
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-mif mif
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/zip zip
+audio/basic au snd
+audio/midi midi kar
+audio/x-midi mid
+audio/mpeg mpga mp2 mp3
+audio/x-aiff aif aiff aifc
+audio/x-pn-realaudio ram
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb xyz
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/png png
+image/tiff tiff tif
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/external-body
+message/news
+message/partial
+message/rfc822
+model/iges igs iges
+model/vrml wrl vrml
+model/mesh msh mesh silo
+multipart/alternative
+multipart/appledouble
+multipart/digest
+multipart/mixed
+multipart/parallel
+text/css css
+text/html html htm
+text/plain txt
+text/richtext rtx
+text/tab-separated-values tsv
+text/x-setext etx
+text/x-sgml sgml sgm
+text/xml xml dtd
+video/mpeg mpeg mpg mpe
+video/quicktime qt mov
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+
+# More mapping !
+
+application/x-shockwave-flash swf
+
+text/javascript js
+# application/x-javascript js
+
+text/json json
+# text/x-json json
+# application/json
+
+text/csv csv
+# text/comma-separated-values 
+# application/csv 
+# application/excel 
+# application/vnd.ms-excel 
+# application/vnd.msexcel 
+
+# WAP forum
+text/vnd.wap.wml wml 
+text/vnd.wap.wmlscript wmls 
+image/vnd.wap.wbmp wbmp 
+application/vnd.wap.wmlc wmlc 
+application/vnd.wap.wmlscriptc wmlsc 

Propchange: felix/sandbox/donsez/junitrunner/src/main/resources/WEB-INF/mimetype.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/main/resources/webroot/logofelix.png
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/resources/webroot/logofelix.png?rev=637026&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/sandbox/donsez/junitrunner/src/main/resources/webroot/logofelix.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/sandbox/donsez/junitrunner/src/main/resources/webroot/style.css
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/main/resources/webroot/style.css?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/main/resources/webroot/style.css (added)
+++ felix/sandbox/donsez/junitrunner/src/main/resources/webroot/style.css Fri Mar 14 02:52:26 2008
@@ -0,0 +1,224 @@
+
+
+body {
+	margin-top:4px;
+	margin-left:4px;
+}
+
+
+p {
+	color:black;
+  	font-size: 12px;
+	font-family: verdana;
+	font-weight:normal;
+	line-height:15px;
+}
+
+table.bundles {
+	border-style:solid; 
+	border-width:1px; 
+	border-color:black;
+	width:90%;
+	border-collapse:collapse;
+	margin:auto;
+}
+
+td {
+	color:black;
+  	font-size: 12px;
+	font-family: verdana;
+	font-weight:normal;
+	line-height:15px;
+	border-top: solid 1px;
+}
+
+td.action {
+	color:black;
+  	font-size: 9px;
+	font-family: verdana;
+	font-weight:normal;
+	text-align: right;
+	border-top: solid 1px;
+}
+
+a:link {
+  color:#00669C; 
+  font-weight:bold;
+  text-decoration: none; 
+}
+a:visited {
+  color:#00669C; 
+  text-decoration: none; 
+  font-weight:bold;
+}
+a:hover {
+  color:#A00000; 
+  font-weight:bold;
+  text-decoration: underline; 
+}
+a.mem:link {
+  font-size: 12px;
+  color:#00669C; 
+  text-decoration: underline; 
+}
+a.mem:visited {
+  font-size: 12px;
+  color:#00669C; 
+  text-decoration: underline; 
+}
+a.mem:hover {
+  font-size: 12px;
+  color:#00669C; 
+  text-decoration: underline; 
+}
+a.mem:active {
+  font-size: 12px;
+  color:#00669C; 
+  text-decoration: underline; 
+}
+.page-title {
+	color:black;
+  	font-size: 17px;
+	font-weight: bold;
+	font-family: verdana;
+	padding-top:12px;
+	padding-bottom:4px;
+}
+.page-sub-title {
+	color:#00669C; 
+ 	font-weight:bold;
+  	text-decoration: none; 
+  	font-size: 15px;
+	font-weight: bold;
+	font-family: verdana;
+	padding-top:12px;
+	padding-bottom:4px;
+}
+.default {
+	color:black;
+  	font-size: 12px;
+	font-family: verdana;
+	line-height:15px;
+}
+.small {
+	color:gray;
+  	font-size: 10px;
+	font-family: verdana;
+	padding-bottom:5px;
+}
+.to-do {
+	color:red;
+  	font-size: 12px;
+	font-family: verdana;
+	font-weight:normal;
+	line-height:15px;
+	font-style:italic;
+	padding-top:12px;
+	padding-bottom:12px;
+}
+
+.box-header {
+  font-family: verdana;
+  color:#FFFFFF;
+  font-size: 11px;
+  font-weight: bold;
+  margin-top : 16px;
+  margin-left : 12px;
+  background-image:url("images/bg0.gif");
+  background-repeat:repeat;
+  height:24px;
+  width:174px;
+  vertical-align:middle;
+}
+.box {
+  text-align: left;
+  font-family: verdana;
+  color:#0;
+  font-size: 11px;
+  height:100px;
+  padding:6px;
+  margin-left:12px;
+  border:1px solid #A5BDDE;
+  width:174px;
+  vertical-align:top;
+  text-align:center;
+}
+.left-nav-menu {
+  text-align: left;
+  font-family: verdana;
+  color:#00669C;
+  font-size: 11px;
+  font-weight: bold;
+  background-image:url("images/bg0.gif");
+  background-repeat:repeat;
+  padding:7px;
+}
+a.left-nav-menu:hover {
+  text-decoration: none; 
+}
+.left-nav-gradient {
+  background-image:url("images/bg0_gradient.jpg");
+  background-repeat:repeat-x;
+}
+
+.footer {
+  font-family: verdana;
+  color:#00669C;
+  font-size: 11px;
+  font-weight: bold;
+}
+a.footer:hover {
+	color:#800000;
+	text-decoration: underline;
+}
+h1 {
+	color:black;
+  	font-size: 18px;
+	font-weight: bold;
+	font-family: verdana;
+	padding-top:12px;
+	padding-bottom:4px;
+    text-align:center;    
+	border:1px 
+	solid #B5B5B5
+}
+h2 {
+	color:white;
+  	font-size: 16px;
+	font-weight: bold;
+	font-family: verdana;
+  	margin-top:5px;
+  	margin-bottom:0px;
+	padding-top:6px;
+    padding-left:2px;
+	padding-bottom:6px;
+    background-image:url("/images/background-blue.gif");
+}
+h3 {
+	color:black;
+  	font-size: 14px;
+	font-weight: bold;
+	font-family: verdana;
+	padding-top:12px;
+	padding-bottom:4px;
+    text-decoration: underline; 
+}
+h4 {
+	color:black;
+  	font-size: 14px;
+	font-weight: bold;
+	font-family: verdana;
+    text-decoration: none; 
+}
+.box1 { 
+	font-size:14px; 
+	font-family:  verdana; 
+	border:1px 
+	solid #B5B5B5
+}
+.box2 { 
+	font-size:10px; 
+	font-family:  verdana; 
+	border:1px 
+	solid #B5B5B5
+}
\ No newline at end of file

Propchange: felix/sandbox/donsez/junitrunner/src/main/resources/webroot/style.css
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/site/readme.html
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/site/readme.html?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/site/readme.html (added)
+++ felix/sandbox/donsez/junitrunner/src/site/readme.html Fri Mar 14 02:52:26 2008
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>Apache Felix JUnit Runner (sandbox)</title>
+</head>
+<body>
+
+<!-- Start of Felix Bundle Documentation -->
+<hr width="100%" size="2">
+<h1><i><a name="junitrunner"></a><font color="#0000aa">Apache Felix JUnit Runner (sandbox)</font></i></h1>
+
+<p>
+<b>Description</b><br>
+provides services (Command and Servlet) to test Services following the JUnit pattern
+<br>For more details on how to use this bundle, refer to the ./site/readme.html file in the project sources.<br>
+</p>
+
+<p>
+<b>Contributors</b><br>
+<ul>
+<li>Author:<a href="mailto:dev@felix.apache.org">Felix Project Team</a></li>
+</ul>
+</p>
+
+<p>
+<b>License</b><br>
+ASL v2<br>
+</p>
+
+
+<hr width="100%" size="2">
+
+<p id="build">
+<b>Build</b><br>
+<ol>
+<li>build with <code>mvn clean install</code></li>
+</ol>
+</p>
+
+<p id="rundemo">
+<b>Run the demo</b><br>
+To run the demo of this bundle, enter the following commands in the Felix shell ./src/site/script.txt<br>
+
+<p id="todo">
+<b>TODO (contributions are welcome)</b><br>
+<ul>
+<li>A Ajaxified version of the Http-based runner</li>
+<li>JUnitRunnerMXBean to run tests from a JMX console</li>
+</ul>
+</p>
+
+</body>
+</html>

Propchange: felix/sandbox/donsez/junitrunner/src/site/readme.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/junitrunner/src/site/script.txt
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/junitrunner/src/site/script.txt?rev=637026&view=auto
==============================================================================
--- felix/sandbox/donsez/junitrunner/src/site/script.txt (added)
+++ felix/sandbox/donsez/junitrunner/src/site/script.txt Fri Mar 14 02:52:26 2008
@@ -0,0 +1,12 @@
+obr add-url file:C:\docume~1\Donsez\.m2\repository\repository.xml
+
+obr start "OSGi R4 Compendium Bundle"
+start http://repository.ops4j.org/maven2/org/ops4j/pax/url/pax-url-mvn/0.3.0/pax-url-mvn-0.3.0.jar
+start http://repository.ops4j.org/maven2/org/ops4j/pax/url/pax-url-wrap/0.3.0/pax-url-wrap-0.3.0.jar
+
+start wrap:mvn:junit/junit/3.8.1
+
+obr start "Apache Felix Declarative Services"
+obr start "Apache Felix JUnit Runner"
+
+rem browse http://localhost:8080/junit
\ No newline at end of file

Propchange: felix/sandbox/donsez/junitrunner/src/site/script.txt
------------------------------------------------------------------------------
    svn:eol-style = native