You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/02/12 20:36:19 UTC

svn commit: r743848 [1/2] - in /felix/sandbox/rickhall/bnd-test: ./ cnf/ org.apache.felix.framework.test/ org.apache.felix.framework.test/recipes/ org.apache.felix.framework.test/src/ org.apache.felix.framework.test/src/org/ org.apache.felix.framework....

Author: rickhall
Date: Thu Feb 12 19:36:18 2009
New Revision: 743848

URL: http://svn.apache.org/viewvc?rev=743848&view=rev
Log:
Initial commit of bnd test framework example.

Added:
    felix/sandbox/rickhall/bnd-test/   (with props)
    felix/sandbox/rickhall/bnd-test/cnf/
    felix/sandbox/rickhall/bnd-test/cnf/build.bnd
    felix/sandbox/rickhall/bnd-test/cnf/build.xml
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/bnd.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/build.xml
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cyclea.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cycleb.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/fragment.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/host.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/requirehost.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/FelixTestCase.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestCycle.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFilter.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFragment.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitA.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitB.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleA.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAA.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAAA.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleB.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleBB.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/host/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/host/Host.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message.properties
    felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message_fr.properties
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/bnd.bnd
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/build.xml
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Activator.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Log.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogEntryImpl.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogException.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogListenerThread.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogNode.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogNodeEnumeration.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogReaderServiceFactory.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogReaderServiceImpl.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogServiceFactory.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogServiceImpl.java
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/test/
    felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/test/TestLog.java
    felix/sandbox/rickhall/bnd-test/pom.xml

Propchange: felix/sandbox/rickhall/bnd-test/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Feb 12 19:36:18 2009
@@ -0,0 +1,22 @@
+classes
+target
+*.log
+*.ipr
+*.iws
+*.iml
+lib
+bundle
+dist
+.project
+.classpath
+bin
+build
+.settings
+.wtpmodules
+.deployables
+nbbuild.xml
+nbproject
+*.patch
+.externalToolBuilders
+maven-eclipse.xml
+

Added: felix/sandbox/rickhall/bnd-test/cnf/build.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/cnf/build.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/cnf/build.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/cnf/build.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,57 @@
+# Very general
+project.dependson       = ${p-dependson;:}
+project.bootclasspath   = ${p-bootclasspath;:}
+project.buildpath       = ${p-buildpath;:}
+project.sourcepath      = ${p-sourcepath;:}
+project.allsourcepath   = ${p-allsourcepath;:}
+project.output          = ${p-output}
+project.testpath        = ${p-testpath;:}
+bin                     = ${target}/bin
+verbose                 = false
+project                 = ${basedir}
+target                  = ${project}/${target-dir}
+workspace               = ${dir;${project}}
+build                   = ${workspace}/cnf
+repo                    = ${build}/repo
+target-dir              = tmp
+p                       = ${basename;${project}}
+project.name            = ${p}
+bin.includes            = ${project.name}.jar
+
+# Java compiler options
+java                    = java
+javac                   = javac
+javac.debug             = on
+javac.source            = 1.3
+javac.target            = 1.2
+
+#Bnd options
+-sources                = true
+-sourcepath             = ${project}/src 
+-plugin                 = aQute.lib.deployer.FileRepo;location=${repo}, aQute.bnd.maven.MavenRepository, aQute.bnd.maven.MavenGroup; groupId=org.apache.felix
+junit                   = junit.junit;version=3.8;export="junit.framework;version=3.8,junit.extensions;version=3.8"
+
+# Time options
+# base.modified is used by bnd to not make when files are not changed
+base.modified           = ${fmodified;${build}/build.xml,${build}/build.bnd,${project}/build.properties,${project}/bnd.bnd,${project}/build.xml}
+base.modified.readable  = ${long2date;${base.modified}}
+project.build           = ${tstamp;yyyyMMddhhmm}
+
+-make : (*).jar; type=bnd; recipe=recipes/$1.bnd
+
+copyright = ...
+copyright.html = ...
+
+# Documentation
+Bundle-Vendor    = The Apache Software Foundation          
+Bundle-DocURL    = http://www.apache.org/                  
+Bundle-License   = http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Copyright = ${copyright}
+Bundle-Vendor    = Apache Felix
+-removeheader    = Include-Resource
+
+
+-runpath		= \
+	org.apache.felix.framework; version=1.5.0; framework=org.apache.felix.framework.Felix, \
+	junit.junit; version=3.8; export="junit.framework;version=3.8"
+

Added: felix/sandbox/rickhall/bnd-test/cnf/build.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/cnf/build.xml?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/cnf/build.xml (added)
+++ felix/sandbox/rickhall/bnd-test/cnf/build.xml Thu Feb 12 19:36:18 2009
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="master" default="none">
+
+	<target name="all" depends="publish">
+		<!-- all target is a synonym for publish target -->
+	</target>
+	<target name="publish" depends="init,dependencies,compile,jars,release,deploy">
+		<echo>Exit project ${project.name}</echo>
+	</target>
+
+	<target name="deploy" depends="init,dependencies,compile,jars,release" unless="nodeploy">
+		<bnddeploy>
+			<fileset dir="${target}" includes="${bin.includes}" />
+		</bnddeploy>
+	</target>
+
+	<!-- 
+	     INIT
+	     The target is a dependent of all other targets.
+	     It's purpose is to set up the environment only once
+	     and avoid it being repeatedly done for each antcall.
+	-->
+
+	<target name="init" unless="initialized">
+		<dirname property="projectdir" file="${ant.file}" />
+		<dirname property="workspacedir" file="${projectdir}" />
+		<taskdef resource="aQute/bnd/ant/taskdef.properties" classpath="${workspacedir}/cnf/repo/biz.aQute.bnd/biz.aQute.bnd-latest.jar" />
+
+		<available file="bnd.bnd" property="use.bnd" />
+
+		<bndprepare basedir="${projectdir}" print="false" />
+
+		<!-- Now we have the same properties set as bnd 
+		-->
+
+		<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="${workspace}/lib/ant-contrib-0.6.jar" />
+
+		<!-- mark init has been run -->
+		<property name="initialized" value="set" />
+		<echo>Enter project ${project.name}</echo>
+	</target>
+
+	<!-- 
+		DEPENDENCIES
+		Build project dependencies.
+	-->
+	<target name="dependencies" depends="init" if="project.dependson" unless="donotrecurse">
+		<subant target="publish" inheritAll="false" buildpath="${project.dependson}">
+			<property name="release.dir" value="${target}" />
+			<property name="donotrecurse" value="true" />
+		</subant>
+	</target>
+
+	<!--
+	     Test
+	-->
+	<target name="test" depends="compile">
+		<bnd command="test" exceptions="true" basedir="${project}"/>
+	</target>
+
+	<!--
+	     COMPILE
+	     Compile the sources. 
+	-->
+	<target name="compile" depends="init" if="project.sourcepath">
+		<echo>${project.sourcepath} ${project.output}</echo>
+		<mkdir dir="${project.output}"/>
+		<javac fork="no" 
+			executable="${javac}" 
+			srcdir="${project.sourcepath}" 
+			destdir="${project.output}" 
+			classpath="${project.buildpath}" 
+			bootclasspath="${project.bootclasspath}" 
+			deprecation="true" 
+			listfiles="true" 
+			target="${javac.target}" 
+			source="${javac.source}" 
+			debug="${javac.debug}" 
+			includeAntRuntime="no" 
+			verbose="${verbose}" />
+	</target>
+
+	<!-- 
+		JARS
+		Iterate of the jars to build.
+	-->
+	<target name="jars" depends="-mktarget,jars-bnd,copy-from">
+	</target>
+
+	<target name="-mktarget" if="target">
+		<mkdir dir="${target}" />
+	</target>
+
+	<target name="copy-from" if="copy.from">
+		<copy overwrite="true" file="${copy.from}" tofile="${target}/${p}.jar" preservelastmodified="true" />
+	</target>
+
+	<!-- Use the next generation bnd tool -->
+	<target name="jars-bnd" depends="init" if="use.bnd">
+		<echo>JARs ${use.bnd}</echo>
+		<antcall target="-interleave">
+			<param name="x" value="before.${item.jarFile}" />
+		</antcall>
+		<bndproject basedir="${project}"/>
+	</target>
+
+	<target name="-jar" depends="-signjar" />
+
+	<target name="-signjar" if="sign.${item.jarFile}">
+		<signjar jar="${target}/${item.jarFile}" signedjar="${target}/${item.jarFile}.signed" keystore="${workspace}/cnf/certificate/.keystore" storepass="testtest" keypass="testtest" alias="test" />
+	</target>
+
+
+	<!--
+	  If you specify before.<jarfile>.jar=target, then we will
+	  call this target before the creation of the jar file.
+	-->
+	<target name="-interleave" if="${x}">
+		<indirect inputName="${x}" outputName="before" />
+		<antcall target="${before}" />
+	</target>
+
+	<!--
+	    RELEASE
+	    Copy the JAR file to the osgi.released directory.
+	-->
+	<target name="release" depends="init" if="release.dir">
+		<copy todir="${release.dir}" verbose="${verbose}" preservelastmodified="true">
+			<fileset dir="${target}" includes="${bin.includes}" />
+		</copy>
+	</target>
+
+	<!--
+	     CLEAN
+	-->
+	<target name="deepclean" depends="init,clean" if="project.dependson">
+		<subant target="clean" inheritAll="false" buildpath="${project.dependson}"/>
+	</target>
+
+	<target name="clean" depends="init">
+		<delete quiet="true" includeEmptyDirs="true" verbose="${verbose}">
+			<fileset dir="${project.output}" includes="**/*.class" />
+			<fileset dir="${target}" />
+		</delete>
+	</target>
+
+	<!--
+	     ECHO
+	-->
+	<target name="echo" depends="init">
+		<echo>verbose:                ${verbose}</echo>
+		<echo>project.name:           ${project.name}</echo>
+		<echo>project.output:         ${project.output}</echo>
+		<echo>project.sourcepath:     ${project.sourcepath}</echo>
+		<echo>project.allsourcepath:  ${project.allsourcepath}</echo>
+		<echo>project.buildpath:      ${project.buildpath}</echo>
+		<echo>project.testpath:       ${project.testpath}</echo>
+		<echo>project.dependson:      ${project.dependson}</echo>
+		<echo>project.bootclasspath:  ${project.bootclasspath}</echo>
+		<echo>javac:                  ${javac}</echo>
+		<echo>p:                      ${p}</echo>
+		<echo>jars.compile.order:     ${jars.compile.order}</echo>
+		<echo>bin.includes:           ${bin.includes}</echo>
+		<echo>base.modfied:           ${base.modified} (${base.modified.readable})</echo>
+		<echo>target:                 ${target}</echo>
+		<echo>licensed repo:          ${licensed-repo}</echo>
+		<echo>repo:                   ${repo}</echo>
+		<echo>use.bnd:                ${use.bnd}</echo>
+		<echo>nodeploy:               ${nodeploy}</echo>
+		<echo>-dependson:             ${-dependson}</echo>
+
+	</target>
+
+	<!--
+	     Default Target
+	-->
+	<target name="none">
+		<fail message="This ant script should never be directly called." />
+	</target>
+
+	<!--
+		Check out the projects that are part of the build.
+	-->
+	<target name="co" depends="init">
+		<cvs cvsRoot=":pserver:www2.osgi.org:/cvshome/build" dest="${workspace}" package="${specs},${impls},${tests}" />
+	</target>
+</project>

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/bnd.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/bnd.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/bnd.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/bnd.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,12 @@
+Private-Package: ${p}
+Include-Resource: cyclea.jar,cycleb.jar,host.jar,fragment.jar,requirehost.jar,org/apache/felix/framework/test/Message.properties=src/resource/Message.properties,org/apache/felix/framework/test/Message_fr.properties=src/resource/Message_fr.properties
+
+-buildpath: \
+	org.osgi.core; version=1.2.0, \
+	org.osgi.foundation; version=1.2.0, \
+	junit.junit
+
+	
+-runproperties = report=true
+
+Test-Cases = ${classes;extending;*FelixTestCase}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/build.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/build.xml?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/build.xml (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/build.xml Thu Feb 12 19:36:18 2009
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="publish"> 
+	<import file="../cnf/build.xml"/>
+</project>

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cyclea.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cyclea.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cyclea.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cyclea.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,4 @@
+Bundle-SymbolicName: org.apache.felix.framework.test.cycle.cyclea
+Export-Package: org.apache.felix.framework.test.cycle;-noimport:=true, org.apache.felix.framework.test.cycle.cyclea
+Require-Bundle: org.apache.felix.framework.test.cycle.cycleb
+

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cycleb.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cycleb.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cycleb.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/cycleb.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,4 @@
+Bundle-SymbolicName: org.apache.felix.framework.test.cycle.cycleb
+Export-Package: org.apache.felix.framework.test.cycle;-noimport:=true, org.apache.felix.framework.test.cycle.cycleb
+Require-Bundle: org.apache.felix.framework.test.cycle.cyclea
+

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/fragment.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/fragment.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/fragment.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/fragment.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,4 @@
+Bundle-SymbolicName: org.apache.felix.framework.test.fragment
+-resourceonly : true
+Fragment-Host: org.apache.felix.framework.test.host
+Include-Resource: org/apache/felix/framework/test/host/Message_fr.properties=src/resource/Message_fr.properties

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/host.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/host.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/host.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/host.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,4 @@
+Bundle-SymbolicName: org.apache.felix.framework.test.host
+Bundle-Activator: org.apache.felix.framework.test.host.Host
+Private-Package: org.apache.felix.framework.test.host
+Include-Resource: org/apache/felix/framework/test/host/Message.properties=src/resource/Message.properties

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/requirehost.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/requirehost.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/requirehost.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/recipes/requirehost.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,3 @@
+Bundle-SymbolicName: org.apache.felix.framework.test.requirehost
+-failok : true
+Require-Bundle: org.apache.felix.framework.test.host

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/FelixTestCase.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/FelixTestCase.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/FelixTestCase.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/FelixTestCase.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.framework.test;
+
+import junit.framework.TestCase;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public abstract class FelixTestCase extends TestCase
+{
+    private volatile BundleContext m_context;
+    private volatile PackageAdmin m_pa = null;
+    private volatile boolean m_isRefreshed = false;
+
+    public BundleContext getBundleContext()
+    {
+        return m_context;
+    }
+
+    public void setBundleContext(BundleContext context)
+    {
+        m_context = context;
+        m_context.addFrameworkListener(new FrameworkListener() {
+            public void frameworkEvent(FrameworkEvent event)
+            {
+                if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED)
+                {
+                    m_isRefreshed = true;
+                }
+            }
+        });
+    }
+
+    public PackageAdmin getPackageAdmin()
+    {
+        if (m_pa == null)
+        {
+            m_pa = (PackageAdmin) m_context.getService(
+                m_context.getServiceReference(PackageAdmin.class.getName()));
+        }
+        return m_pa;
+    }
+
+    public void refreshAndWait()
+    {
+        m_isRefreshed = false;
+        getPackageAdmin().refreshPackages(null);
+        while (!m_isRefreshed)
+        {
+            try
+            {
+                Thread.sleep(100);
+            }
+            catch (InterruptedException ex)
+            {
+                // Ignore.
+            }
+        }
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestCycle.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestCycle.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestCycle.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestCycle.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.framework.test;
+
+import java.io.InputStream;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class TestCycle extends FelixTestCase
+{
+    public void testCycle() throws Exception
+    {
+        PackageAdmin pa = getPackageAdmin();
+
+        Bundle bundleA = null, bundleB = null;
+
+        try
+        {
+            // Install bundles with a cyclical relationship.
+            InputStream is = this.getClass().getClassLoader().getResourceAsStream("cyclea.jar");
+            bundleA = getBundleContext().installBundle("cyclea.jar", is);
+            is = this.getClass().getClassLoader().getResourceAsStream("cycleb.jar");
+            bundleB = getBundleContext().installBundle("cycleb.jar", is);
+
+            // This class load causes delegation cycles, but should load fine.
+            Class clazz = bundleA.loadClass("org.apache.felix.framework.test.cycle.cyclea.CycleA");
+            clazz.newInstance();
+
+            // Since there is a circular require-bundle dependency, bundleA's class load
+            // should come from bundleB.
+            clazz = bundleA.loadClass("org.apache.felix.framework.test.cycle.CycleSplitB");
+            if (!bundleB.equals(pa.getBundle(clazz)))
+            {
+                throw new Exception("Loaded from incorrect bundle.");
+            }
+            // Since there is a circular require-bundle dependency, bundleB's class load
+            // should come from bundleA.
+            clazz = bundleB.loadClass("org.apache.felix.framework.test.cycle.CycleSplitA");
+            if (!bundleA.equals(pa.getBundle(clazz)))
+            {
+                throw new Exception("Loaded from incorrect bundle.");
+            }
+            // Since the last class load by bundleB caused bundleA to define the
+            // CycleSplitA class, subsequent requests by bundleA for the same class
+            // should also come from bundleA.
+            clazz = bundleA.loadClass("org.apache.felix.framework.test.cycle.CycleSplitA");
+            if (!bundleA.equals(pa.getBundle(clazz)))
+            {
+                throw new Exception("Loaded from incorrect bundle.");
+            }
+        }
+        finally
+        {
+            // Clean up.
+            if (bundleA != null) bundleA.uninstall();
+            bundleA = null;
+            if (bundleB != null) bundleB.uninstall();
+            bundleB = null;
+            refreshAndWait();
+        }
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFilter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFilter.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFilter.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFilter.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,59 @@
+/*
+ * 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.framework.test;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+public class TestFilter extends FelixTestCase
+{
+    public void testFilter() throws Exception
+    {
+        getBundleContext().registerService(String.class.getName(), "a=1", props(new Object[]
+            {
+                "test", Boolean.TRUE, "a", new Integer(1), "b", "4"
+            }));
+        getBundleContext().registerService(String.class.getName(), "a=2", props(new Object[]
+            {
+                "test", Boolean.TRUE, "a", new Integer(2), "b", "3"
+            }));
+        getBundleContext().registerService(String.class.getName(), "a=3", props(new Object[]
+            {
+                "test", Boolean.TRUE, "a", new Integer(3), "b", "2"
+            }));
+        getBundleContext().registerService(String.class.getName(), "a=4", props(new Object[]
+            {
+                "test", Boolean.TRUE, "a", new Integer(4), "b", "1"
+            }));
+
+        assertEquals(1, getBundleContext().getServiceReferences(null, "(&(a=1)(b=4))").length);
+        assertEquals(2, getBundleContext().getServiceReferences(null, "(&(a<=2)(b>=3))").length);
+        assertEquals(4, getBundleContext().getServiceReferences(null, "(&(a=*)(b=*))").length);
+    }
+
+    Dictionary props(Object[] args)
+    {
+        Properties p = new Properties();
+        for (int i = 0; i < args.length; i += 2)
+        {
+            p.put(args[i], args[i + 1]);
+        }
+        return p;
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFragment.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFragment.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFragment.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/TestFragment.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,206 @@
+/*
+ * 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.framework.test;
+
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import org.osgi.framework.Bundle;
+
+public class TestFragment extends FelixTestCase
+{
+    private Bundle m_host = null;
+    private Bundle m_fragment = null;
+    private Bundle m_requirer = null;
+    private ResourceBundle m_hostRB = null;
+
+    public void testFragment() throws Exception
+    {
+        InputStream is = null;
+        ResourceBundle enRB, frRB;
+
+        // Get local copies of english and french resource bundles.
+        enRB = ResourceBundle.getBundle("org.apache.felix.framework.test.Message");
+        frRB = ResourceBundle.getBundle("org.apache.felix.framework.test.Message", Locale.FRENCH);
+
+        // Scenario #1
+        //
+        // Install only the host bundle, which will cause it to register
+        // a resource bundle for english by default.
+        try
+        {
+            is = this.getClass().getClassLoader().getResourceAsStream("host.jar");
+            m_host = getBundleContext().installBundle("host.jar", is);
+            m_host.start();
+            m_hostRB = (ResourceBundle) getBundleContext().getService(
+                getBundleContext().getServiceReference(ResourceBundle.class.getName()));
+            if (!m_hostRB.getString("STARTING_SYSTEM").equals(enRB.getString("STARTING_SYSTEM")))
+            {
+                throw new RuntimeException("Expected '" + enRB.getString("STARTING_SYSTEM")
+                    + "' received '" + m_hostRB.getString("STARTING_SYSTEM") + "'");
+            }
+            if (!m_hostRB.getString("LOADING_SETTINGS").equals(enRB.getString("LOADING_SETTINGS")))
+            {
+                throw new RuntimeException("Expected '" + enRB.getString("LOADING_SETTINGS")
+                    + "' received '" + m_hostRB.getString("LOADING_SETTINGS") + "'");
+            }
+        }
+        finally
+        {
+            cleanup();
+        }
+
+        // Scenario #2
+        //
+        // Install both host and fragment bundles, but resolve the host first;
+        // this should result in french locale because the fragment will be
+        // attached to the host.
+        try
+        {
+            is = this.getClass().getClassLoader().getResourceAsStream("host.jar");
+            m_host = getBundleContext().installBundle("host.jar", is);
+            is = this.getClass().getClassLoader().getResourceAsStream("fragment.jar");
+            m_fragment = getBundleContext().installBundle("fragment.jar", is);
+            m_host.start();
+            m_hostRB = (ResourceBundle) getBundleContext().getService(
+                getBundleContext().getServiceReference(ResourceBundle.class.getName()));
+            if (!m_hostRB.getString("STARTING_SYSTEM").equals(frRB.getString("STARTING_SYSTEM")))
+            {
+                throw new RuntimeException("Expected '" + frRB.getString("STARTING_SYSTEM")
+                    + "' received '" + m_hostRB.getString("STARTING_SYSTEM") + "'");
+            }
+            if (!m_hostRB.getString("LOADING_SETTINGS").equals(frRB.getString("LOADING_SETTINGS")))
+            {
+                throw new RuntimeException("Expected '" + frRB.getString("LOADING_SETTINGS")
+                    + "' received '" + m_hostRB.getString("LOADING_SETTINGS") + "'");
+            }
+        }
+        finally
+        {
+            cleanup();
+        }
+
+        // Scenario #3
+        //
+        // Install both host and fragment bundles, but resolve the fragment first;
+        // this should still result in french locale because the fragment will
+        // still attach to the host.
+        try
+        {
+            is = this.getClass().getClassLoader().getResourceAsStream("host.jar");
+            m_host = getBundleContext().installBundle("host.jar", is);
+            is = this.getClass().getClassLoader().getResourceAsStream("fragment.jar");
+            m_fragment = getBundleContext().installBundle("fragment.jar", is);
+            getPackageAdmin().resolveBundles(new Bundle[] { m_fragment });
+            m_host.start();
+            m_hostRB = (ResourceBundle) getBundleContext().getService(
+                getBundleContext().getServiceReference(ResourceBundle.class.getName()));
+            if (!m_hostRB.getString("STARTING_SYSTEM").equals(frRB.getString("STARTING_SYSTEM")))
+            {
+                throw new RuntimeException("Expected '" + frRB.getString("STARTING_SYSTEM")
+                    + "' received '" + m_hostRB.getString("STARTING_SYSTEM") + "'");
+            }
+            if (!m_hostRB.getString("LOADING_SETTINGS").equals(frRB.getString("LOADING_SETTINGS")))
+            {
+                throw new RuntimeException("Expected '" + frRB.getString("LOADING_SETTINGS")
+                    + "' received '" + m_hostRB.getString("LOADING_SETTINGS") + "'");
+            }
+        }
+        finally
+        {
+            cleanup();
+        }
+
+        // Scenario #4
+        //
+        // Install host, fragment, and host requiring bundles. Resolve the host
+        // requiring bundle, which ultimately will result in the French locale
+        // because the fragment should still be attached to the host even though
+        // the host was indirectly resolved.
+        try
+        {
+            is = this.getClass().getClassLoader().getResourceAsStream("host.jar");
+            m_host = getBundleContext().installBundle("host.jar", is);
+            is = this.getClass().getClassLoader().getResourceAsStream("fragment.jar");
+            m_fragment = getBundleContext().installBundle("fragment.jar", is);
+            is = this.getClass().getClassLoader().getResourceAsStream("requirehost.jar");
+            m_requirer = getBundleContext().installBundle("requirehost.jar", is);
+            getPackageAdmin().resolveBundles(new Bundle[] { m_requirer });
+            m_host.start();
+            m_hostRB = (ResourceBundle) getBundleContext().getService(
+                getBundleContext().getServiceReference(ResourceBundle.class.getName()));
+            if (!m_hostRB.getString("STARTING_SYSTEM").equals(frRB.getString("STARTING_SYSTEM")))
+            {
+                throw new RuntimeException("Expected '" + frRB.getString("STARTING_SYSTEM")
+                    + "' received '" + m_hostRB.getString("STARTING_SYSTEM") + "'");
+            }
+            if (!m_hostRB.getString("LOADING_SETTINGS").equals(frRB.getString("LOADING_SETTINGS")))
+            {
+                throw new RuntimeException("Expected '" + frRB.getString("LOADING_SETTINGS")
+                    + "' received '" + m_hostRB.getString("LOADING_SETTINGS") + "'");
+            }
+        }
+        finally
+        {
+            cleanup();
+        }
+    }
+
+    private void cleanup()
+    {
+        if (m_host != null)
+        {
+            try
+            {
+                m_host.uninstall();
+            }
+            catch (Exception ex)
+            {
+                // Ummm?
+            }
+            m_host = null;
+            m_hostRB = null;
+        }
+        if (m_fragment != null)
+        {
+            try
+            {
+                m_fragment.uninstall();
+            }
+            catch (Exception ex)
+            {
+                // Ummm?
+            }
+            m_fragment = null;
+        }
+        if (m_requirer != null)
+        {
+            try
+            {
+                m_requirer.uninstall();
+            }
+            catch (Exception ex)
+            {
+                // Ummm?
+            }
+            m_requirer = null;
+        }
+        refreshAndWait();
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitA.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitA.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitA.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitA.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,24 @@
+/*
+ * 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.framework.test.cycle;
+
+public class CycleSplitA
+{
+
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitB.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitB.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitB.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/CycleSplitB.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,24 @@
+/*
+ * 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.framework.test.cycle;
+
+public class CycleSplitB
+{
+
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleA.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleA.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleA.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleA.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.framework.test.cycle.cyclea;
+
+import org.apache.felix.framework.test.cycle.cycleb.CycleB;
+
+public class CycleA extends CycleB
+{
+    public CycleA()
+    {
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAA.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAA.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAA.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAA.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.framework.test.cycle.cyclea;
+
+import org.apache.felix.framework.test.cycle.cycleb.CycleBB;
+
+public class CycleAA extends CycleBB
+{
+    public CycleAA()
+    {
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAAA.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAAA.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAAA.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cyclea/CycleAAA.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,26 @@
+/*
+ * 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.framework.test.cycle.cyclea;
+
+public class CycleAAA
+{
+    public CycleAAA()
+    {
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleB.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleB.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleB.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleB.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.framework.test.cycle.cycleb;
+
+import org.apache.felix.framework.test.cycle.cyclea.CycleAA;
+
+public class CycleB extends CycleAA
+{
+    public CycleB()
+    {
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleBB.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleBB.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleBB.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/cycle/cycleb/CycleBB.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.framework.test.cycle.cycleb;
+
+import org.apache.felix.framework.test.cycle.cyclea.CycleAAA;
+
+public class CycleBB extends CycleAAA
+{
+    public CycleBB()
+    {
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/host/Host.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/host/Host.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/host/Host.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/org/apache/felix/framework/test/host/Host.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,43 @@
+/*
+ * 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.framework.test.host;
+
+import java.util.*;
+import org.osgi.framework.*;
+
+public class Host implements BundleActivator
+{
+    public void start(BundleContext context)
+    {
+        try
+        {
+            ResourceBundle rb;
+            rb = ResourceBundle.getBundle("org.apache.felix.framework.test.host.Message", Locale.FRENCH);
+            context.registerService(ResourceBundle.class.getName(), rb, null);
+        }
+        catch (Exception ex)
+        {
+            System.out.println(ex);
+        }
+    }
+
+    public void stop(BundleContext context)
+    {
+    }
+}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message.properties
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message.properties?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message.properties (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message.properties Thu Feb 12 19:36:18 2009
@@ -0,0 +1,3 @@
+STARTING_SYSTEM=Starting the system...
+LOADING_SETTINGS=Loading user's settings...
+

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message_fr.properties
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message_fr.properties?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message_fr.properties (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.framework.test/src/resource/Message_fr.properties Thu Feb 12 19:36:18 2009
@@ -0,0 +1,3 @@
+STARTING_SYSTEM=Commencer le système...
+LOADING_SETTINGS=Les arrangements de l'utilisateur de chargement...
+

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/bnd.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/bnd.bnd?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/bnd.bnd (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/bnd.bnd Thu Feb 12 19:36:18 2009
@@ -0,0 +1,14 @@
+Private-Package: ${p},test
+Export-Package: org.osgi.service.log
+Bundle-Activator: org.apache.felix.log.Activator
+
+-buildpath: \
+	org.osgi.core; version=1.2.0, \
+	org.osgi.compendium; version=1.2.0, \
+	org.osgi.foundation; version=1.2.0, \
+	junit.junit
+
+	
+-runproperties = report=true
+
+Test-Cases = ${classes;extending;*TestCase}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/build.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/build.xml?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/build.xml (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/build.xml Thu Feb 12 19:36:18 2009
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="publish"> 
+	<import file="../cnf/build.xml"/>
+</project>

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Activator.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Activator.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Activator.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,132 @@
+/* 
+ * 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.log;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogReaderService;
+import org.osgi.service.log.LogService;
+
+/**
+ * The bundle activator for the OSGi log service (see section 101 of the service
+ * compendium).
+ * <p>
+ * The log service provides a general purpose message logger for the OSGi service
+ * platform.  It consists of two services, one for logging information and another
+ * for retrieving current or previously recorded log information.
+ * <p>
+ * The service knows about the following properties which are read at bundle
+ * startup:
+ * <dl>
+ *   <dt>org.apache.felix.log.maxSize</dt>
+ *   <dd>Determines the maximum size of the log used to maintain historic
+ *       log information.  A value of -1 means the log has no maximum size;
+ *       a value of 0 means that no historic log information will be maintained.
+ *       The default value is 100.</dd>
+ *
+ *   <dt>org.apache.felix.log.storeDebug</dt>
+ *   <dd>Determines whether or not debug messages will be stored as part of
+ *       the historic log information. The default value is false.</dd>
+ * </dl>
+ */
+public final class Activator implements BundleActivator {
+    /** The name of the property that defines the maximum size of the log. */
+    private static final String MAX_SIZE_PROPERTY = "org.apache.felix.log.maxSize";
+
+    /** The default value for the maximum size property. */
+    private static final int DEFAULT_MAX_SIZE = 100;
+
+    /** The name of the property that defines whether debug messages are stored. */
+    private static final String STORE_DEBUG_PROPERTY = "org.apache.felix.log.storeDebug";
+
+    /** The default value for the store debug property. */
+    private static final boolean DEFAULT_STORE_DEBUG = false;
+
+    /** The log. */
+    private Log m_log;
+
+    /**
+     * Returns the maximum size for the log.
+     * @param context the bundle context (used to look up a property)
+     * @return the maximum size for the log
+     */
+    private static int getMaxSize(final BundleContext context) {
+        int maxSize = DEFAULT_MAX_SIZE;
+
+        String maxSizePropValue = context.getProperty(MAX_SIZE_PROPERTY);
+        if (maxSizePropValue != null) {
+            try {
+                maxSize = Integer.parseInt(maxSizePropValue);
+            } catch (NumberFormatException e) {
+                // the property value is invalid - ignore
+            }
+        }
+
+        return maxSize;
+    }
+
+    /**
+     * Returns whether or not to store debug messages.
+     * @param context the bundle context (used to look up a property)
+     * @return whether or not to store debug messages
+     */
+    private static boolean getStoreDebug(final BundleContext context) {
+        boolean storeDebug = DEFAULT_STORE_DEBUG;
+
+        String storeDebugPropValue = context.getProperty(STORE_DEBUG_PROPERTY);
+        if (storeDebugPropValue != null) {
+            storeDebug = Boolean.valueOf(storeDebugPropValue).booleanValue();
+        }
+
+        return storeDebug;
+    }
+
+    /**
+     * Called by the OSGi framework when the bundle is started.
+     * Used to register the service implementations with the framework.
+     * @param context the bundle context
+     * @throws Exception if an error occurs
+     */
+    public void start(final BundleContext context) throws Exception {
+        // create the log instance
+        m_log = new Log(getMaxSize(context), getStoreDebug(context));
+
+        // register the listeners
+        context.addBundleListener(m_log);
+        context.addFrameworkListener(m_log);
+        context.addServiceListener(m_log);
+
+        // register the services with the framework
+        context.registerService(LogService.class.getName(),
+                new LogServiceFactory(m_log), null);
+
+        context.registerService(LogReaderService.class.getName(),
+                new LogReaderServiceFactory(m_log), null);
+    }
+
+    /**
+     * Called by the OSGi framework when the bundle is stopped.
+     * @param context the bundle context
+     * @throws Exception if an error occurs
+     */
+    public void stop(final BundleContext context) throws Exception {
+        // close the log
+        m_log.close();
+    }
+}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Log.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Log.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Log.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/Log.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,265 @@
+/* 
+ * 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.log;
+
+import java.util.Enumeration;
+
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogListener;
+import org.osgi.service.log.LogService;
+
+/**
+ * Class used to represent the log.  This class is used by the implementations
+ * of both the {@link org.osgi.service.log.LogService} interface and the
+ * {@link org.osgi.service.log.LogReaderService} to access the log.
+ * @see org.osgi.service.log.LogService
+ * @see org.osgi.service.log.LogReaderService
+ */
+final class Log implements BundleListener, FrameworkListener, ServiceListener {
+    /** The first log entry. */
+    private LogNode m_head;
+
+    /** The last log entry. */
+    private LogNode m_tail;
+
+    /** The log size. */
+    private int m_size;
+
+    /** The log listener thread. */
+    private LogListenerThread listenerThread;
+
+    /** The maximum size for the log. */
+    private final int m_maxSize;
+
+    /** Whether or not to store debug messages. */
+    private final boolean m_storeDebug;
+
+    /**
+     * Create a new instance.
+     * @param maxSize the maximum size for the log
+     * @param storeDebug whether or not to store debug messages
+     */
+    Log(final int maxSize, final boolean storeDebug) {
+        this.m_maxSize = maxSize;
+        this.m_storeDebug = storeDebug;
+    }
+
+    /**
+     * Close the log.
+     */
+    void close() {
+        if (listenerThread != null) {
+            listenerThread.shutdown();
+            listenerThread = null;
+        }
+
+        m_head = null;
+        m_tail = null;
+        m_size = 0;
+    }
+
+    /**
+     * Adds the entry to the log.
+     * @param entry the entry to add to the log
+     */
+    synchronized void addEntry(final LogEntry entry) {
+        if (m_maxSize != 0) {
+            // add the entry to the historic log
+            if (m_storeDebug || entry.getLevel() != LogService.LOG_DEBUG) {
+                // create a new node for the entry
+                LogNode node = new LogNode(entry);
+
+                // add to the front of the linked list
+                node.setNextNode(m_head);
+                if (m_head != null) {
+                    m_head.setPreviousNode(node);
+                }
+
+                // and store the node
+                m_head = node;
+
+                // bump the size of the list
+                ++m_size;
+
+                // if no tail node - add the node to the tail
+                if (m_tail == null) {
+                    m_tail = node;
+                }
+            }
+
+            // ensure the historic log doesn't grow beyond a certain size
+            if (m_maxSize != -1) {
+                if (m_size > m_maxSize) {
+                    LogNode last = m_tail.getPreviousNode();
+                    last.setNextNode(null);
+                    m_tail = last;
+                    --m_size;
+                }
+            }
+        }
+
+        // notify any listeners
+        if (listenerThread != null) {
+            listenerThread.addEntry(entry);
+        }
+    }
+
+    /**
+     * Add a listener to the log.
+     * @param listener the log listener to subscribe
+     */
+    synchronized void addListener(final LogListener listener) {
+        if (listenerThread == null) {
+            // create a new listener thread if necessary:
+            // the listener thread only runs if there are any registered listeners
+            listenerThread = new LogListenerThread();
+            listenerThread.start();
+        }
+        listenerThread.addListener(listener);
+    }
+
+    /**
+     * Remove a listener from the log.
+     * @param listener the log listener to unsubscribe
+     */
+    synchronized void removeListener(final LogListener listener) {
+        if (listenerThread != null) {
+            listenerThread.removeListener(listener);
+
+            // shutdown the thread if there are no listeners
+            if (listenerThread.getListenerCount() == 0) {
+                listenerThread.shutdown();
+                listenerThread = null;
+            }
+        }
+    }
+
+    /**
+     * Returns an enumeration of all the entries in the log most recent first.
+     * @return an enumeration of all the entries in the log most recent first
+     */
+    synchronized Enumeration getEntries() {
+        return new LogNodeEnumeration(m_head, m_tail);
+    }
+
+    /** The messages returned for the framework events. */
+    private static final String[] FRAMEWORK_EVENT_MESSAGES = {
+        "FrameworkEvent STARTED",
+        "FrameworkEvent ERROR",
+        "FrameworkEvent PACKAGES REFRESHED",
+        "FrameworkEvent STARTLEVEL CHANGED",
+        "FrameworkEvent WARNING",
+        "FrameworkEvent INFO"
+    };
+
+    /**
+     * Called when a framework event occurs.
+     * @param event the event that occured
+     */
+    public void frameworkEvent(final FrameworkEvent event) {
+        int eventType = event.getType();
+        String message = null;
+
+        for (int i = 0; message == null && i < FRAMEWORK_EVENT_MESSAGES.length; ++i) {
+            if (eventType >> i == 1) {
+                message = FRAMEWORK_EVENT_MESSAGES[i];
+            }
+        }
+
+        LogEntry entry = new LogEntryImpl(event.getBundle(),
+                null,
+                (eventType == FrameworkEvent.ERROR) ? LogService.LOG_ERROR : LogService.LOG_INFO,
+                message,
+                event.getThrowable());
+
+        addEntry(entry);
+    }
+
+    /** The messages returned for the bundle events. */
+    private static final String[] BUNDLE_EVENT_MESSAGES = {
+        "BundleEvent INSTALLED",
+        "BundleEvent STARTED",
+        "BundleEvent STOPPED",
+        "BundleEvent UPDATED",
+        "BundleEvent UNINSTALLED",
+        "BundleEvent RESOLVED",
+        "BundleEvent UNRESOLVED"
+    };
+
+    /**
+     * Called when a bundle event occurs.
+     * @param event the event that occured
+     */
+    public void bundleChanged(final BundleEvent event) {
+        int eventType = event.getType();
+        String message = null;
+
+        for (int i = 0; message == null && i < BUNDLE_EVENT_MESSAGES.length; ++i) {
+            if (eventType >> i == 1) {
+                message = BUNDLE_EVENT_MESSAGES[i];
+            }
+        }
+
+        if (message != null) {
+            LogEntry entry = new LogEntryImpl(event.getBundle(),
+                    null,
+                    LogService.LOG_INFO,
+                    message,
+                    null);
+
+            addEntry(entry);
+        }
+    }
+
+    /** The messages returned for the service events. */
+    private static final String[] SERVICE_EVENT_MESSAGES = {
+        "ServiceEvent REGISTERED",
+        "ServiceEvent MODIFIED",
+        "ServiceEvent UNREGISTERING"
+    };
+
+    /**
+     * Called when a service event occurs.
+     * @param event the event that occured
+     */
+    public void serviceChanged(final ServiceEvent event) {
+        int eventType = event.getType();
+        String message = null;
+
+        for (int i = 0; message == null && i < SERVICE_EVENT_MESSAGES.length; ++i) {
+            if (eventType >> i == 1) {
+                message = SERVICE_EVENT_MESSAGES[i];
+            }
+        }
+
+        LogEntry entry = new LogEntryImpl(event.getServiceReference().getBundle(),
+                event.getServiceReference(),
+                (eventType == ServiceEvent.MODIFIED) ? LogService.LOG_DEBUG : LogService.LOG_INFO,
+                message,
+                null);
+
+        addEntry(entry);
+    }
+}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogEntryImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogEntryImpl.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogEntryImpl.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogEntryImpl.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,148 @@
+/* 
+ * 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.log;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogEntry;
+
+/**
+ * Implementation of the OSGi {@link LogEntry} interface.  See section 101
+ * of the OSGi service compendium.
+ * <p>
+ * Provides methods to access the information contained in an individual Log
+ * Service log entry.
+ * <p>
+ * A LogEntry object may be acquired from the
+ * {@link org.osgi.service.log.LogReaderService#getLog()} method or by
+ * registering a {@link org.osgi.service.log.LogListener} object.
+ * @see org.osgi.service.log.LogReaderService#getLog()
+ * @see org.osgi.service.log.LogListener
+ */
+final class LogEntryImpl implements LogEntry {
+
+    /** The bundle that created the LogEntry object. */
+    private final Bundle m_bundle;
+
+    /** The exception associated with this LogEntry object. */
+    private final Throwable m_exception;
+
+    /** The severity level of this LogEntry object. */
+    private final int m_level;
+
+    /** The message associated with this LogEntry object. */
+    private final String m_message;
+
+    /** The service reference associated with this LogEntry object. */
+    private final ServiceReference m_serviceReference;
+
+    /** The system time in milliseconds when this LogEntry object was created. */
+    private final long m_time;
+
+    /**
+     * Create a new instance.
+     * @param bundle the bundle that created the LogEntry object
+     * @param sr the service reference to associate with this LogEntry object
+     * @param level the severity level for this LogEntry object
+     * @param message the message to associate with this LogEntry object
+     * @param exception the exception to associate with this LogEntry object
+     */
+    LogEntryImpl(final Bundle bundle,
+            final ServiceReference sr,
+            final int level,
+            final String message,
+            final Throwable exception) {
+        this.m_bundle = bundle;
+        this.m_exception = LogException.getException(exception);
+        this.m_level = level;
+        this.m_message = message;
+        this.m_serviceReference = sr;
+        this.m_time = System.currentTimeMillis();
+    }
+
+    /**
+     * Returns the bundle that created this LogEntry object.
+     * @return the bundle that created this LogEntry object;<code>null</code> if no
+     * bundle is associated with this LogEntry object
+     */
+    public Bundle getBundle() {
+        return m_bundle;
+    }
+
+    /**
+     * Returns the {@link ServiceReference} object for the service associated with
+     * this LogEntry object.
+     * @return the {@link ServiceReference} object for the service associated with
+     * this LogEntry object; <code>null</code> if no {@link ServiceReference} object
+     * was provided
+     */
+    public ServiceReference getServiceReference() {
+        return m_serviceReference;
+    }
+
+    /**
+     * Returns the severity level of this LogEntry object.
+     * <p>
+     * This is one of the severity levels defined by the
+     * {@link org.osgi.service.logLogService} interface.
+     * @return severity level of this LogEntry object.
+     * @see org.osgi.service.LogService#LOG_ERROR
+     * @see org.osgi.service.LogService#LOG_WARNING
+     * @see org.osgi.service.LogService#LOG_INFO
+     * @see org.osgi.service.LogService#LOG_DEBUG
+     */
+    public int getLevel() {
+        return m_level;
+    }
+
+    /**
+     * Returns the human readable message associated with this LogEntry object.
+     * @return a string containing the message associated with this LogEntry object
+     */
+    public String getMessage() {
+        return m_message;
+    }
+
+    /**
+     * Returns the exception object associated with this LogEntry object.
+     * <p>
+     * The returned exception may not be the original exception.  To avoid
+     * references to a bundle defined exception class, thus preventing an
+     * uninstalled bundle from being garbage collected, this LogService will
+     * return an exception object of an implementation defined
+     * {@link Throwable} sub-class.
+     * This exception will maintain as much information as possible from the
+     * original exception object such as the message and stack trace.
+     * @return throwable object of the exception associated with this LogEntry;
+     * <code>null</code> if no exception is associated with this LogEntry object
+     */
+    public Throwable getException() {
+        return m_exception;
+    }
+
+    /**
+     * Returns the value of {@link System#currentTimeMillis()} at the time this
+     * LogEntry object was created.
+     * @return the system time in milliseconds when this LogEntry object was created
+     * @see System#currentTimeMillis()
+     */
+    public long getTime() {
+        return m_time;
+    }
+}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogException.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogException.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogException.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogException.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,99 @@
+/* 
+ * 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.log;
+
+/**
+ * Implementation dependent exception class used to avoid references to any
+ * bundle defined exception class, which might prevent an uninstalled bundle
+ * from being garbage collected.  This exception maintains the class of the
+ * original exception (as part of the message), the message (appended to the
+ * class name) and the stack trace of both the exception thrown and any
+ * embedded exceptions.
+ */
+final class LogException extends Exception {
+    /** The class name of the original exception. */
+    private final String m_className;
+
+    /** The message from the original exception. */
+    private final String m_message;
+
+    /** The localized message from the original exception. */
+    private final String m_localizedMessage;
+
+    /**
+     * Create a new instance.
+     * @param exception the original exception.
+     */
+    private LogException(final Throwable exception) {
+        m_className = exception.getClass().getName();
+        m_message = exception.getMessage();
+        m_localizedMessage = exception.getLocalizedMessage();
+        setStackTrace(exception.getStackTrace());
+
+        Throwable cause = exception.getCause();
+        if (cause != null) {
+            cause = getException(cause);
+            initCause(cause);
+        }
+    }
+
+    /**
+     * Returns the message associated with the exception.  The message
+     * will be the class name of the original exception followed by the
+     * message of the original exception.
+     * @return the message associated with the exception
+     */
+    public String getMessage() {
+        return m_className + ": " + m_message;
+    }
+
+    /**
+     * Returns the localized message associated with the exception.  The
+     * localized message will be the class name of the original exception
+     * followed by the localized message of the original exception.
+     * @return the localized message associated with the exception
+     */
+    public String getLocalizedMessage() {
+        return m_className + ": " + m_localizedMessage;
+    }
+
+    /** The prefix that identifies classes from the "java" namespace. */
+    private static final String JAVA_PACKAGE_PREFIX = "java.";
+
+    /**
+     * Returns the exception to store in the {@link LogEntry}.
+     * @param exception the exception that was originally thrown.
+     * @return the exception to store in the {@link LogEntry}
+     */
+    static Throwable getException(final Throwable exception) {
+        Throwable result = null;
+
+        if (exception != null) {
+            String className = exception.getClass().getName();
+            if (exception.getCause() == null
+                    && className.startsWith(JAVA_PACKAGE_PREFIX)) {
+                result = exception;
+            } else {
+                result = new LogException(exception);
+            }
+        }
+
+        return result;
+    }
+}

Added: felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogListenerThread.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogListenerThread.java?rev=743848&view=auto
==============================================================================
--- felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogListenerThread.java (added)
+++ felix/sandbox/rickhall/bnd-test/org.apache.felix.log/src/org/apache/felix/log/LogListenerThread.java Thu Feb 12 19:36:18 2009
@@ -0,0 +1,135 @@
+/* 
+ * 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.log;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogListener;
+
+/**
+ * This class is responsible for asynchronously delivering log messages to
+ * any {@link LogListener} subscribers.  A subscriber can be added using the
+ * {@link org.osgi.service.log.LogReaderService#addLogListener(LogListener)}
+ * method.
+ */
+final class LogListenerThread extends Thread {
+
+    /** Whether the thread is stopping or not. */
+    private boolean m_stopping = false;
+
+    /** The stack of entries waiting to be delivered to the log listeners. **/
+    private final Stack m_entriesToDeliver = new Stack();
+
+    /** The list of listeners. */
+    private final List m_listeners = new Vector();
+
+    /**
+     * Add an entry to the list of messages to deliver.
+     * @param entry the log entry to deliver
+     */
+    void addEntry(final LogEntry entry) {
+        synchronized (m_entriesToDeliver) {
+            m_entriesToDeliver.add(entry);
+            m_entriesToDeliver.notifyAll();
+        }
+    }
+
+    /**
+     * Add a listener to the list of listeners that are subscribed.
+     * @param listener the listener to add to the list of subscribed listeners
+     */
+    void addListener(final LogListener listener) {
+        synchronized (m_listeners) {
+            m_listeners.add(listener);
+        }
+    }
+
+    /**
+     * Remove a listener from the list of listeners that are subscribed.
+     * @param listener the listener to remove from the list of subscribed listeners
+     */
+    void removeListener(final LogListener listener) {
+        synchronized (m_listeners) {
+            m_listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Returns the number of listeners that are currently registered.
+     * @return the number of listeners that are currently registered
+     */
+    int getListenerCount() {
+        return m_listeners.size();
+    }
+
+    /**
+     * Stop the thread.  This will happen asynchronously.
+     */
+    void shutdown() {
+        m_stopping = true;
+
+        synchronized (m_entriesToDeliver) {
+            m_entriesToDeliver.notifyAll();
+        }
+    }
+
+    /**
+     * The main method of the thread: waits for new messages to be receieved
+     * and then delivers them to any registered log listeners.
+     */
+    public void run() {
+        boolean stop = false;
+
+        for (; !stop;) {
+            synchronized (m_entriesToDeliver) {
+                if (!m_entriesToDeliver.isEmpty()) {
+                    LogEntry entry = (LogEntry) m_entriesToDeliver.pop();
+
+                    synchronized (m_listeners) {
+                        Iterator listenerIt = m_listeners.iterator();
+                        while (listenerIt.hasNext()) {
+                            try {
+                                LogListener listener = (LogListener) listenerIt.next();
+                                listener.logged(entry);
+                            } catch (Throwable t) {
+                                // catch and discard any exceptions thrown by the listener
+                            }
+                        }
+                    }
+                }
+
+                if (m_entriesToDeliver.isEmpty()) {
+                    try {
+                        m_entriesToDeliver.wait();
+                    } catch (InterruptedException e) {
+                        // do nothing
+                    }
+                }
+            }
+
+            if (m_stopping) {
+                stop = true;
+            }
+        }
+    }
+}