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/01/12 22:55:47 UTC

svn commit: r611493 - in /felix/sandbox/donsez/wireadminbinder.cmd: ./ 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/san...

Author: donsez
Date: Sat Jan 12 13:55:45 2008
New Revision: 611493

URL: http://svn.apache.org/viewvc?rev=611493&view=rev
Log:
creation of the wireadminbinder command, a Felix shell command to use the WireAdminBinder.

Added:
    felix/sandbox/donsez/wireadminbinder.cmd/
    felix/sandbox/donsez/wireadminbinder.cmd/pom.xml   (with props)
    felix/sandbox/donsez/wireadminbinder.cmd/src/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/LoadUtils.java   (with props)
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/
    felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/WABCommand.java   (with props)
    felix/sandbox/donsez/wireadminbinder.cmd/src/site/
    felix/sandbox/donsez/wireadminbinder.cmd/src/site/readme.html   (with props)

Added: felix/sandbox/donsez/wireadminbinder.cmd/pom.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/wireadminbinder.cmd/pom.xml?rev=611493&view=auto
==============================================================================
--- felix/sandbox/donsez/wireadminbinder.cmd/pom.xml (added)
+++ felix/sandbox/donsez/wireadminbinder.cmd/pom.xml Sat Jan 12 13:55:45 2008
@@ -0,0 +1,94 @@
+<!--
+ 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>
+		<description>shell command to use the WireAdminBinder.</description>
+	</properties>  
+
+
+
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>Apache Felix Wire Admin Binder Command</name>
+  <artifactId>org.apache.felix.sandbox.wireadminbinder.cmd</artifactId>
+  <groupId>org.apache.felix.sandbox</groupId>
+  <version>0.1.0</version>
+  <description>${description}</description>
+
+  <dependencies>
+
+	<dependency>
+		<groupId>org.apache.felix</groupId>
+		<artifactId>org.osgi.core</artifactId>
+  		<version>1.1.0-SNAPSHOT</version>
+	</dependency>
+	
+	<dependency>
+		<groupId>org.apache.felix</groupId>
+		<artifactId>org.osgi.compendium</artifactId>
+  		<version>0.9.0-SNAPSHOT</version>
+	</dependency>
+        
+	<dependency>
+		<groupId>org.apache.felix</groupId>
+		<artifactId>org.apache.felix.shell</artifactId>
+  		<version>1.1.0-SNAPSHOT</version>
+	</dependency>
+
+	<dependency>
+		  <groupId>org.apache.felix.sandbox</groupId>
+		  <artifactId>org.apache.felix.sandbox.wireadminbinder</artifactId>
+		  <version>0.1.0</version>
+	</dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+          	<!-- docs in http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html and http://cwiki.apache.org/FELIX/osgi-plugin-for-maven-2.html -->
+          	
+            <Import-Package>
+            	org.osgi.framework,
+            	org.apache.felix.sandbox.wireadminbinder,
+            	org.apache.felix.shell
+            </Import-Package>
+
+            <Private-Package>
+            		${pom.artifactId},
+            		org.apache.felix.sandbox.util.*
+            </Private-Package>
+            
+           	<Bundle-Activator>${pom.artifactId}.WABCommand</Bundle-Activator>
+            
+            <!-- docs in http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html and http://cwiki.apache.org/FELIX/osgi-plugin-for-maven-2.html -->
+            <Export-Service>org.apache.felix.shell.Command</Export-Service>
+            <!-- <Import-Service>org.osgi.service.wireadmin.WireAdmin</Import-Service> -->
+            
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

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

Added: felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/LoadUtils.java
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/LoadUtils.java?rev=611493&view=auto
==============================================================================
--- felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/LoadUtils.java (added)
+++ felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/LoadUtils.java Sat Jan 12 13:55:45 2008
@@ -0,0 +1,127 @@
+/*
+ * 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.util.load;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Utility class to load text from URL or Ressources
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class LoadUtils {
+
+	/**
+	 * Load the text from a document located at an URL
+	 * @param urlStr the url of the document to load
+	 * @return the text contained in the document
+	 * @throws Exception
+	 */
+	public static String loadAsUrl(String urlStr) throws Exception {
+		URL url = null;
+		url = new URL(urlStr);
+		InputStream inputStream = null;
+		BufferedInputStream bufferedInputStream = null;
+		ByteArrayOutputStream byteArrayOutputStream = null;
+
+		try {
+			inputStream = url.openStream();
+			bufferedInputStream = new BufferedInputStream(inputStream);
+			byteArrayOutputStream = new ByteArrayOutputStream();
+			int n;
+			byte[] buffer = new byte[512];
+			while ((n = bufferedInputStream.read(buffer)) != -1) {
+				byteArrayOutputStream.write(buffer, 0, n);
+			}
+			bufferedInputStream.close();
+			inputStream=null;
+			bufferedInputStream=null;
+
+			String res = new String(byteArrayOutputStream.toByteArray());
+			return res;
+		} finally {
+			if (bufferedInputStream != null)
+				try {
+					bufferedInputStream.close();
+					inputStream = null;
+				} catch (IOException e) {
+				}
+			if (inputStream != null)
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+				}
+			if (byteArrayOutputStream != null)
+				try {
+					byteArrayOutputStream.close();
+				} catch (IOException e) {
+				}
+		}
+	}
+
+	/**
+	 * Load the text from a ressource
+	 * @param classLoader classLoader from which the ressource is accessible
+	 * @param path path of the ressource
+	 * @return the text contained in the ressource
+	 * @throws Exception
+	 */public static String loadAsRessource(ClassLoader classLoader, String path)
+	 throws Exception {
+		InputStream inputStream = null;
+		BufferedInputStream bufferedInputStream = null;
+		ByteArrayOutputStream byteArrayOutputStream = null;
+
+		try {
+			inputStream = classLoader.getResourceAsStream(path);
+			bufferedInputStream = new BufferedInputStream(inputStream);
+			byteArrayOutputStream = new ByteArrayOutputStream();
+			int n;
+			byte[] buffer = new byte[512];
+			while ((n = bufferedInputStream.read(buffer)) != -1) {
+				byteArrayOutputStream.write(buffer, 0, n);
+			}
+			bufferedInputStream.close();
+			inputStream=null;
+			bufferedInputStream=null;
+
+			String res = new String(byteArrayOutputStream.toByteArray());
+			return res;
+		} finally {
+			if (bufferedInputStream != null)
+				try {
+					bufferedInputStream.close();
+					inputStream = null;
+				} catch (IOException e) {
+				}
+			if (inputStream != null)
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+				}
+			if (byteArrayOutputStream != null)
+				try {
+					byteArrayOutputStream.close();
+				} catch (IOException e) {
+				}
+		}
+	}
+}

Propchange: felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/util/load/LoadUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/WABCommand.java
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/WABCommand.java?rev=611493&view=auto
==============================================================================
--- felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/WABCommand.java (added)
+++ felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/WABCommand.java Sat Jan 12 13:55:45 2008
@@ -0,0 +1,335 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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 org.apache.felix.sandbox.wireadminbinder.cmd;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.felix.sandbox.util.load.LoadUtils;
+import org.apache.felix.sandbox.wireadminbinder.BaseActivator;
+import org.apache.felix.shell.Command;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * shell command to start/stop wired applications
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class WABCommand implements Command, BundleActivator {
+
+	private static final String BASE_CMD = "base";
+
+	private static final String START_CMD = "start";
+
+	private static final String STOP_CMD = "stop";
+
+	// private static final String INSTALL_CMD = "install";
+
+	// private static final String UNINSTALL_CMD = "uninstall";
+
+	// private static final String UPDATE_CMD = "update";
+
+	private static final String LIST_CMD = "list";
+
+	private static final String HELP_CMD = "help";
+
+	private BundleContext bundleContext;
+
+	private String baseUrlStr;
+
+	private Map wabs = new HashMap();
+
+	private ServiceRegistration serviceRegistration;
+
+	public WABCommand() {
+	}
+
+	public String getName() {
+		return "wab";
+	}
+
+	public String getUsage() {
+		return "wab [help|base|list|start|stop]";
+	}
+
+	public String getShortDescription() {
+		return "start/stop wireadminbinder applications";
+	}
+
+	private void printUsage(PrintStream out, String message) {
+		StringBuffer sb = new StringBuffer();
+		if (message != null)
+			sb.append(message);
+		sb.append(getUsage()).append('\n');
+		sb.append(
+				"wab " + START_CMD
+						+ " <url> : start a wired application from the url").append('\n');
+		sb.append("wab " + STOP_CMD + " <script id> : stop a wired application")
+				.append('\n');
+		sb.append("wab " + LIST_CMD + " : list all started applications")
+				.append('\n');
+		sb.append("wab " + BASE_CMD + " [new base] : set/get the base for URLs")
+		.append('\n');
+		out.println(sb.toString());
+		return;
+	}
+
+	public void execute(String commandline, PrintStream out, PrintStream err) {
+
+		StringTokenizer st = new StringTokenizer(commandline, " ");
+
+		if (st.countTokens() == 1) {
+			printUsage(out, null);
+			return;
+		}
+
+		// Ignore the command name.
+		st.nextToken();
+
+		if (!st.hasMoreTokens()) {
+			printUsage(out, null);
+			return;
+		}
+
+		String option = st.nextToken().trim();
+
+		if (option.equals(HELP_CMD)) {
+			printUsage(out, null);
+			return;
+		} else if (option.equals(BASE_CMD)) {
+			if (!st.hasMoreTokens()) {
+				out.println("base url is :"+baseUrlStr);
+				return;
+			} else {
+				baseUrlStr = st.nextToken().trim();
+				return;
+			}
+		} else if (option.equals(START_CMD)) {
+			if (!st.hasMoreTokens()) {
+				printUsage(out, "url is missing");
+				return;
+			}
+			String urlstr = st.nextToken().trim();
+
+			WAB wab = new WAB();
+			try {
+				wab.install(urlstr,baseUrlStr);
+				wab.start(bundleContext);
+			} catch (Exception e) {
+				err.println(e);
+				e.printStackTrace(err);
+				return;
+			}
+
+			Integer id = new Integer(wab.getId());
+			wabs.put(id, wab);
+			// TODO save entry to disk
+
+		} else if (option.equals(STOP_CMD)) {
+			if (!st.hasMoreTokens()) {
+				printUsage(out, "the wab number is missing");
+				return;
+			}
+			int id = Integer.parseInt(st.nextToken().trim());
+			Integer number = new Integer(id);
+			WAB script = (WAB) wabs.remove(number);
+			if (script == null) {
+				err.println("this script is stopped or does not exist");
+			} else {
+				try {
+					script.stop(bundleContext);
+				} catch (Exception e) {
+					err.println(e);
+					return;
+				}
+				out.println("the script is stopped");
+			}
+			// TODO save entry to disk
+		} else if (option.equals(LIST_CMD)) {
+			Iterator iterator = wabs.entrySet().iterator();
+			while (iterator.hasNext()) {
+				Map.Entry entry = (Map.Entry) iterator.next();
+				out.print(entry.getKey().toString());
+				out.print(':');
+				// TODO print lifecycle status
+				out.println(((WAB) entry.getValue()).toString());
+			}
+		}
+	}
+
+	public void start(BundleContext bundleContext) throws Exception {
+		this.bundleContext = bundleContext;
+		Dictionary properties = new Hashtable();
+		properties.put("categories", new String[] { "command", "script", "wireadmin" });
+		serviceRegistration = bundleContext.registerService(Command.class
+				.getName(), this, properties);
+	}
+
+	public void stop(BundleContext bundleContext) throws Exception {
+		serviceRegistration.unregister();
+
+		// stop all scripts
+		Iterator iterator = wabs.values().iterator();
+		while (iterator.hasNext()) {
+			((WAB) iterator.next()).shutdown(bundleContext);
+		}
+	}
+}
+
+/**
+ * represents an instance of a wired application
+ */
+class WAB implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private static int wabCounter = 0;
+
+	// TODO for persistence : private int lifecycle;
+	private int id = 0; // may be a long to be consistent with bundle ids
+							// and service ids
+
+	private String urlStr;
+
+	private String baseUrlStr;
+
+	private String metadata;
+
+	private transient BundleActivator bundleActivator;
+
+	public WAB() {
+		super();
+	}
+
+	public String getUrlStr() {
+		return urlStr;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void install(String urlStr, String baseUrlStr) throws Exception {
+		URL url=null;
+		try {
+			url=new URL(urlStr);
+		} catch (MalformedURLException e) {
+			try {
+				if(baseUrlStr==null){
+					throw e;
+				}
+				url=new URL(new URL(baseUrlStr),urlStr);
+			} catch (MalformedURLException e1) {
+				throw e1;
+			}
+		}
+		
+		this.metadata = LoadUtils.loadAsUrl(url.toExternalForm());
+		this.urlStr = urlStr;
+		this.baseUrlStr = baseUrlStr;
+	}
+
+	public void start(BundleContext bundleContext) throws Exception {
+		if (bundleActivator == null) {
+			InputStream inputStream = new ByteArrayInputStream(metadata
+					.getBytes());
+			bundleActivator = new BaseActivator(inputStream);
+			try {
+				bundleActivator.start(bundleContext);
+				// TODO save lifecycle ! use a finally to ensure that
+			} catch (Exception e) {
+				bundleActivator = null;
+				throw e;
+			}
+		} else {
+			throw new IllegalStateException("the wab application is already started");
+		}
+	}
+
+	public void stop(BundleContext bundleContext) throws Exception {
+		if (bundleActivator != null) {
+			BundleActivator _bundleActivator = bundleActivator;
+			bundleActivator = null;
+			_bundleActivator.stop(bundleContext);
+			// TODO save lifecycle ! use a finally to ensure that
+		} else {
+			throw new IllegalStateException("the wab application is already stopped");
+		}
+	}
+
+	public void shutdown(BundleContext bundleContext) throws Exception {
+		bundleActivator.stop(bundleContext);
+	}
+
+	public void update(BundleContext bundleContext) throws Exception {
+		bundleActivator.stop(bundleContext);
+		this.metadata = LoadUtils.loadAsUrl(this.urlStr);
+		bundleActivator.start(bundleContext);
+	}
+
+	public void update(BundleContext bundleContext, String urlStr)
+			throws Exception {
+		bundleActivator.stop(bundleContext);
+		this.metadata = LoadUtils.loadAsUrl(urlStr);
+		// keep this.urlStr unchanged
+		bundleActivator.start(bundleContext);
+	}
+
+	public static void uninstall(BundleContext bundleContext, WAB script)
+			throws Exception {
+		// TODO
+		throw new Exception("Not implemented");
+	}
+
+	public String toString() {
+		return urlStr; // + lifecycle
+	}
+}
+
+// unuseful since R4 !!
+class Activator extends BaseActivator {
+	Activator(InputStream inputStream){
+		super(inputStream);
+	}
+
+	public void start(BundleContext bundleContext) throws Exception {
+		// add pre processing here 
+		super.start(bundleContext);
+		// add post processing here 
+	}
+
+	public void stop(BundleContext bundleContext) {
+		// add pre processing here 
+		super.stop(bundleContext);
+		// add post processing here 
+	}	
+}

Propchange: felix/sandbox/donsez/wireadminbinder.cmd/src/main/java/org/apache/felix/sandbox/wireadminbinder/cmd/WABCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/sandbox/donsez/wireadminbinder.cmd/src/site/readme.html
URL: http://svn.apache.org/viewvc/felix/sandbox/donsez/wireadminbinder.cmd/src/site/readme.html?rev=611493&view=auto
==============================================================================
--- felix/sandbox/donsez/wireadminbinder.cmd/src/site/readme.html (added)
+++ felix/sandbox/donsez/wireadminbinder.cmd/src/site/readme.html Sat Jan 12 13:55:45 2008
@@ -0,0 +1,87 @@
+<html>
+<head>
+<title>WireAdminBinder Command</title>
+</head>
+<body>
+
+<!-- Start of Bundle Documentation -->
+<hr width="100%" size="2">
+<h1><i><a name="wireadminbinder.cmd"></a><font color="#0000aa">WireAdminBinder Command</font></i></h1>
+
+<p>
+<b>Description</b><br>
+provides a command to start/stop wired applications developed with WireAdminBinder 
+<br>see <a href="http://www-adele.imag.fr/users/Didier.Donsez/dev/osgi/wireadminbinder/index.html">WireAdminBinder</a> for more details
+<br>For more details on how to use this bundle, refer to the /doc/readme.html file embedded in the bundle jarfile.<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 2<br>
+</p>
+
+<p>
+<b>Services</b><br>
+org.apache.felix.shell.Command
+</p>
+
+<p>
+<b>Properties</b><br>
+<ul>
+<li>None</li>
+</ul>
+</p>
+
+<p><b>Requirements</b><br>
+org.apache.felix.shell,
+org.apache.felix.sandbox.wireadminbinder
+</p>
+
+<!-- End of Bundle Documentation -->
+
+<hr width="100%" size="2">
+
+<!-- Start of extra information  -->
+
+<p id="build">
+<b>Build</b><br>
+<ol>
+<li>mvn clean install</li>
+</ol>
+</p>
+
+
+<p id="rundemo">
+<b>Run the demo</b><br>
+To run the demo of this bundle, enter in the shell the <a href="http://people.apache.org/~donsez/dev/osgi/wireadminbinder/script.txt">following commands</a><br>
+</p>
+
+<p id="typicalusage">
+<b>Typical Usages</b><br>
+<li>quick wireadmin-based prototyping</li>
+</p>
+
+<p id="versions">
+<b>Versions history</b><br>
+<ul>
+<li>0.1.0, Nov 15 2006</li>
+</ul>
+</p>
+
+<p id="todo">
+<b>TODO (contributions are welcome)</b><br>
+<ul>
+<li>TODO: persistence for wabs</li>
+<li>TODO: wabs lifecycle (install, start, stop, update, uninstall)</li>
+</ul>
+<p>
+
+</body>
+</html>

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