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