diff options
226 files changed, 10426 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa91ebf --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*/src/main/resources/META-INF/MANIFEST.MF +*/src/test/resources/META-INF/TEST.MF +integration-repo +ivy-cache +target +serviceability diff --git a/build-medic/build.xml b/build-medic/build.xml new file mode 100644 index 0000000..678f857 --- /dev/null +++ b/build-medic/build.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="build-medic"> + + <path id="bundles"> + <pathelement location="../org.eclipse.virgo.medic"/> + <pathelement location="../org.eclipse.virgo.medic.weaving"/> + <pathelement location="../org.eclipse.virgo.ch.qos.logback.classic.woven"/> + <pathelement location="../org.eclipse.virgo.medic.core"/> + <pathelement location="../org.eclipse.virgo.medic.test"/> + <pathelement location="../org.eclipse.virgo.medic.testfragment"/> + <pathelement location="../org.eclipse.virgo.medic.integrationtest"/> + </path> + + <property file="${basedir}/../build.properties"/> + <property file="${basedir}/../build.versions"/> + + <import file="${basedir}/../virgo-build/multi-bundle/default.xml"/> + + <target name="precommit" depends="clean, clean-integration, test, findbugs" + description="Performs a CI server-like build, should be run prior to performing a push"/> + +</project> diff --git a/build.properties b/build.properties new file mode 100644 index 0000000..382e802 --- /dev/null +++ b/build.properties @@ -0,0 +1,13 @@ +version=1.0.1
+release.type=integration
+javadoc.exclude.package.names=**/internal/**,**/internal
+ivy.cache=ivy-cache
+ivy.cache.dir=${basedir}/../${ivy.cache}
+integration.repo.dir=${basedir}/../integration-repo
+source.version=1.5
+test.vm.args= -Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError
+findbugs.enforce=true
+clover.enforce=true
+clover.coverage=80%
+
+#debug string to append to test.vm.args= -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y diff --git a/build.versions b/build.versions new file mode 100644 index 0000000..0df543e --- /dev/null +++ b/build.versions @@ -0,0 +1,13 @@ +# Compile +ch.qos.logback=0.9.18 +org.slf4j=1.5.10 +org.eclipse.osgi=3.5.1.R35x_v20091005 +org.apache.felix.configadmin=1.2.4 +org.aspectj=1.6.6.RELEASE + +# Test +org.junit=4.7.0 +org.easymock=2.3.0 +org.eclipse.virgo.test=2.1.0.D-20100420091951 +org.eclipse.virgo.teststubs=1.0.0.D-20100420091314 +org.eclipse.virgo.util=2.1.0.D-20100420091708 diff --git a/org.eclipse.virgo.ch.qos.logback.classic.woven/build.xml b/org.eclipse.virgo.ch.qos.logback.classic.woven/build.xml new file mode 100644 index 0000000..b5d9549 --- /dev/null +++ b/org.eclipse.virgo.ch.qos.logback.classic.woven/build.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.ch.qos.logback.classic.woven"> + + <property name="disable.bundlor" value="true"/> + <property name="clover.enforce" value="false"/> + + <property file="${basedir}/../build.properties" /> + <property file="${basedir}/../build.versions" /> + + <import file="${basedir}/../virgo-build/weaving-external/default.xml" /> +</project> diff --git a/org.eclipse.virgo.ch.qos.logback.classic.woven/ivy.xml b/org.eclipse.virgo.ch.qos.logback.classic.woven/ivy.xml new file mode 100644 index 0000000..bcf6d9d --- /dev/null +++ b/org.eclipse.virgo.ch.qos.logback.classic.woven/ivy.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}" /> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + <conf name="bundleclasspath" description="Dependencies to be packaged within the bundle"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="ch.qos.logback" name="com.springsource.ch.qos.logback.classic" rev="${ch.qos.logback}" conf="external->runtime"/> + <dependency org="org.aspectj" name="com.springsource.org.aspectj.runtime" rev="${org.aspectj}" conf="aspects->runtime"/> + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic.weaving" rev="latest.integration" conf="aspects->compile"/> + <exclude org="org.eclipse.virgo.medic" module="org.eclipse.virgo.medic" conf="aspects"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.ch.qos.logback.classic.woven/src/main/java/.gitignore b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/main/java/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/main/java/.gitignore diff --git a/org.eclipse.virgo.ch.qos.logback.classic.woven/src/main/resources/.gitignore b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/main/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/main/resources/.gitignore diff --git a/org.eclipse.virgo.ch.qos.logback.classic.woven/src/test/java/.gitignore b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/test/java/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/test/java/.gitignore diff --git a/org.eclipse.virgo.ch.qos.logback.classic.woven/src/test/resources/.gitignore b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/test/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.ch.qos.logback.classic.woven/src/test/resources/.gitignore diff --git a/org.eclipse.virgo.medic.core/.classpath b/org.eclipse.virgo.medic.core/.classpath new file mode 100644 index 0000000..0ae8c79 --- /dev/null +++ b/org.eclipse.virgo.medic.core/.classpath @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" path="src/main/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-3.5.1.R35x_v20091005.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-sources-3.5.1.R35x_v20091005.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar" sourcepath="/MEDIC_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.medic"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-1.2.4.jar" sourcepath="/MEDIC_IVY_CACHE/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-sources-1.2.4.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.virgo.teststubs/org.eclipse.virgo.teststubs.osgi/1.0.0.D-20100420091314/org.eclipse.virgo.teststubs.osgi-1.0.0.D-20100420091314.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.virgo.teststubs/org.eclipse.virgo.teststubs.osgi/1.0.0.D-20100420091314/org.eclipse.virgo.teststubs.osgi-sources-1.0.0.D-20100420091314.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.aspectj/com.springsource.org.aspectj.runtime/1.6.6.RELEASE/com.springsource.org.aspectj.runtime-1.6.6.RELEASE.jar" sourcepath="/MEDIC_IVY_CACHE/org.aspectj/com.springsource.org.aspectj.runtime/1.6.6.RELEASE/com.springsource.org.aspectj.runtime-sources-1.6.6.RELEASE.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar" sourcepath="/MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-sources-1.5.10.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.classic/0.9.18/com.springsource.ch.qos.logback.classic-0.9.18.jar" sourcepath="/MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.classic/0.9.18/com.springsource.ch.qos.logback.classic-sources-0.9.18.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.core/0.9.18/com.springsource.ch.qos.logback.core-0.9.18.jar" sourcepath="/MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.core/0.9.18/com.springsource.ch.qos.logback.core-sources-0.9.18.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.1.0.D-20100420091708/org.eclipse.virgo.util.osgi-2.1.0.D-20100420091708.jar"/> + <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.medic.weaving"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/org.eclipse.virgo.medic.core/.project b/org.eclipse.virgo.medic.core/.project new file mode 100644 index 0000000..d69168c --- /dev/null +++ b/org.eclipse.virgo.medic.core/.project @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.virgo.medic.core</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.ajdt.core.ajbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.springframework.ide.eclipse.core.springbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.springsource.server.ide.bundlor.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + <nature>com.springsource.server.ide.facet.core.bundlenature</nature> + <nature>org.springframework.ide.eclipse.core.springnature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.virgo.medic.core/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.medic.core/.settings/com.springsource.server.ide.bundlor.core.prefs new file mode 100644 index 0000000..84b9c6a --- /dev/null +++ b/org.eclipse.virgo.medic.core/.settings/com.springsource.server.ide.bundlor.core.prefs @@ -0,0 +1,5 @@ +#Thu Nov 12 08:44:12 GMT 2009 +com.springsource.server.ide.bundlor.core.bundlor.generated.manifest.autoformatting=true +com.springsource.server.ide.bundlor.core.byte.code.scanning=true +com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions +eclipse.preferences.version=1 diff --git a/org.eclipse.virgo.medic.core/.settings/org.springframework.ide.eclipse.core.prefs b/org.eclipse.virgo.medic.core/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 0000000..00626fc --- /dev/null +++ b/org.eclipse.virgo.medic.core/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,67 @@ +#Wed Aug 19 13:16:35 BST 2009 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true +org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=false +org.springframework.ide.eclipse.core.enable.project.preferences=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/org.eclipse.virgo.medic.core/.springBeans b/org.eclipse.virgo.medic.core/.springBeans new file mode 100644 index 0000000..8ce1035 --- /dev/null +++ b/org.eclipse.virgo.medic.core/.springBeans @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beansProjectDescription> + <version>1</version> + <pluginVersion><![CDATA[2.2.5.200906231226-RC1]]></pluginVersion> + <configSuffixes> + <configSuffix><![CDATA[xml]]></configSuffix> + </configSuffixes> + <enableImports><![CDATA[false]]></enableImports> + <configs> + </configs> + <configSets> + </configSets> +</beansProjectDescription> diff --git a/org.eclipse.virgo.medic.core/build.xml b/org.eclipse.virgo.medic.core/build.xml new file mode 100644 index 0000000..dda91ba --- /dev/null +++ b/org.eclipse.virgo.medic.core/build.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.medic.core"> + + <property file="${basedir}/../build.properties" /> + <property file="${basedir}/../build.versions" /> + + <import file="${basedir}/../virgo-build/aspect/default.xml" /> + +</project> diff --git a/org.eclipse.virgo.medic.core/ivy.xml b/org.eclipse.virgo.medic.core/ivy.xml new file mode 100644 index 0000000..c12b5a3 --- /dev/null +++ b/org.eclipse.virgo.medic.core/ivy.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}" /> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic" rev="latest.integration" conf="compile->compile"/> + + <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="${org.slf4j}" conf="compile->runtime"/> + <dependency org="org.eclipse.virgo.util" name="org.eclipse.virgo.util.osgi" rev="${org.eclipse.virgo.util}" conf="compile->runtime"/> + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.ch.qos.logback.classic.woven" rev="latest.integration" conf="provided, additional->runtime"/> + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic.weaving" rev="latest.integration" conf="provided, additional->runtime"/> + <dependency org="ch.qos.logback" name="com.springsource.ch.qos.logback.core" rev="${ch.qos.logback}" conf="provided, additional->runtime"/> + <dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="provided->runtime"/> + + <dependency org="org.apache.felix" name="org.apache.felix.configadmin" rev="${org.apache.felix.configadmin}" conf="optional->runtime"/> + + <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/> + <dependency org="org.easymock" name="com.springsource.org.easymock" rev="${org.easymock}" conf="test->runtime"/> + <dependency org="org.eclipse.virgo.teststubs" name="org.eclipse.virgo.teststubs.osgi" rev="${org.eclipse.virgo.teststubs}" conf="test->runtime"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorPublisher.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorPublisher.java new file mode 100644 index 0000000..3fbaa26 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorPublisher.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.impl.heap.HeapDumpContributor; +import org.eclipse.virgo.medic.dump.impl.logback.LogDumpContributor; +import org.eclipse.virgo.medic.dump.impl.summary.SummaryDumpContributor; +import org.eclipse.virgo.medic.dump.impl.thread.ThreadDumpContributor; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.eclipse.virgo.medic.log.impl.logback.LoggingInterceptor; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + + +public final class DumpContributorPublisher { + + private final List<ServiceRegistration> contributorRegistrations = new ArrayList<ServiceRegistration>(); + + private final BundleContext bundleContext; + + private final ConfigurationProvider configurationProvider; + + private final LogDumpContributor logDumpContributor; + + public DumpContributorPublisher(BundleContext bundleContext, ConfigurationProvider configurationProvider) { + this.bundleContext = bundleContext; + this.configurationProvider = configurationProvider; + this.logDumpContributor = new LogDumpContributor(this.configurationProvider); + } + + public void publishDumpContributors() { + LoggingInterceptor.aspectOf().setLoggingListener(this.logDumpContributor); + + publishDumpContributor(new SummaryDumpContributor()); + publishDumpContributor(new HeapDumpContributor()); + publishDumpContributor(new ThreadDumpContributor()); + publishDumpContributor(this.logDumpContributor); + } + + private void publishDumpContributor(DumpContributor dumpContributor) { + ServiceRegistration registration = this.bundleContext.registerService(DumpContributor.class.getName(), dumpContributor, null); + this.contributorRegistrations.add(registration); + } + + public void retractDumpContributors() { + for (ServiceRegistration registration : this.contributorRegistrations) { + registration.unregister(); + } + + LoggingInterceptor.aspectOf().setLoggingListener(null); + this.logDumpContributor.clear(); + + this.contributorRegistrations.clear(); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorResolver.java new file mode 100644 index 0000000..55f36f9 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorResolver.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.util.List; + +import org.eclipse.virgo.medic.dump.DumpContributor; + + +interface DumpContributorResolver { + + List<DumpContributor> getDumpContributors(); + + void close(); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorTracker.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorTracker.java new file mode 100644 index 0000000..a4a4ae5 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/DumpContributorTracker.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTrackerCustomizer; + + +final class DumpContributorTracker implements ServiceTrackerCustomizer { + + private final List<DumpContributor> contributors = new CopyOnWriteArrayList<DumpContributor>(); + + private final BundleContext bundleContext; + + DumpContributorTracker(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public Object addingService(ServiceReference reference) { + Object service = bundleContext.getService(reference); + contributors.add((DumpContributor) service); + return service; + } + + public void modifiedService(ServiceReference reference, Object service) { + } + + public void removedService(ServiceReference reference, Object service) { + this.contributors.remove(service); + this.bundleContext.ungetService(reference); + } + + List<DumpContributor> getDumpContributors() { + return this.contributors; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDump.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDump.java new file mode 100644 index 0000000..3dd9500 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDump.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; + + +final class StandardDump implements Dump { + + private final File dumpDirectory; + + private final String cause; + + private final Map<String, Object> context; + + private final Throwable[] throwables; + + private final long timestamp; + + StandardDump(String cause, long timestamp, Map<String, Object> context, Throwable[] throwables, File dumpDirectory) { + this.cause = cause; + this.timestamp = timestamp; + this.context = context; + this.throwables = throwables; + this.dumpDirectory = dumpDirectory; + } + + public String getCause() { + return this.cause; + } + + public Map<String, Object> getContext() { + return this.context; + } + + public Throwable[] getThrowables() { + return this.throwables; + } + + public long getTimestamp() { + return this.timestamp; + } + + public File createFile(String name) { + return new File(this.dumpDirectory, name); + } + + public FileOutputStream createFileOutputStream(String name) throws DumpContributionFailedException { + try { + return new FileOutputStream(createFile(name)); + } catch (FileNotFoundException e) { + throw new DumpContributionFailedException("Unable to open output stream '" + name + "'"); + } + } + + public FileWriter createFileWriter(String name) throws DumpContributionFailedException { + try { + return new FileWriter(createFile(name)); + } catch (IOException e) { + throw new DumpContributionFailedException("Unable to open file writer '" + name + "'"); + } + } + + File getDumpDirectory() { + return this.dumpDirectory; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDumpContributorResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDumpContributorResolver.java new file mode 100644 index 0000000..7ac0cdf --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDumpContributorResolver.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.util.List; + +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + + +public final class StandardDumpContributorResolver implements DumpContributorResolver { + + private final ServiceTracker serviceTracker; + + private final DumpContributorTracker dumpContributorTracker; + + public StandardDumpContributorResolver(BundleContext bundleContext) { + this.dumpContributorTracker = new DumpContributorTracker(bundleContext); + + this.serviceTracker = new ServiceTracker(bundleContext, DumpContributor.class.getName(), this.dumpContributorTracker); + this.serviceTracker.open(); + } + + public List<DumpContributor> getDumpContributors() { + return this.dumpContributorTracker.getDumpContributors(); + } + + public void close() { + this.serviceTracker.close(); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDumpGenerator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDumpGenerator.java new file mode 100644 index 0000000..13cbe68 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/StandardDumpGenerator.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.DumpGenerationFailedException; +import org.eclipse.virgo.medic.dump.DumpGenerator; +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.impl.MedicLogEvents; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; + + +public final class StandardDumpGenerator implements DumpGenerator { + + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd-HH-mm-SSS"); + + private static final Map<String, Object> NO_CONTEXT = new HashMap<String, Object>(); + + private final DumpContributorResolver dumpContributorsAccessor; + + private final ConfigurationProvider configurationProvider; + + private final EventLogger eventLogger; + + private String latestDumpId = null; + + public StandardDumpGenerator(DumpContributorResolver accessor, ConfigurationProvider configurationProvider, EventLogger eventLogger) { + this.dumpContributorsAccessor = accessor; + this.configurationProvider = configurationProvider; + this.eventLogger = eventLogger; + } + + public void generateDump(String cause, Throwable... throwables) { + this.generateDump(cause, NO_CONTEXT, throwables); + } + + public void generateDump(String cause, Map<String, Object> context, Throwable... throwables) { + StandardDump dump; + try { + dump = createDump(cause, context, throwables); + } catch (DumpGenerationFailedException e) { + return; + } + + for (DumpContributor dumpContributor : getDumpContributors(cause)) { + try { + dumpContributor.contribute(dump); + } catch (DumpContributionFailedException e) { + this.eventLogger.log(MedicLogEvents.CONTRIBUTION_FAILED, e, dumpContributor.getName(), dump.getTimestamp()); + } + } + + this.eventLogger.log(MedicLogEvents.DUMP_GENERATED, dump.getDumpDirectory()); + } + + private StandardDump createDump(String cause, Map<String, Object> context, Throwable... throwables) throws DumpGenerationFailedException { + File dumpDirectory = null; + + long timestamp = System.currentTimeMillis(); + + while ((dumpDirectory = getDumpDirectory(timestamp)) == null) { + try { + Thread.sleep(10); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + timestamp = System.currentTimeMillis(); + } + + return new StandardDump(cause, timestamp, context, throwables, dumpDirectory); + } + + @SuppressWarnings("unchecked") + private List<DumpContributor> getDumpContributors(String cause) { + Dictionary configuration = this.configurationProvider.getConfiguration(); + String excludedContributorsProperty = (String) configuration.get("dump.exclusions." + cause); + List<String> excludedContributors = toList(excludedContributorsProperty); + excludedContributorsProperty = (String) configuration.get("dump.exclusions.*"); + excludedContributors.addAll(toList(excludedContributorsProperty)); + + List<DumpContributor> candidateContributors = this.dumpContributorsAccessor.getDumpContributors(); + + List<DumpContributor> includedContributors = new ArrayList<DumpContributor>(); + + for (DumpContributor candidate : candidateContributors) { + if (!excludedContributors.contains(candidate.getName())) { + includedContributors.add(candidate); + } + } + + return includedContributors; + } + + private List<String> toList(String property) { + List<String> list = new ArrayList<String>(); + if (property != null) { + String[] components = property.split(","); + for (String component : components) { + String trimmed = component.trim(); + list.add(trimmed); + } + } + return list; + } + + private String getDumpId(long timestamp) { + Date date = new Date(timestamp); + synchronized (DATE_FORMAT) { + String dumpId = DATE_FORMAT.format(date); + if (dumpId.equals(latestDumpId)) { + dumpId = null; + } else { + latestDumpId = dumpId; + } + return dumpId; + } + } + + private File getDumpDirectory(long timestamp) throws DumpGenerationFailedException { + File dumpDirectory = null; + + String dumpId = getDumpId(timestamp); + + if (dumpId != null) { + dumpDirectory = new File(getRootDumpDirectory(), dumpId); + if (dumpDirectory.exists()) { + dumpDirectory = null; + } else { + createDirectory(dumpDirectory); + } + } + + return dumpDirectory; + } + + @SuppressWarnings("unchecked") + private String getRootDumpDirectory() { + Dictionary configuration = this.configurationProvider.getConfiguration(); + return (String) configuration.get(ConfigurationProvider.KEY_DUMP_ROOT_DIRECTORY); + } + + private void createDirectory(File file) throws DumpGenerationFailedException { + if (!file.mkdirs()) { + this.eventLogger.log(MedicLogEvents.DIRECTORY_CREATION_FAILED, file.getAbsolutePath()); + throw new DumpGenerationFailedException("Directory creation failed"); + } + } + + public void close() { + this.dumpContributorsAccessor.close(); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/heap/HeapDumpContributor.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/heap/HeapDumpContributor.java new file mode 100644 index 0000000..80daccc --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/heap/HeapDumpContributor.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.heap; + +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; + + +public final class HeapDumpContributor implements DumpContributor { + + private final Method heapDumpMethod; + + private final Object diagnosticMBean; + + public HeapDumpContributor() { + + Method heapDumpMethod = null; + Object diagnosticMBean = null; + + try { + Class<?> managementFactoryClass = Class.forName("sun.management.ManagementFactory", true, HeapDumpContributor.class.getClassLoader()); + Method method = managementFactoryClass.getMethod("getDiagnosticMXBean"); + diagnosticMBean = method.invoke(null); + heapDumpMethod = diagnosticMBean.getClass().getMethod("dumpHeap", String.class, boolean.class); + } catch (Exception e) { + heapDumpMethod = null; + diagnosticMBean = null; + } + + this.heapDumpMethod = heapDumpMethod; + this.diagnosticMBean = diagnosticMBean; + } + + public void contribute(Dump dump) throws DumpContributionFailedException { + try { + if (this.heapDumpMethod != null && this.diagnosticMBean != null) { + heapDumpMethod.invoke(this.diagnosticMBean, dump.createFile("heap.out").getAbsolutePath(), true); + } else { + PrintWriter writer = null; + try { + writer = new PrintWriter(dump.createFileWriter("heap.out")); + writer.println("Diagnostic MXBean is not available. Heap dump cannot be generated."); + } finally { + if (writer != null) { + writer.close(); + } + } + } + } catch (InvocationTargetException e) { + throw new DumpContributionFailedException("Failed to generate heap dump contribution", e); + } catch (IllegalArgumentException e) { + throw new DumpContributionFailedException("Failed to generate heap dump contribution", e); + } catch (IllegalAccessException e) { + throw new DumpContributionFailedException("Failed to generate heap dump contribution", e); + } + } + + public String getName() { + return "heap"; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/logback/LogDumpContributor.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/logback/LogDumpContributor.java new file mode 100644 index 0000000..ef89636 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/logback/LogDumpContributor.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.logback; + +import java.io.PrintWriter; +import java.util.Dictionary; +import java.util.List; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.eclipse.virgo.medic.log.impl.logback.LoggingListener; +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.PatternLayout; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.helpers.CyclicBuffer; + + +/** + * A {@link DumpContributor} that stores {@link LoggingEvent LoggingEvents} in a {@link CyclicBuffer} and + * when a dump is triggered, writes those entries (a small subset of all that it has seen) to the dump directory. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * + * Not threadsafe + * + */ +public final class LogDumpContributor implements DumpContributor, LoggingListener { + + private static final String DEFAULT_LEVEL = Level.OFF.levelStr; + + private static final String DEFAULT_BUFFER_SIZE = "10000"; + + private static final String DEFAULT_PATTERN = "%message%n"; + + private static final String FILE_NAME = "log.log"; + + private static final String NAME = "log"; + + private final CyclicBuffer<LoggingEvent> buffer; + + private final ConfigurationProvider configurationProvider; + + private final Object monitor = new Object(); + + @SuppressWarnings("unchecked") + public LogDumpContributor(ConfigurationProvider configurationProvider) { + this.configurationProvider = configurationProvider; + + Dictionary configDictionary = this.configurationProvider.getConfiguration(); + this.buffer = new CyclicBuffer<LoggingEvent>(getBufferSize(configDictionary)); + } + + public String getName() { + return NAME; + } + + public void contribute(Dump dump) throws DumpContributionFailedException { + Level configuredLevel = getLevel(); + if (Level.OFF.levelInt > configuredLevel.levelInt) { + PrintWriter writer = null; + try { + writer = new PrintWriter(dump.createFileWriter(FILE_NAME)); + List<LoggingEvent> loggingEvents = buffer.asList(); + + PatternLayout layout = createLayout(); + + for (LoggingEvent event : loggingEvents) { + writer.print(layout.doLayout(event)); + } + } finally { + if (writer != null) { + writer.close(); + } + } + } + } + + private PatternLayout createLayout() { + PatternLayout layout = new PatternLayout(); + layout.setPattern(getPattern(this.configurationProvider.getConfiguration())); + layout.setContext(new LoggerContext()); + layout.start(); + + return layout; + } + + @SuppressWarnings("unchecked") + private Level getLevel() { + Dictionary configDictionary = this.configurationProvider.getConfiguration(); + String level = getLevel(configDictionary); + return Level.valueOf(level); + } + + @SuppressWarnings("unchecked") + private int getBufferSize(Dictionary configuration) { + String bufferSizeString = getStringFromConfiguration(configuration, ConfigurationProvider.KEY_LOG_DUMP_BUFFERSIZE, DEFAULT_BUFFER_SIZE); + return Integer.parseInt(bufferSizeString); + } + + @SuppressWarnings("unchecked") + private String getLevel(Dictionary configuration) { + return getStringFromConfiguration(configuration, ConfigurationProvider.KEY_LOG_DUMP_LEVEL, DEFAULT_LEVEL); + } + + @SuppressWarnings("unchecked") + private String getPattern(Dictionary configuration) { + return getStringFromConfiguration(configuration, ConfigurationProvider.KEY_LOG_DUMP_PATTERN, DEFAULT_PATTERN); + } + + @SuppressWarnings("unchecked") + private String getStringFromConfiguration(Dictionary configuration, String key, String defaultValue) { + String value = (String)configuration.get(key); + + if (value == null) { + value = defaultValue; + } + + return value; + } + + public void onLogging(Logger logger, String fqcn, Marker marker, + Level level, String message, Object param, Throwable throwable) { + + if (level.isGreaterOrEqual(getLevel())) { + LoggingEvent event = new LoggingEvent(fqcn, logger, level, message, throwable, new Object[] {param}); + event.setMarker(marker); + event.setThreadName(Thread.currentThread().getName()); + + synchronized (this.monitor) { + this.buffer.add(event); + } + } + } + + public void onLogging(Logger logger, String fqcn, Marker marker, + Level level, String message, Object param1, Object param2, + Throwable throwable) { + + if (level.isGreaterOrEqual(getLevel())) { + LoggingEvent event = new LoggingEvent(fqcn, logger, level, message, throwable, new Object[] {param1, param2}); + event.setMarker(marker); + event.setThreadName(Thread.currentThread().getName()); + + synchronized (this.monitor) { + this.buffer.add(event); + } + } + } + + public void onLogging(Logger logger, String fqcn, Marker marker, + Level level, String message, Object[] params, Throwable throwable) { + + if (level.isGreaterOrEqual(getLevel())) { + LoggingEvent event = new LoggingEvent(fqcn, logger, level, message, throwable, params); + event.setMarker(marker); + event.setThreadName(Thread.currentThread().getName()); + + synchronized (this.monitor) { + this.buffer.add(event); + } + } + } + + /** + * + */ + public void clear() { + synchronized (this.monitor) { + this.buffer.clear(); + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/summary/SummaryDumpContributor.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/summary/SummaryDumpContributor.java new file mode 100644 index 0000000..6c4489c --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/summary/SummaryDumpContributor.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.summary; + +import java.io.PrintWriter; +import java.text.DateFormat; +import java.util.Date; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; + + +public final class SummaryDumpContributor implements DumpContributor { + + private final DateFormat dateFormat = DateFormat.getDateInstance(); + + private final DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.LONG); + + private final Object formatterLock = new Object(); + + public void contribute(Dump dump) throws DumpContributionFailedException { + PrintWriter writer = null; + try { + writer = new PrintWriter(dump.createFileWriter("summary.txt")); + processHeader(writer, dump.getTimestamp()); + processCause(writer, dump.getCause()); + processThrowables(writer, dump.getThrowables()); + } finally { + if (writer != null) { + writer.close(); + } + } + } + + public String getName() { + return "summary"; + } + + private void processHeader(PrintWriter dump, long timestamp) { + synchronized (formatterLock) { + dump.println("Date:\t\t" + dateFormat.format(new Date(timestamp))); + dump.println("Time:\t\t" + timeFormat.format(new Date(timestamp))); + } + } + + private static void processCause(PrintWriter dump, String cause) { + dump.println(); + dump.println("Cause: " + cause); + } + + private static void processThrowables(PrintWriter dump, Throwable... throwables) { + if (throwables.length == 0) { + dump.println(); + dump.println("Exception: None"); + } else { + for (Throwable throwable : throwables) { + dump.println(); + dump.println("Exception:"); + throwable.printStackTrace(dump); + } + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/Java5ThreadInfoWriter.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/Java5ThreadInfoWriter.java new file mode 100644 index 0000000..557a138 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/Java5ThreadInfoWriter.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.io.PrintWriter; +import java.lang.management.ThreadInfo; + +final class Java5ThreadInfoWriter implements ThreadInfoWriter { + + /** + * {@inheritDoc} + */ + public void write(ThreadInfo threadInfo, PrintWriter writer) { + writer.print(String.format("\"%s\" Id=%s %s", threadInfo.getThreadName(), threadInfo.getThreadId(), threadInfo.getThreadState())); + if (threadInfo.getLockName() != null) { + writer.print(String.format(" on %s", threadInfo.getLockName())); + if (threadInfo.getLockOwnerName() != null) { + writer.print(String.format(" owned by \"%s\" Id=%s", threadInfo.getLockOwnerName(), threadInfo.getLockOwnerId())); + } + } + if (threadInfo.isInNative()) { + writer.println(" (in native)"); + } else { + writer.println(); + } + StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); + for (StackTraceElement stackTraceElement : stackTraceElements) { + writer.println(" at " + stackTraceElement); + } + } +} + diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/Java5ThreadMXBeanDelegate.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/Java5ThreadMXBeanDelegate.java new file mode 100644 index 0000000..0c054b6 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/Java5ThreadMXBeanDelegate.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; + +/** + * A Java 5-based implementation of <code>ThreadMXBeanDelegate</code>. This class requires a Java 5 (or later) VM. + * <p/> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public class Java5ThreadMXBeanDelegate implements ThreadMXBeanDelegate { + + private ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + + /** + * {@inheritDoc} + */ + public long[] findDeadlockedThreads() { + return threadBean.findMonitorDeadlockedThreads(); + } + + /** + * {@inheritDoc} + */ + public ThreadInfo[] getThreadInfo(long[] threadIds) { + return threadBean.getThreadInfo(threadIds, Integer.MAX_VALUE); + } + + /** + * {@inheritDoc} + */ + public ThreadInfo[] dumpAllThreads() { + return threadBean.getThreadInfo(threadBean.getAllThreadIds(), Integer.MAX_VALUE); + } +} + diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/StandardThreadInfoWriter.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/StandardThreadInfoWriter.java new file mode 100644 index 0000000..fe01b2e --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/StandardThreadInfoWriter.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.io.PrintWriter; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; + +class StandardThreadInfoWriter implements ThreadInfoWriter { + + public void write(ThreadInfo threadInfo, PrintWriter writer) { + writer.print(String.format("\"%s\" Id=%s %s", threadInfo.getThreadName(), threadInfo.getThreadId(), threadInfo.getThreadState())); + if (threadInfo.getLockName() != null) { + writer.print(String.format(" on %s", threadInfo.getLockName())); + if (threadInfo.getLockOwnerName() != null) { + writer.print(String.format(" owned by \"%s\" Id=%s", threadInfo.getLockOwnerName(), threadInfo.getLockOwnerId())); + } + } + if (threadInfo.isInNative()) { + writer.println(" (in native)"); + } else { + writer.println(); + } + MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors(); + + StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); + for (StackTraceElement stackTraceElement : stackTraceElements) { + writer.println(" at " + stackTraceElement); + MonitorInfo lockedMonitor = findLockedMonitor(stackTraceElement, lockedMonitors); + if (lockedMonitor != null) { + writer.println(" - locked " + lockedMonitor.getClassName() + "@" + lockedMonitor.getIdentityHashCode()); + } + } + } + + private static MonitorInfo findLockedMonitor(StackTraceElement stackTraceElement, MonitorInfo[] lockedMonitors) { + for (MonitorInfo monitorInfo : lockedMonitors) { + if (stackTraceElement.equals(monitorInfo.getLockedStackFrame())) { + return monitorInfo; + } + } + return null; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/StandardThreadMXBeanDelegate.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/StandardThreadMXBeanDelegate.java new file mode 100644 index 0000000..e07f607 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/StandardThreadMXBeanDelegate.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; + +public class StandardThreadMXBeanDelegate implements ThreadMXBeanDelegate { + + private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + + public ThreadInfo[] dumpAllThreads() { + return threadBean.dumpAllThreads(true, true); + } + + public long[] findDeadlockedThreads() { + return threadBean.findDeadlockedThreads(); + } + + public ThreadInfo[] getThreadInfo(long[] threadIds) { + return threadBean.getThreadInfo(threadIds, true, true); + } + +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadDumpContributor.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadDumpContributor.java new file mode 100644 index 0000000..e6b4fd8 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadDumpContributor.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.io.PrintWriter; +import java.lang.management.ThreadInfo; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; + + +public class ThreadDumpContributor implements DumpContributor { + + private final ThreadMXBeanDelegate threadBeanDelegate; + + private final ThreadInfoWriter threadInfoWriter; + + public ThreadDumpContributor(ThreadMXBeanDelegate threadBeanDelegate, ThreadInfoWriter threadInfoPrinter) { + this.threadBeanDelegate = threadBeanDelegate; + this.threadInfoWriter = threadInfoPrinter; + } + + public ThreadDumpContributor() { + String javaSpecificationVersion = System.getProperty("java.specification.version"); + if ("1.5".equals(javaSpecificationVersion)) { + this.threadBeanDelegate = new Java5ThreadMXBeanDelegate(); + this.threadInfoWriter = new Java5ThreadInfoWriter(); + } else { + this.threadBeanDelegate = new StandardThreadMXBeanDelegate(); + this.threadInfoWriter = new StandardThreadInfoWriter(); + } + } + + public String getName() { + return "thread"; + } + + /** + * {@inheritDoc} + */ + public void contribute(Dump dump) throws DumpContributionFailedException { + PrintWriter writer = null; + try { + writer = new PrintWriter(dump.createFileWriter("thread.txt")); + processDeadlocks(writer); + processAllThreads(writer); + writer.close(); + } finally { + if (writer != null) { + writer.close(); + } + } + } + + private void processDeadlocks(PrintWriter dump) { + dump.println("Deadlocked Threads"); + dump.println("=================="); + long[] deadlockedThreadIds = this.threadBeanDelegate.findDeadlockedThreads(); + if (deadlockedThreadIds != null) { + dumpThreads(dump, this.threadBeanDelegate.getThreadInfo(deadlockedThreadIds)); + } + } + + private void processAllThreads(PrintWriter dump) { + dump.println(); + dump.println("All Threads"); + dump.println("==========="); + dumpThreads(dump, this.threadBeanDelegate.dumpAllThreads()); + } + + private void dumpThreads(PrintWriter dump, ThreadInfo[] infos) { + for (ThreadInfo info : infos) { + dump.println(); + this.threadInfoWriter.write(info, dump); + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadInfoWriter.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadInfoWriter.java new file mode 100644 index 0000000..cdfe8f2 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadInfoWriter.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.io.PrintWriter; +import java.lang.management.ThreadInfo; + +/** + * A helper interface for writing {@link ThreadInfo} instances enabling the plugging-in of an implementation that can + * cope with the differences in {@link ThreadInfo}'s contents on Java 5 and Java 6 virtual machines. + * <p/> + * + * <strong>Concurrent Semantics</strong><br /> + * + * Implementations <strong>must</strong> be thread-safe. + * + */ +interface ThreadInfoWriter { + + /** + * Writes the supplied {@ThreadInfo} to the supplied {@PrintWriter}. + * + * @param threadInfo The <code>ThreadInfo</code> + * @param writer the <code>PrintWriter</code> to write to + */ + void write(ThreadInfo threadInfo, PrintWriter writer); +} + diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadMXBeanDelegate.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadMXBeanDelegate.java new file mode 100644 index 0000000..ac8501a --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadMXBeanDelegate.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.lang.management.ThreadInfo; + +/** + * A delegate for ThreadMXBean to hide the differences in the methods and capabilities of its Java 5 and Java 6 + * versions. + * <p /> + * <strong>Concurrent Semantics</strong><br /> + * Implementation <strong>must</strong> be thread-safe. + * + */ +interface ThreadMXBeanDelegate { + + /** + * Finds all threads in the JVM that are deadlocked + * + * @return An array of thread ids of the deadlocked threads + */ + long[] findDeadlockedThreads(); + + /** + * Returns an array of <code>ThreadInfo</code> instances, one for each thread identified in the supplied array of + * thread ids. + * + * @param threadIds The thread ids + * @return The array of <code>ThreadInfo</code> instances. + */ + public ThreadInfo[] getThreadInfo(long[] threadIds); + + /** + * Returns an array of <code>ThreadInfo</code> instances, one for each live thread. + * + * @return The array of <code>ThreadInfo</code> instances. + */ + public ThreadInfo[] dumpAllThreads(); +} + diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/BundleSearchingPropertyResourceBundleResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/BundleSearchingPropertyResourceBundleResolver.java new file mode 100644 index 0000000..d86a2da --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/BundleSearchingPropertyResourceBundleResolver.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.PropertyResourceBundle; + +import org.osgi.framework.Bundle; + +public final class BundleSearchingPropertyResourceBundleResolver implements PropertyResourceBundleResolver { + + public List<PropertyResourceBundle> getResourceBundles(Bundle bundle, String candidatePropertiesFileName) { + Enumeration<?> entries = bundle.findEntries("", candidatePropertiesFileName, false); + List<PropertyResourceBundle> propertyBundles = new ArrayList<PropertyResourceBundle>(); + if (entries != null) { + while (entries.hasMoreElements()) { + URL propertiesFile = (URL) entries.nextElement(); + InputStream input = null; + try { + input = propertiesFile.openStream(); + propertyBundles.add(new PropertyResourceBundle(input)); + } catch (IOException ioe) { + } finally { + try { + if (input != null) { + input.close(); + } + } catch (IOException e) { + } + } + } + } + return propertyBundles; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/EventLoggerServiceFactory.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/EventLoggerServiceFactory.java new file mode 100644 index 0000000..03d7a11 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/EventLoggerServiceFactory.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import org.eclipse.virgo.medic.eventlog.EventLoggerFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceRegistration; + + +public final class EventLoggerServiceFactory implements ServiceFactory { + + private final EventLoggerFactory eventLoggerFactory; + + public EventLoggerServiceFactory(EventLoggerFactory factory) { + this.eventLoggerFactory = factory; + } + + public Object getService(Bundle bundle, ServiceRegistration registration) { + return this.eventLoggerFactory.createEventLogger(bundle); + } + + public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) { + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/LocaleResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/LocaleResolver.java new file mode 100644 index 0000000..c29742d --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/LocaleResolver.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.util.Locale; + +/** + * A <code>LocaleResolver</code> provides a basic strategy for determining the current {@link Locale}. + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + * + */ +public interface LocaleResolver { + + /** + * Return the current {@link Locale}. This should never return <code>null</code>. + * + * @return the current <code>Locale</code>. Never <code>null</code>. + */ + Locale getLocale(); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/MessageResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/MessageResolver.java new file mode 100644 index 0000000..4ace248 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/MessageResolver.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.util.Locale; + +/** + * A LogEventMessageResolver is used to resolve the message of a logged event. + * + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + * + */ +public interface MessageResolver { + + /** + * Resolves the message identified by the supplied event code. + * @param eventCode The code identifying the message to be resolved + * @return The resolved message, or <code>null</code> if no message could be found + */ + String resolveLogEventMessage(String eventCode); + + /** + * Resolves the message identified by the supplied event code in the supplied {@link Locale}. + * + * @param eventCode The code identifying the message is to be resolved + * @param locale the {@link Locale} in which the message is to be resolved + * @return The resolved message, or <code>null</code> if no message could be found + */ + String resolveLogEventMessage(String eventCode, Locale locale); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/PropertyResourceBundleResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/PropertyResourceBundleResolver.java new file mode 100644 index 0000000..f043968 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/PropertyResourceBundleResolver.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.util.List; +import java.util.PropertyResourceBundle; + +import org.osgi.framework.Bundle; + +public interface PropertyResourceBundleResolver { + + List<PropertyResourceBundle> getResourceBundles(Bundle bundle, String candidatePropertiesFileName); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/ResourceBundleUtils.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/ResourceBundleUtils.java new file mode 100644 index 0000000..4bc9795 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/ResourceBundleUtils.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +final class ResourceBundleUtils { + + private static final String PROPERTIES_SUFFIX = ".properties"; + + static List<String> generateCandidatePropertiesFileNames(String baseName, Locale locale) { + List<String> candidateNames = new ArrayList<String>(); + + candidateNames.addAll(generateCandidatePropertiesFileNames(baseName, locale.getLanguage(), locale.getCountry(), locale.getVariant())); + + Locale defaultLocale = Locale.getDefault(); + + if (!defaultLocale.equals(locale)) { + candidateNames.addAll(generateCandidatePropertiesFileNames(baseName, defaultLocale.getLanguage(), defaultLocale.getCountry(), + defaultLocale.getVariant())); + } + + candidateNames.add(baseName + PROPERTIES_SUFFIX); + + return candidateNames; + } + + private static List<String> generateCandidatePropertiesFileNames(String baseName, String language, String country, String variant) { + List<String> candidateNames = new ArrayList<String>(); + + if (hasText(language)) { + if (hasText(country)) { + if (hasText(variant)) { + candidateNames.add(baseName + "_" + language + "_" + country + "_" + variant + PROPERTIES_SUFFIX); + } + candidateNames.add(baseName + "_" + language + "_" + country + PROPERTIES_SUFFIX); + } + candidateNames.add(baseName + "_" + language + PROPERTIES_SUFFIX); + } + + return candidateNames; + } + + private static boolean hasText(String string) { + return (string != null && string.length() > 0); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/StandardLocaleResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/StandardLocaleResolver.java new file mode 100644 index 0000000..fd63b99 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/StandardLocaleResolver.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.util.Locale; + +public final class StandardLocaleResolver implements LocaleResolver { + + public Locale getLocale() { + return Locale.getDefault(); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/StandardMessageResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/StandardMessageResolver.java new file mode 100644 index 0000000..5969c1b --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/StandardMessageResolver.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.PropertyResourceBundle; + +import org.osgi.framework.Bundle; + +public final class StandardMessageResolver implements MessageResolver { + + private static final String RESOURCE_BUNDLE_NAME = "EventLogMessages"; + + private final LocaleResolver localeResolver; + + private final PropertyResourceBundleResolver resourceBundleLocator; + + private final Bundle primaryBundle; + + private final Bundle secondaryBundle; + + public StandardMessageResolver(LocaleResolver localeResolver, PropertyResourceBundleResolver resourceBundleLocator, Bundle primaryBundle, + Bundle secondaryBundle) { + this.localeResolver = localeResolver; + this.resourceBundleLocator = resourceBundleLocator; + this.primaryBundle = primaryBundle; + this.secondaryBundle = secondaryBundle; + } + + public String resolveLogEventMessage(String eventCode) { + return resolveLogEventMessage(eventCode, this.localeResolver.getLocale()); + } + + public String resolveLogEventMessage(String eventCode, Locale locale) { + List<String> candidatePropertiesFileNames = ResourceBundleUtils.generateCandidatePropertiesFileNames(RESOURCE_BUNDLE_NAME, locale); + + String message = resolveMessageInBundle(this.primaryBundle, eventCode, candidatePropertiesFileNames); + + if (message == null) { + message = resolveMessageInBundle(this.secondaryBundle, eventCode, candidatePropertiesFileNames); + } + + return message; + } + + private String resolveMessageInBundle(Bundle bundle, String key, List<String> candidatePropertiesFileNames) { + for (String candidatePropertiesFileName : candidatePropertiesFileNames) { + List<PropertyResourceBundle> resourceBundles = this.resourceBundleLocator.getResourceBundles(bundle, candidatePropertiesFileName); + for (PropertyResourceBundle resourceBundle : resourceBundles) { + try { + String string = resourceBundle.getString(key); + if (string != null) { + return string; + } + } catch (MissingResourceException mre) { + // Continue searching + } + } + } + return null; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLogger.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLogger.java new file mode 100644 index 0000000..85008c6 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLogger.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl.logback; + +import java.util.Locale; + +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.eventlog.LogEvent; +import org.eclipse.virgo.medic.eventlog.impl.MessageResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.helpers.MessageFormatter; + + +class LogBackEventLogger implements EventLogger { + + private static final String MDC_KEY_MEDIC_EVENT_CODE = "medic.eventCode"; + + private static final String MISSING_MESSAGE_EVENT_CODE = "ME0001W"; + + private final Logger localizedLogger = LoggerFactory.getLogger("org.eclipse.virgo.medic.eventlog.localized"); + + private final Logger defaultLogger = LoggerFactory.getLogger("org.eclipse.virgo.medic.eventlog.default"); + + private final MessageResolver messageResolver; + + private final Locale defaultLocale = Locale.ENGLISH; + + LogBackEventLogger(MessageResolver messageResolver) { + this.messageResolver = messageResolver; + } + + public void log(String code, Level level, Object... inserts) { + this.log(code, level, null, inserts); + } + + public void log(LogEvent logEvent, Object... inserts) { + this.log(logEvent.getEventCode(), logEvent.getLevel(), inserts); + } + + public void log(String eventCode, Level level, Throwable throwable, Object... inserts) { + try { + String localisedMessage = messageResolver.resolveLogEventMessage(eventCode); + + if (localisedMessage != null) { + logMessage(this.localizedLogger, localisedMessage, level, eventCode, throwable, inserts); + } else { + logMissingMessage(this.localizedLogger, eventCode, throwable, inserts); + } + + String defaultMessage = messageResolver.resolveLogEventMessage(eventCode, defaultLocale); + + if (defaultMessage != null) { + logMessage(this.defaultLogger, defaultMessage, level, eventCode, throwable, inserts); + } else { + logMissingMessage(this.defaultLogger, eventCode, throwable, inserts); + } + } finally { + MDC.remove(MDC_KEY_MEDIC_EVENT_CODE); + } + } + + public void log(LogEvent logEvent, Throwable throwable, Object... inserts) { + this.log(logEvent.getEventCode(), logEvent.getLevel(), throwable, inserts); + } + + private void logMissingMessage(Logger logger, String eventCode, Throwable throwable, Object[] inserts) { + logMessage(logger, "A message with the key '{}' was not found. The inserts for the message were '{}'", Level.WARNING, + MISSING_MESSAGE_EVENT_CODE, throwable, eventCode, inserts); + } + + private void logMessage(Logger logger, String message, Level level, String eventCode, Throwable throwable, Object... inserts) { + try { + MDC.put(MDC_KEY_MEDIC_EVENT_CODE, eventCode); + String formattedMessage = MessageFormatter.arrayFormat(message, (Object[]) inserts); + switch (level) { + case ERROR: + logger.error(formattedMessage, throwable); + break; + case WARNING: + logger.warn(formattedMessage, throwable); + break; + case INFO: + logger.info(formattedMessage, throwable); + break; + } + } finally { + MDC.remove(MDC_KEY_MEDIC_EVENT_CODE); + } + } + +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLoggerFactory.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLoggerFactory.java new file mode 100644 index 0000000..b5d8349 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLoggerFactory.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl.logback; + +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.EventLoggerFactory; +import org.eclipse.virgo.medic.eventlog.impl.LocaleResolver; +import org.eclipse.virgo.medic.eventlog.impl.MessageResolver; +import org.eclipse.virgo.medic.eventlog.impl.PropertyResourceBundleResolver; +import org.eclipse.virgo.medic.eventlog.impl.StandardMessageResolver; +import org.osgi.framework.Bundle; + + +public class LogBackEventLoggerFactory implements EventLoggerFactory { + + private final Bundle secondaryBundle; + + private final PropertyResourceBundleResolver resourceBundleResolver; + + private final LocaleResolver localeResolver; + + public LogBackEventLoggerFactory(PropertyResourceBundleResolver resourceBundleResolver, LocaleResolver localeResolver, Bundle secondaryBundle) { + this.secondaryBundle = secondaryBundle; + this.resourceBundleResolver = resourceBundleResolver; + this.localeResolver = localeResolver; + } + + public EventLogger createEventLogger(Bundle primaryBundle) { + MessageResolver messageResolver = new StandardMessageResolver(this.localeResolver, resourceBundleResolver, primaryBundle, + this.secondaryBundle); + return new LogBackEventLogger(messageResolver); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java new file mode 100644 index 0000000..3bc296b --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl; + +import java.io.File; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Dictionary; +import java.util.List; +import java.util.Properties; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleListener; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.ConfigurationListener; +import org.osgi.service.packageadmin.PackageAdmin; + + +import org.eclipse.virgo.medic.dump.DumpGenerator; +import org.eclipse.virgo.medic.dump.impl.DumpContributorPublisher; +import org.eclipse.virgo.medic.dump.impl.StandardDumpContributorResolver; +import org.eclipse.virgo.medic.dump.impl.StandardDumpGenerator; +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.EventLoggerFactory; +import org.eclipse.virgo.medic.eventlog.impl.BundleSearchingPropertyResourceBundleResolver; +import org.eclipse.virgo.medic.eventlog.impl.EventLoggerServiceFactory; +import org.eclipse.virgo.medic.eventlog.impl.StandardLocaleResolver; +import org.eclipse.virgo.medic.eventlog.impl.logback.LogBackEventLoggerFactory; +import org.eclipse.virgo.medic.impl.config.ConfigurationAdminConfigurationProvider; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.eclipse.virgo.medic.log.ConfigurationPublicationFailedException; +import org.eclipse.virgo.medic.log.DelegatingPrintStream; +import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher; +import org.eclipse.virgo.medic.log.impl.CallingBundleResolver; +import org.eclipse.virgo.medic.log.impl.ClassSelector; +import org.eclipse.virgo.medic.log.impl.ExecutionStackAccessor; +import org.eclipse.virgo.medic.log.impl.LoggingLevel; +import org.eclipse.virgo.medic.log.impl.LoggingPrintStreamWrapper; +import org.eclipse.virgo.medic.log.impl.PackageNameFilteringClassSelector; +import org.eclipse.virgo.medic.log.impl.SecurityManagerExecutionStackAccessor; +import org.eclipse.virgo.medic.log.impl.StandardCallingBundleResolver; +import org.eclipse.virgo.medic.log.impl.StandardDelegatingPrintStream; +import org.eclipse.virgo.medic.log.impl.config.BundleResourceConfigurationLocator; +import org.eclipse.virgo.medic.log.impl.config.CompositeConfigurationLocator; +import org.eclipse.virgo.medic.log.impl.config.ConfigurationLocator; +import org.eclipse.virgo.medic.log.impl.config.ServiceRegistryConfigurationLocator; +import org.eclipse.virgo.medic.log.impl.config.StandardLoggingConfigurationPublisher; +import org.eclipse.virgo.medic.log.impl.logback.DelegatingContextSelector; +import org.eclipse.virgo.medic.log.impl.logback.JoranLoggerContextConfigurer; +import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurer; +import org.eclipse.virgo.medic.log.impl.logback.StandardContextSelectorDelegate; +import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker; + +public final class MedicActivator implements BundleActivator { + + private static final String LOGGER_NAME_SYSERR = "System.err"; + + private static final String LOGGER_NAME_SYSOUT = "System.out"; + + private static final String LOGGER_NAME_SYSERR_DELEGATE = "delegating.System.err"; + + private static final String LOGGER_NAME_SYSOUT_DELEGATE = "delegating.System.out"; + + private static final String PROPERTY_MEDIC_CONFIG_PATH = "org.eclipse.virgo.medic.log.config.path"; + + private static final String DEFAULT_CONTEXT_SELECTOR = "ch.qos.logback.classic.selector.DefaultContextSelector"; + + private static final String PROPERTY_LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector"; + + private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker(); + + private volatile StandardDumpGenerator dumpGenerator; + + private volatile LogBackEventLoggerFactory eventLoggerFactory; + + private volatile DumpContributorPublisher dumpContributorPublisher; + + private volatile ServiceReference packageAdminReference; + + private volatile PrintStream sysOut; + + private volatile PrintStream sysErr; + + private static final List<String> DEFAULT_LOGGING_PACKAGES = Arrays.asList(// + "org.apache.commons.logging",// + "org.apache.log4j",// + "org.slf4j",// + "org.slf4j.impl",// + "org.eclipse.virgo.medic.log",// + "org.eclipse.virgo.medic.log.impl",// + "org.eclipse.virgo.medic.log.impl.logback"); + + public void start(BundleContext context) throws Exception { + ConfigurationProvider configurationProvider = new ConfigurationAdminConfigurationProvider(context); + this.registrationTracker.track(context.registerService(ConfigurationListener.class.getName(), configurationProvider, null)); + + logStart(context, configurationProvider); + eventLogStart(context); + dumpStart(context, configurationProvider); + } + + public void stop(BundleContext context) throws Exception { + + this.registrationTracker.unregisterAll(); + + dumpStop(); + logStop(context); + } + + private void dumpStart(BundleContext context, ConfigurationProvider configurationProvider) { + + this.dumpGenerator = new StandardDumpGenerator(new StandardDumpContributorResolver(context), configurationProvider, + this.eventLoggerFactory.createEventLogger(context.getBundle())); + this.registrationTracker.track(context.registerService(DumpGenerator.class.getName(), this.dumpGenerator, null)); + + this.dumpContributorPublisher = new DumpContributorPublisher(context, configurationProvider); + this.dumpContributorPublisher.publishDumpContributors(); + } + + private void dumpStop() { + if (this.dumpGenerator != null) { + this.dumpGenerator.close(); + } + + if (this.dumpContributorPublisher != null) { + this.dumpContributorPublisher.retractDumpContributors(); + } + } + + @SuppressWarnings("unchecked") + private void logStart(BundleContext context, ConfigurationProvider configurationProvider) throws ConfigurationPublicationFailedException { + this.packageAdminReference = context.getServiceReference(PackageAdmin.class.getName()); + PackageAdmin packageAdmin = (PackageAdmin) context.getService(this.packageAdminReference); + + StandardContextSelectorDelegate delegate = createContextSelectorDelegate(context, packageAdmin); + this.registrationTracker.track(context.registerService(BundleListener.class.getName(), delegate, null)); + DelegatingContextSelector.setDelegate(delegate); + + StandardLoggingConfigurationPublisher loggingConfigurationPublisher = new StandardLoggingConfigurationPublisher(context); + this.registrationTracker.track(context.registerService(LoggingConfigurationPublisher.class.getName(), loggingConfigurationPublisher, null)); + + publishDefaultConfigurationIfAvailable(context, loggingConfigurationPublisher); + + System.setProperty(PROPERTY_LOGBACK_CONTEXT_SELECTOR, DelegatingContextSelector.class.getName()); + + ExecutionStackAccessor stackAccessor = new SecurityManagerExecutionStackAccessor(); + + Dictionary configuration = configurationProvider.getConfiguration(); + + PrintStream delegatingSysOut = new StandardDelegatingPrintStream(System.out); + PrintStream delegatingSysErr = new StandardDelegatingPrintStream(System.err); + + this.sysOut = System.out; + this.sysErr = System.err; + + System.setOut(delegatingSysOut); + System.setErr(delegatingSysErr); + + if (Boolean.valueOf((String)configuration.get(ConfigurationProvider.KEY_LOG_WRAP_SYSOUT))) { + publishDelegatingPrintStream(delegatingSysOut, LOGGER_NAME_SYSOUT_DELEGATE, context); + publishPrintStream(this.sysOut, LOGGER_NAME_SYSOUT, context); + + System.setOut(wrapPrintStream(System.out, LOGGER_NAME_SYSOUT, LoggingLevel.INFO, stackAccessor, configurationProvider, ConfigurationProvider.KEY_LOG_WRAP_SYSOUT)); + } + + if (Boolean.valueOf((String)configuration.get(ConfigurationProvider.KEY_LOG_WRAP_SYSERR))) { + publishDelegatingPrintStream(delegatingSysErr, LOGGER_NAME_SYSERR_DELEGATE, context); + publishPrintStream(this.sysErr, LOGGER_NAME_SYSERR, context); + + System.setErr(wrapPrintStream(System.err, LOGGER_NAME_SYSERR, LoggingLevel.ERROR, stackAccessor, configurationProvider, ConfigurationProvider.KEY_LOG_WRAP_SYSERR)); + } + } + + private PrintStream wrapPrintStream(PrintStream printStream, String loggerName, LoggingLevel loggingLevel, ExecutionStackAccessor stackAccessor, ConfigurationProvider configurationProvider, String configurationProperty) { + LoggingPrintStreamWrapper wrapper = new LoggingPrintStreamWrapper(printStream, loggerName, loggingLevel, stackAccessor, configurationProvider, configurationProperty); + return wrapper; + } + + private void publishPrintStream(PrintStream printStream, String name, BundleContext context) { + Properties properties = new Properties(); + properties.put("org.eclipse.virgo.medic.log.printStream", name); + + this.registrationTracker.track(context.registerService(PrintStream.class.getName(), printStream, properties)); + } + + private void publishDelegatingPrintStream(PrintStream printStream, String name, BundleContext context) { + Properties properties = new Properties(); + properties.put("org.eclipse.virgo.medic.log.printStream", name); + + String[] classes = new String[] {DelegatingPrintStream.class.getName()}; + this.registrationTracker.track(context.registerService(classes, printStream, properties)); + } + + private void publishDefaultConfigurationIfAvailable(BundleContext context, StandardLoggingConfigurationPublisher publisher) throws ConfigurationPublicationFailedException { + String logConfigPath = context.getProperty(PROPERTY_MEDIC_CONFIG_PATH); + if (logConfigPath != null) { + File logConfigFile = new File(logConfigPath); + if (logConfigFile.exists()) { + publisher.publishDefaultConfiguration(new File(logConfigPath)); + } + } + } + + private static StandardContextSelectorDelegate createContextSelectorDelegate(BundleContext bundleContext, PackageAdmin packageAdmin) { + ConfigurationLocator configurationLocator = createConfigurationLocator(bundleContext); + CallingBundleResolver loggingCallerLocator = createLoggingCallerLocator(packageAdmin); + LoggerContextConfigurer loggerContextConfigurer = new JoranLoggerContextConfigurer(); + return new StandardContextSelectorDelegate(loggingCallerLocator, configurationLocator, bundleContext.getBundle(), loggerContextConfigurer); + } + + private static ConfigurationLocator createConfigurationLocator(BundleContext bundleContext) { + return new CompositeConfigurationLocator(new ServiceRegistryConfigurationLocator(bundleContext), new BundleResourceConfigurationLocator()); + } + + private static CallingBundleResolver createLoggingCallerLocator(PackageAdmin packageAdmin) { + ClassSelector classSelector = createClassSelector(); + ExecutionStackAccessor executionStackAccessor = createExecutionStackAccessor(); + + return new StandardCallingBundleResolver(executionStackAccessor, classSelector, packageAdmin); + } + + private static ClassSelector createClassSelector() { + return new PackageNameFilteringClassSelector(DEFAULT_LOGGING_PACKAGES); + } + + private static ExecutionStackAccessor createExecutionStackAccessor() { + return new SecurityManagerExecutionStackAccessor(); + } + + private void logStop(BundleContext context) { + + System.setProperty(PROPERTY_LOGBACK_CONTEXT_SELECTOR, DEFAULT_CONTEXT_SELECTOR); + + if (this.packageAdminReference != null) { + context.ungetService(this.packageAdminReference); + this.packageAdminReference = null; + } + + DelegatingContextSelector.setDelegate(null); + + if (this.sysOut != null) { + System.setOut(this.sysOut); + } + + if (this.sysErr != null) { + System.setErr(this.sysErr); + } + } + + private void eventLogStart(BundleContext context) { + this.eventLoggerFactory = createFactory(context); + ServiceFactory serviceFactory = new EventLoggerServiceFactory(this.eventLoggerFactory); + this.registrationTracker.track(context.registerService(EventLoggerFactory.class.getName(), this.eventLoggerFactory, null)); + this.registrationTracker.track(context.registerService(EventLogger.class.getName(), serviceFactory, null)); + } + + private LogBackEventLoggerFactory createFactory(BundleContext context) { + BundleSearchingPropertyResourceBundleResolver resourceBundleResolver = new BundleSearchingPropertyResourceBundleResolver(); + return new LogBackEventLoggerFactory(resourceBundleResolver, new StandardLocaleResolver(), context.getBundle()); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicLogEvents.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicLogEvents.java new file mode 100644 index 0000000..ed7877f --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicLogEvents.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl; + +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.eventlog.LogEvent; + +public enum MedicLogEvents implements LogEvent { + + DIRECTORY_CREATION_FAILED(1, Level.WARNING), // + CONTRIBUTION_FAILED(2, Level.WARNING), // + DUMP_GENERATED(3, Level.INFO); + + private static final String PREFIX = "ME"; + + private final int code; + + private final Level level; + + private MedicLogEvents(int code, Level level) { + this.code = code; + this.level = level; + } + + public String getEventCode() { + return String.format("%s%04d%1.1s", PREFIX, this.code, this.level); + } + + public Level getLevel() { + return level; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java new file mode 100644 index 0000000..7d9c2f7 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl.config; + +import java.io.IOException; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.cm.ConfigurationEvent; +import org.osgi.service.cm.ConfigurationListener; + +public final class ConfigurationAdminConfigurationProvider implements ConfigurationProvider, ConfigurationListener { + + private static final String CONFIG_ADMIN_PID = "org.eclipse.virgo.medic"; + + private static final String CONFIG_ADMIN_SERVICE_NAME = "org.osgi.service.cm.ConfigurationAdmin"; + + private static final Dictionary<Object, Object> DEFAULT_CONFIG = createDefaultConfiguration(); + + private final BundleContext bundleContext; + + @SuppressWarnings("unchecked") + private volatile Dictionary configuration = DEFAULT_CONFIG; + + public ConfigurationAdminConfigurationProvider(BundleContext context) { + this.bundleContext = context; + initialisePropertiesFromConfigurationAdmin(); + } + + public Dictionary<?, ?> getConfiguration() { + return this.configuration; + } + + + private void initialisePropertiesFromConfigurationAdmin() { + ServiceReference configAdminReference = this.bundleContext.getServiceReference(CONFIG_ADMIN_SERVICE_NAME); + + if (configAdminReference != null) { + this.bundleContext.registerService(ConfigurationListener.class.getName(), new MedicConfigurationListener(), null); + setPropertiesFromConfigurationAdmin(configAdminReference); + } + } + + @SuppressWarnings("unchecked") + private void setPropertiesFromConfigurationAdmin(ServiceReference configAdminReference) { + ConfigurationAdmin configurationAdmin = (ConfigurationAdmin)this.bundleContext.getService(configAdminReference); + + if (configurationAdmin != null) { + try { + Configuration configuration = configurationAdmin.getConfiguration(CONFIG_ADMIN_PID, null); + + Dictionary properties = configuration.getProperties(); + + if (properties == null) { + properties = DEFAULT_CONFIG; + } else { + DictionaryUtils.merge(properties, DEFAULT_CONFIG); + } + + this.configuration = properties; + } catch (IOException ioe) { + } + } else { + this.configuration = DEFAULT_CONFIG; + } + } + + private static Dictionary<Object, Object> createDefaultConfiguration() { + Dictionary<Object, Object> configuration = new Hashtable<Object, Object>(); + configuration.put(KEY_DUMP_ROOT_DIRECTORY, "."); + configuration.put(KEY_LOG_WRAP_SYSOUT, Boolean.toString(Boolean.TRUE)); + configuration.put(KEY_LOG_WRAP_SYSERR, Boolean.toString(Boolean.TRUE)); + return configuration; + } + + private final class MedicConfigurationListener implements ConfigurationListener { + + public void configurationEvent(ConfigurationEvent configEvent) { + if (CONFIG_ADMIN_PID.equals(configEvent.getPid()) && configEvent.getType() == ConfigurationEvent.CM_UPDATED) { + setPropertiesFromConfigurationAdmin(configEvent.getReference()); + } + } + } + + public void configurationEvent(ConfigurationEvent event) { + if (event.getType() == ConfigurationEvent.CM_UPDATED && CONFIG_ADMIN_PID.equals(event.getPid())) { + setPropertiesFromConfigurationAdmin(event.getReference()); + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java new file mode 100644 index 0000000..01b6470 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl.config; + +import java.util.Dictionary; + +public interface ConfigurationProvider { + + public static final String KEY_DUMP_ROOT_DIRECTORY = "dump.root.directory"; + + public static final String KEY_LOG_WRAP_SYSOUT = "log.wrapSysOut"; + + public static final String KEY_LOG_WRAP_SYSERR = "log.wrapSysErr"; + + public static final String KEY_LOG_DUMP_BUFFERSIZE = "log.dump.bufferSize"; + + public static final String KEY_LOG_DUMP_LEVEL = "log.dump.level"; + + public static final String KEY_LOG_DUMP_PATTERN = "log.dump.pattern"; + + @SuppressWarnings("unchecked") + Dictionary getConfiguration(); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/DictionaryUtils.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/DictionaryUtils.java new file mode 100644 index 0000000..285d84d --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/DictionaryUtils.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl.config; + +import java.util.Dictionary; +import java.util.Enumeration; + +final class DictionaryUtils { + + static void merge(Dictionary<Object, Object> primary, Dictionary<Object, Object> secondary) { + Enumeration<?> keys = secondary.keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + if (primary.get(key) == null) { + primary.put(key, secondary.get(key)); + } + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/CallingBundleResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/CallingBundleResolver.java new file mode 100644 index 0000000..195e368 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/CallingBundleResolver.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import org.osgi.framework.Bundle; + +public interface CallingBundleResolver { + + /** + * Returns the {@link Bundle} from which the current logging call originated. + * + * @return the <code>Bundle</code> that made the logging call + */ + Bundle getCallingBundle(); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/ClassSelector.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/ClassSelector.java new file mode 100644 index 0000000..a949187 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/ClassSelector.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +public interface ClassSelector { + + Class<?> select(Class<?>[] classes); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/ExecutionStackAccessor.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/ExecutionStackAccessor.java new file mode 100644 index 0000000..fb0c03a --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/ExecutionStackAccessor.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +public interface ExecutionStackAccessor { + + /** + * Returns the current execution stack as an array of {@link Class Classes}. The first elements in the array is the + * class of this method's caller, the second element is that method's caller, and so on. + * + * @return the execution stack + */ + Class<?>[] getExecutionStack(); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/LoggingLevel.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/LoggingLevel.java new file mode 100644 index 0000000..9420366 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/LoggingLevel.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +/** + * A fixed set of logging levels used to control logging for wrapped print streams. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Fully thread-safe constants. + * + */ +public enum LoggingLevel { + WARNING, INFO, DEBUG, ERROR; +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapper.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapper.java new file mode 100644 index 0000000..ee50845 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapper.java @@ -0,0 +1,506 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import java.io.PrintStream; +import java.util.Locale; + +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * A <code>LoggingPrintStreamWrapper</code> wraps a PrintStream instance and logs, via SLF4j, + * all data that is written to it. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public final class LoggingPrintStreamWrapper extends PrintStream { + + private static final String LOGBACK_PACKAGE_NAME_PREFIX = "ch.qos.logback"; + + private final ThreadLocal<StringBuilder> entryBuilders; + + private final Logger logger; + + private final ExecutionStackAccessor executionStackAccessor; + + private final ConfigurationProvider configurationProvider; + + private final String configurationProperty; + + private final PrintStream originalPrintStream; + + private final LoggingLevel loggingLevel; + + private static final String NULL_STRING = "null"; + + /** + * Creates a new LoggingPrintStreamWrapper for the given PrintStream. Data written to + * the stream is logged via SLF4j to a logger with the supplied <code>loggerName</code>.<br/> + * The logging level is determined by the parameter of type {@link LoggingLevel}. + * + * @param printStream The PrintStream instance to wrap + * @param loggerName The name of the logger + * @param loggingLevel The level of the log entries created + * @param executionStackAccessor + * @param configurationProvider + * @param configurationProperty + */ + public LoggingPrintStreamWrapper(PrintStream printStream, String loggerName, LoggingLevel loggingLevel, ExecutionStackAccessor executionStackAccessor, ConfigurationProvider configurationProvider, String configurationProperty) { + super(printStream); + + this.logger = LoggerFactory.getLogger(loggerName); + this.loggingLevel = loggingLevel; + + this.executionStackAccessor = executionStackAccessor; + + this.entryBuilders = new ThreadLocal<StringBuilder>() { + public StringBuilder initialValue() { + return new StringBuilder(); + } + }; + + this.configurationProvider = configurationProvider; + + this.configurationProperty = configurationProperty; + + this.originalPrintStream = printStream; + } + + /** + * Creates a new LoggingPrintStreamWrapper for the given PrintStream. Data written to + * the stream is logged via SLF4j to a logger with the supplied <code>loggerName</code>.<br/> + * (The logging level is DEBUG by default.) + * + * @param printStream The PrintStream instance to wrap + * @param loggerName The name of the logger + * @param executionStackAccessor + * @param configurationProvider + * @param configurationProperty + */ + public LoggingPrintStreamWrapper(PrintStream printStream, String loggerName, ExecutionStackAccessor executionStackAccessor, ConfigurationProvider configurationProvider, String configurationProperty) { + this(printStream, loggerName, LoggingLevel.DEBUG, executionStackAccessor, configurationProvider, configurationProperty); + } + + @Override + public PrintStream append(char c) { + if (!isLoggingEnabled()) { + super.append(c); + } else { + this.internalAppend(c); + } + return this; + } + + private boolean internalAppend(char c) { + if (c == '\n' || c == '\r') { + createEntryAndLog(entryBuilders.get()); + return true; + } else { + entryBuilders.get().append(c); + return false; + } + } + + @Override + public PrintStream append(CharSequence csq, int start, int end) { + if (!isLoggingEnabled()) { + super.append(csq, start, end); + } else { + this.internalAppend(csq, start, end); + } + + return this; + } + + private void internalAppend(CharSequence csq, int start, int end) { + for (int i = start; i < end; i++) { + boolean loggedEntry = internalAppend(csq.charAt(i)); + if (loggedEntry && i < (end - 1)) { + char c = csq.charAt(i + 1); + if (c == '\n' || c == '\r') { + i++; + } + } + } + } + + @Override + public PrintStream append(CharSequence csq) { + if (!isLoggingEnabled()) { + super.append(csq); + } else { + if(csq == null){ + throw new NullPointerException("Character Sequence to be added to the printStream from source '" + this.logger.getName() + "' is null"); + } + this.internalAppend(csq, 0, csq.length()); + } + return this; + } + + @Override + public boolean checkError() { + if (!isLoggingEnabled()) { + return super.checkError(); + } else { + return false; + } + } + + @Override + public void close() { + if (!isLoggingEnabled()) { + super.close(); + } + } + + @Override + public void flush() { + if (!isLoggingEnabled()) { + super.flush(); + } + } + + @Override + public PrintStream format(Locale l, String format, Object... args) { + if (!isLoggingEnabled()) { + super.format(l, format, args); + } else { + this.internalPrint(String.format(l, format, args)); + } + return this; + } + + @Override + public PrintStream format(String format, Object... args) { + if (!isLoggingEnabled()) { + super.format(format, args); + } else { + this.internalPrint(String.format(format, args)); + } + return this; + } + + @Override + public void print(boolean b) { + if (!isLoggingEnabled()) { + super.print(b); + } else { + this.internalPrint(b); + } + } + + private void internalPrint(boolean b) { + entryBuilders.get().append(b); + } + + @Override + public void print(char c) { + if (!isLoggingEnabled()) { + super.print(c); + } else { + this.internalAppend(c); + } + } + + @Override + public void print(char[] ca) { + if (!isLoggingEnabled()) { + super.print(ca); + } else { + this.internalPrint(ca); + } + } + + private void internalPrint(char[] ca) { + final String s = new String(ca); + this.internalAppend(s, 0, s.length()); + } + + @Override + public void print(double d) { + if (!isLoggingEnabled()) { + super.print(d); + } else { + this.internalPrint(d); + } + } + + private void internalPrint(double d) { + entryBuilders.get().append(d); + } + + @Override + public void print(float f) { + if (!isLoggingEnabled()) { + super.print(f); + } else { + this.internalPrint(f); + } + } + + private void internalPrint(float f) { + entryBuilders.get().append(f); + } + + @Override + public void print(int i) { + if (!isLoggingEnabled()) { + super.print(i); + } else { + this.internalPrint(i); + } + } + + private void internalPrint(int i) { + entryBuilders.get().append(i); + } + + @Override + public void print(long l) { + if (!isLoggingEnabled()) { + super.print(l); + } else { + this.internalPrint(l); + } + } + + private void internalPrint(long l) { + entryBuilders.get().append(l); + } + + @Override + public void print(Object obj) { + if (!isLoggingEnabled()) { + super.print(obj); + } else { + this.internalPrint(obj); + } + } + + private void internalPrint(Object obj) { + if (obj == null) { + entryBuilders.get().append(NULL_STRING); + } else { + internalPrint(obj.toString().toCharArray()); + } + } + + @Override + public void print(String s) { + if (!isLoggingEnabled()) { + super.print(s); + } else { + this.internalPrint(s); + } + } + private void internalPrint(String s) { + if (s == null) { + s = NULL_STRING; + } + this.internalAppend(s, 0, s.length()); + } + + @Override + public PrintStream printf(Locale l, String format, Object... args) { + if (!isLoggingEnabled()) { + super.printf(l, format, args); + } else { + this.internalPrint(String.format(l, format, args)); + } + return this; + } + + @Override + public PrintStream printf(String format, Object... args) { + if (!isLoggingEnabled()) { + super.printf(format, args); + } else { + this.internalPrint(String.format(format, args)); + } + return this; + } + + @Override + public void println() { + if (!isLoggingEnabled()) { + super.println(); + } else { + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(boolean x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(char x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalAppend(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(char[] x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(double x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(float x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(int x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(long x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(Object x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + public void println(String x) { + if (!isLoggingEnabled()) { + super.println(x); + } else { + this.internalPrint(x); + createEntryAndLog(entryBuilders.get()); + } + } + + @Override + protected void setError() { + if (!isLoggingEnabled()) { + super.setError(); + } + } + + @Override + public void write(byte[] buf, int off, int len) { + if (!isLoggingEnabled()) { + super.write(buf, off, len); + } else { + byte[] outputBytes = new byte[len]; + System.arraycopy(buf, off, outputBytes, 0, len); + this.internalPrint(new String(outputBytes)); + } + } + + @Override + public void write(int b) { + if (!isLoggingEnabled()) { + super.write(b); + } else { + if (b == '\n' || b == '\r') { + createEntryAndLog(entryBuilders.get()); + } else { + entryBuilders.get().append(new String(new byte[] {(byte)b})); + } + } + } + + private void createEntryAndLog(final StringBuilder stringBuilder) { + final String string = stringBuilder.toString(); + switch (this.loggingLevel) { + case DEBUG: this.logger.debug(string); break; + case ERROR: this.logger.error(string); break; + case INFO: this.logger.info(string); break; + case WARNING: this.logger.warn(string); break; + } + entryBuilders.remove(); + } + + private boolean isLoggingEnabled() { + return isEnabledInConfiguration() && !isWithinLogback(); + } + + private boolean isWithinLogback() { + Class<?>[] executionStack = this.executionStackAccessor.getExecutionStack(); + + for (Class<?> clazz : executionStack) { + Package pkg = clazz.getPackage(); + if (pkg != null) { + String pkgName = pkg.getName(); + if (pkgName != null && pkgName.startsWith(LOGBACK_PACKAGE_NAME_PREFIX)) { + return true; + } + } + } + + return false; + } + + private boolean isEnabledInConfiguration() { + return Boolean.valueOf((String)this.configurationProvider.getConfiguration().get(this.configurationProperty)); + } + + public PrintStream getOriginalPrintStream() { + return this.originalPrintStream; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/PackageNameFilteringClassSelector.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/PackageNameFilteringClassSelector.java new file mode 100644 index 0000000..ba2752d --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/PackageNameFilteringClassSelector.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import java.util.List; + +public final class PackageNameFilteringClassSelector implements ClassSelector { + + private final List<String> loggingPackages; + + public PackageNameFilteringClassSelector(List<String> loggingPackages) { + this.loggingPackages = loggingPackages; + } + + public Class<?> select(Class<?>[] classes) { + for (Class<?> clazz : classes) { + Package pkg = clazz.getPackage(); + if (pkg != null && !this.loggingPackages.contains(pkg.getName())) { + return clazz; + } + } + return null; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/SecurityManagerExecutionStackAccessor.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/SecurityManagerExecutionStackAccessor.java new file mode 100644 index 0000000..865a287 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/SecurityManagerExecutionStackAccessor.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +public final class SecurityManagerExecutionStackAccessor extends SecurityManager implements ExecutionStackAccessor { + + public Class<?>[] getExecutionStack() { + Class<?>[] classes = super.getClassContext(); + Class<?>[] executionStack = new Class<?>[classes.length - 1]; + + System.arraycopy(classes, 1, executionStack, 0, executionStack.length); + + return executionStack; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/StandardCallingBundleResolver.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/StandardCallingBundleResolver.java new file mode 100644 index 0000000..370221e --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/StandardCallingBundleResolver.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import org.osgi.framework.Bundle; +import org.osgi.service.packageadmin.PackageAdmin; + +public final class StandardCallingBundleResolver implements CallingBundleResolver { + + private final ExecutionStackAccessor stackAccessor; + + private final ClassSelector classSelector; + + private final PackageAdmin packageAdmin; + + public StandardCallingBundleResolver(ExecutionStackAccessor stackAccessor, ClassSelector classSelector, PackageAdmin packageAdmin) { + this.stackAccessor = stackAccessor; + this.classSelector = classSelector; + this.packageAdmin = packageAdmin; + } + + public Bundle getCallingBundle() { + Class<?>[] executionStack = this.stackAccessor.getExecutionStack(); + Class<?> loggingCallersClass = classSelector.select(executionStack); + return this.packageAdmin.getBundle(loggingCallersClass); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/StandardDelegatingPrintStream.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/StandardDelegatingPrintStream.java new file mode 100644 index 0000000..908a939 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/StandardDelegatingPrintStream.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Locale; + +import org.eclipse.virgo.medic.log.DelegatingPrintStream; + + +/** + * Standard implementation of {@link DelegatingPrintStream}. + * + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * + * Thread-safe + * + */ +public final class StandardDelegatingPrintStream extends PrintStream implements DelegatingPrintStream { + + private static final PrintStream NO_OP_PRINT_STREAM = new PrintStream(new NoOpOutputStream()); + + private volatile PrintStream delegate; + + /** + * Creates a new <code>StandardDelegatingPrintStream</code> that will delegate to the given <code>delegate</code>. + * + * @param delegate The delegate + */ + public StandardDelegatingPrintStream(PrintStream delegate) { + super(new NoOpOutputStream()); + setDelegate(delegate); + } + + public void setDelegate(PrintStream printStream) { + if (printStream == null) { + this.delegate = NO_OP_PRINT_STREAM; + } else { + this.delegate = printStream; + } + } + + public PrintStream append(char c) { + return delegate.append(c); + } + + public PrintStream append(CharSequence csq, int start, int end) { + return delegate.append(csq, start, end); + } + + public PrintStream append(CharSequence csq) { + return delegate.append(csq); + } + + public boolean checkError() { + return delegate.checkError(); + } + + public void close() { + delegate.close(); + } + + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + public void flush() { + delegate.flush(); + } + + public PrintStream format(Locale l, String format, Object... args) { + return delegate.format(l, format, args); + } + + public PrintStream format(String format, Object... args) { + return delegate.format(format, args); + } + + public int hashCode() { + return delegate.hashCode(); + } + + public void print(boolean b) { + delegate.print(b); + } + + public void print(char c) { + delegate.print(c); + } + + public void print(char[] s) { + delegate.print(s); + } + + public void print(double d) { + delegate.print(d); + } + + public void print(float f) { + delegate.print(f); + } + + public void print(int i) { + delegate.print(i); + } + + public void print(long l) { + delegate.print(l); + } + + public void print(Object obj) { + delegate.print(obj); + } + + public void print(String s) { + delegate.print(s); + } + + public PrintStream printf(Locale l, String format, Object... args) { + return delegate.printf(l, format, args); + } + + public PrintStream printf(String format, Object... args) { + return delegate.printf(format, args); + } + + public void println() { + delegate.println(); + } + + public void println(boolean x) { + delegate.println(x); + } + + public void println(char x) { + delegate.println(x); + } + + public void println(char[] x) { + delegate.println(x); + } + + public void println(double x) { + delegate.println(x); + } + + public void println(float x) { + delegate.println(x); + } + + public void println(int x) { + delegate.println(x); + } + + public void println(long x) { + delegate.println(x); + } + + public void println(Object x) { + delegate.println(x); + } + + public void println(String x) { + delegate.println(x); + } + + public String toString() { + return delegate.toString(); + } + + public void write(byte[] buf, int off, int len) { + delegate.write(buf, off, len); + } + + public void write(byte[] b) throws IOException { + delegate.write(b); + } + + public void write(int b) { + delegate.write(b); + } + + private static final class NoOpOutputStream extends OutputStream { + + public void write(int b) throws IOException { + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/BundleResourceConfigurationLocator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/BundleResourceConfigurationLocator.java new file mode 100644 index 0000000..6039f7d --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/BundleResourceConfigurationLocator.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import java.io.IOException; +import java.net.URL; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.osgi.framework.Bundle; + + +public final class BundleResourceConfigurationLocator implements ConfigurationLocator { + + public LoggingConfiguration locateConfiguration(Bundle bundle) { + if (bundle != null) { + URL logBackConfigurationEntry = bundle.getResource("logback.xml"); + + if (logBackConfigurationEntry == null) { + logBackConfigurationEntry = bundle.getResource("logback-default.xml"); + } + + if (logBackConfigurationEntry != null) { + try { + return new StandardLoggingConfiguration(logBackConfigurationEntry, createContextName(bundle)); + } catch (IOException ioe) { + // TODO Exception handling + } + } + } + + return null; + } + + private static String createContextName(Bundle bundle) { + return bundle.getSymbolicName() + "_" + bundle.getVersion(); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/CompositeConfigurationLocator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/CompositeConfigurationLocator.java new file mode 100644 index 0000000..dec1524 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/CompositeConfigurationLocator.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.osgi.framework.Bundle; + + +public final class CompositeConfigurationLocator implements ConfigurationLocator { + + private final List<ConfigurationLocator> configurationLocators; + + public CompositeConfigurationLocator(ConfigurationLocator... configurationLocators) { + this.configurationLocators = Arrays.asList(configurationLocators); + } + + public LoggingConfiguration locateConfiguration(Bundle bundle) { + for (ConfigurationLocator configurationLocator : this.configurationLocators) { + LoggingConfiguration configuration = configurationLocator.locateConfiguration(bundle); + if (configuration != null) { + return configuration; + } + } + return null; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ConfigurationLocator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ConfigurationLocator.java new file mode 100644 index 0000000..921ade7 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ConfigurationLocator.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.osgi.framework.Bundle; + + +public interface ConfigurationLocator { + + LoggingConfiguration locateConfiguration(Bundle bundle); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ServiceReferenceUtils.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ServiceReferenceUtils.java new file mode 100644 index 0000000..1bb8d9a --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ServiceReferenceUtils.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import org.osgi.framework.ServiceReference; + +class ServiceReferenceUtils { + + static ServiceReference selectServiceReference(ServiceReference[] serviceReferences) { + ServiceReference highest = null; + + for (ServiceReference serviceReference : serviceReferences) { + if (highest == null || serviceReference.compareTo(highest) > 0) { + highest = serviceReference; + } + } + + return highest; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ServiceRegistryConfigurationLocator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ServiceRegistryConfigurationLocator.java new file mode 100644 index 0000000..01a52e5 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/ServiceRegistryConfigurationLocator.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + + +public final class ServiceRegistryConfigurationLocator implements ConfigurationLocator { + + private final BundleContext bundleContext; + + static final String LOGGING_CONFIGURATION_ID_SERVICE_PROPERTY = "org.eclipse.virgo.medic.log.configuration.id"; + + private static final String MEDIC_LOGGING_CONFIGURATION_HEADER = "Medic-LoggingConfiguration"; + + public ServiceRegistryConfigurationLocator(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public LoggingConfiguration locateConfiguration(Bundle bundle) { + if (bundle != null) { + String configurationName = (String) bundle.getHeaders().get(MEDIC_LOGGING_CONFIGURATION_HEADER); + + if (configurationName != null) { + try { + ServiceReference[] serviceReferences = this.bundleContext.getServiceReferences(LoggingConfiguration.class.getName(), "(" + + LOGGING_CONFIGURATION_ID_SERVICE_PROPERTY + "=" + configurationName + ")"); + if (serviceReferences != null && serviceReferences.length > 0) { + ServiceReference serviceReference = ServiceReferenceUtils.selectServiceReference(serviceReferences); + return (LoggingConfiguration) this.bundleContext.getService(serviceReference); + } + } catch (InvalidSyntaxException ise) { + + } + } + } + + return null; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfiguration.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfiguration.java new file mode 100644 index 0000000..7e74f91 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfiguration.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; + + +class StandardLoggingConfiguration implements LoggingConfiguration { + + private final String configuration; + + private final String name; + + StandardLoggingConfiguration(URL configuration, String name) throws IOException { + this(readConfiguration(configuration), name); + } + + StandardLoggingConfiguration(File configuration, String name) throws IOException { + this(readConfiguration(configuration), name); + } + + private StandardLoggingConfiguration(String configuration, String name) { + this.configuration = configuration; + this.name = name; + } + + public String getConfiguration() { + return this.configuration; + } + + public String getName() { + return this.name; + } + + private static String readConfiguration(URL configURL) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(configURL.openStream())); + return readConfiguration(reader); + } finally { + if (reader != null) { + reader.close(); + } + } + } + + private static String readConfiguration(File configFile) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(configFile)); + return readConfiguration(reader); + } finally { + if (reader != null) { + reader.close(); + } + } + } + + private static String readConfiguration(BufferedReader reader) throws IOException { + StringBuilder configurationBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + configurationBuilder.append(line); + } + return configurationBuilder.toString(); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfigurationPublisher.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfigurationPublisher.java new file mode 100644 index 0000000..3472dc7 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfigurationPublisher.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import java.io.File; +import java.io.IOException; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.eclipse.virgo.medic.log.ConfigurationPublicationFailedException; +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher; +import org.osgi.framework.BundleContext; + + +public class StandardLoggingConfigurationPublisher implements LoggingConfigurationPublisher { + + private final BundleContext context; + + private static final String DEFAULT_CONFIGURATION_ID = "org.eclipse.virgo.medic"; + + public StandardLoggingConfigurationPublisher(BundleContext context) { + this.context = context; + } + + public void publishConfiguration(File configuration, String id) throws ConfigurationPublicationFailedException { + LoggingConfiguration loggingConfiguration = createLoggingConfiguration(configuration, id); + Dictionary<String, String> properties = new Hashtable<String, String>(); + + properties.put(ServiceRegistryConfigurationLocator.LOGGING_CONFIGURATION_ID_SERVICE_PROPERTY, id); + context.registerService(LoggingConfiguration.class.getName(), loggingConfiguration, properties); + } + + private static LoggingConfiguration createLoggingConfiguration(File configuration, String id) throws ConfigurationPublicationFailedException { + try { + return new StandardLoggingConfiguration(configuration, id); + } catch (IOException ioe) { + throw new ConfigurationPublicationFailedException("Failed to read the configuration from the file '" + configuration.getAbsolutePath() + + "'.", ioe); + } + } + + public void publishDefaultConfiguration(File file) throws ConfigurationPublicationFailedException { + publishConfiguration(file, DEFAULT_CONFIGURATION_ID); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/ContextSelectorDelegate.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/ContextSelectorDelegate.java new file mode 100644 index 0000000..cbf8662 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/ContextSelectorDelegate.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import java.util.List; + +import ch.qos.logback.classic.LoggerContext; + +public interface ContextSelectorDelegate { + + LoggerContext getLoggerContext(); + + LoggerContext getLoggerContext(String name); + + LoggerContext detachLoggerContext(String loggerContextName); + + List<String> getContextNames(); + + void configureDefaultContext(LoggerContext defaultContext); +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/DelegatingContextSelector.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/DelegatingContextSelector.java new file mode 100644 index 0000000..f76f555 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/DelegatingContextSelector.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import java.util.Arrays; +import java.util.List; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.selector.ContextSelector; + +public class DelegatingContextSelector implements ContextSelector { + + private static volatile ContextSelectorDelegate delegate; + + private static volatile LoggerContext defaultLoggerContext; + + private static volatile boolean defaultContextConfigured; + + public DelegatingContextSelector(LoggerContext loggerContext) { + DelegatingContextSelector.setDefaultLoggerContext(loggerContext); + } + + private static void setDefaultLoggerContext(LoggerContext loggerContext) { + if (delegate != null) { + configureDefaultContextIfNecessary(delegate, loggerContext); + } + DelegatingContextSelector.defaultLoggerContext = loggerContext; + } + + private static void configureDefaultContextIfNecessary(ContextSelectorDelegate delegate, LoggerContext defaultLoggerContext) { + if (!defaultContextConfigured) { + delegate.configureDefaultContext(defaultLoggerContext); + defaultContextConfigured = true; + } + } + + public LoggerContext detachLoggerContext(String loggerContextName) { + if (delegate == null) { + return DelegatingContextSelector.defaultLoggerContext; + } + return delegate.detachLoggerContext(loggerContextName); + } + + public List<String> getContextNames() { + if (delegate == null) { + return Arrays.asList(defaultLoggerContext.getName()); + } + return delegate.getContextNames(); + } + + public LoggerContext getDefaultLoggerContext() { + return DelegatingContextSelector.defaultLoggerContext; + } + + public LoggerContext getLoggerContext() { + if (delegate == null) { + return defaultLoggerContext; + } + + LoggerContext loggerContext = delegate.getLoggerContext(); + if (loggerContext != null) { + return loggerContext; + } + + return defaultLoggerContext; + } + + public LoggerContext getLoggerContext(String name) { + if (name.equals(defaultLoggerContext.getName())) { + return defaultLoggerContext; + } + return delegate.getLoggerContext(name); + } + + public static void setDelegate(ContextSelectorDelegate delegate) { + if (delegate != null) { + if (defaultLoggerContext != null) { + configureDefaultContextIfNecessary(delegate, defaultLoggerContext); + } + } + DelegatingContextSelector.delegate = delegate; + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/JoranLoggerContextConfigurer.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/JoranLoggerContextConfigurer.java new file mode 100644 index 0000000..3eb52c9 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/JoranLoggerContextConfigurer.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.xml.sax.InputSource; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.joran.spi.JoranException; +import ch.qos.logback.core.status.Status; + + +public final class JoranLoggerContextConfigurer implements LoggerContextConfigurer { + + public void applyConfiguration(LoggingConfiguration configuration, LoggerContext loggerContext) throws LoggerContextConfigurationFailedException { + JoranConfigurator configurator = new JoranConfigurator(); + configurator.setContext(loggerContext); + String configurationString = configuration.getConfiguration(); + try { + configurator.doConfigure(new InputSource(new StringReader(configurationString))); + List<Status> statusList = loggerContext.getStatusManager().getCopyOfStatusList(); + List<String> failureMessages = new ArrayList<String>(); + for (Status status : statusList) { + if (Status.INFO != status.getLevel()) { + failureMessages.add(status.getMessage()); + } + } + reportFailureIfNecessary(failureMessages); + } catch (JoranException je) { + throw new LoggerContextConfigurationFailedException("Configuration failed", je); + } + } + + private static void reportFailureIfNecessary(List<String> failureMessages) throws LoggerContextConfigurationFailedException { + if (!failureMessages.isEmpty()) { + throw new LoggerContextConfigurationFailedException("Configuration failed with the following problems: " + failureMessages); + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggerContextConfigurationFailedException.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggerContextConfigurationFailedException.java new file mode 100644 index 0000000..f4daea8 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggerContextConfigurationFailedException.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +class LoggerContextConfigurationFailedException extends Exception { + + private static final long serialVersionUID = -4259913727730630284L; + + public LoggerContextConfigurationFailedException(String message) { + super(message); + } + + public LoggerContextConfigurationFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggerContextConfigurer.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggerContextConfigurer.java new file mode 100644 index 0000000..653cd59 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggerContextConfigurer.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; + +import ch.qos.logback.classic.LoggerContext; + + +public interface LoggerContextConfigurer { + + void applyConfiguration(LoggingConfiguration configuration, LoggerContext loggerContext) throws LoggerContextConfigurationFailedException; +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/StandardContextSelectorDelegate.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/StandardContextSelectorDelegate.java new file mode 100644 index 0000000..e7992d5 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/impl/logback/StandardContextSelectorDelegate.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.impl.CallingBundleResolver; +import org.eclipse.virgo.medic.log.impl.config.ConfigurationLocator; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.BundleListener; + +import ch.qos.logback.classic.LoggerContext; + + +public class StandardContextSelectorDelegate implements ContextSelectorDelegate, BundleListener { + + private final CallingBundleResolver loggingCallerLocator; + + private final Map<String, LoggerContext> loggerContexts = new HashMap<String, LoggerContext>(); + + private final Map<Bundle, LoggingConfiguration> loggingConfigurations = new WeakHashMap<Bundle, LoggingConfiguration>(); + + private final Object monitor = new Object(); + + private final ConfigurationLocator configurationLocator; + + private final LoggerContextConfigurer configurer; + + private final Bundle medicBundle; + + public StandardContextSelectorDelegate(CallingBundleResolver loggingCallerLocator, ConfigurationLocator configurationLocator, Bundle medicBundle, + LoggerContextConfigurer configurer) { + this.loggingCallerLocator = loggingCallerLocator; + this.configurationLocator = configurationLocator; + this.medicBundle = medicBundle; + this.configurer = configurer; + } + + public LoggerContext detachLoggerContext(String name) { + synchronized (monitor) { + return this.loggerContexts.remove(name); + } + } + + public List<String> getContextNames() { + synchronized (this.monitor) { + List<String> names = new ArrayList<String>(); + names.addAll(this.loggerContexts.keySet()); + return names; + } + } + + public LoggerContext getLoggerContext() { + Bundle callingBundle = this.loggingCallerLocator.getCallingBundle(); + + LoggingConfiguration loggingConfiguration = null; + + if (callingBundle != null) { + synchronized(this.monitor) { + loggingConfiguration = this.loggingConfigurations.get(callingBundle); + } + } + + if (loggingConfiguration == null) { + loggingConfiguration = locateConfiguration(callingBundle); + if (loggingConfiguration != null && callingBundle != null) { + synchronized(this.monitor) { + this.loggingConfigurations.put(callingBundle, loggingConfiguration); + } + } + } + + if (loggingConfiguration != null) { + synchronized (this.monitor) { + LoggerContext existingContext = this.loggerContexts.get(loggingConfiguration.getName()); + if (existingContext != null) { + return existingContext; + } else { + LoggerContext configuredContext = createConfiguredContext(loggingConfiguration); + this.loggerContexts.put(loggingConfiguration.getName(), configuredContext); + return configuredContext; + } + } + } + + return null; + } + + private LoggingConfiguration locateConfiguration(Bundle callingBundle) { + return this.configurationLocator.locateConfiguration(callingBundle); + } + + private LoggerContext createConfiguredContext(LoggingConfiguration configuration) { + LoggerContext loggerContext = new LoggerContext(); + loggerContext.setName(configuration.getName()); + + try { + this.configurer.applyConfiguration(configuration, loggerContext); + } catch (LoggerContextConfigurationFailedException lccfe) { + lccfe.printStackTrace(System.err); + } + + return loggerContext; + } + + public LoggerContext getLoggerContext(String name) { + synchronized (monitor) { + return this.loggerContexts.get(name); + } + } + + public void configureDefaultContext(LoggerContext defaultContext) { + LoggingConfiguration configuration = locateConfiguration(this.medicBundle); + + if (configuration != null) { + defaultContext.reset(); + try { + this.configurer.applyConfiguration(configuration, defaultContext); + } catch (LoggerContextConfigurationFailedException lccfe) { + lccfe.printStackTrace(System.err); + } + } + } + + public void bundleChanged(BundleEvent event) { + if (BundleEvent.UPDATED == event.getType()) { + synchronized (this.monitor) { + this.loggingConfigurations.remove(event.getBundle()); + } + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/logback/ReroutingAwareConsoleAppender.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/logback/ReroutingAwareConsoleAppender.java new file mode 100644 index 0000000..0463c47 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/log/logback/ReroutingAwareConsoleAppender.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.logback; + +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import org.eclipse.virgo.medic.log.impl.LoggingPrintStreamWrapper; + +import ch.qos.logback.core.ConsoleAppender; + + +/** + * A special {@link ConsoleAppender} that is aware of re-routing of <code>System.out</code> and <code>System.err</code> + * and will always use the original <code>System.out</code> and <code>System.err</code>, rather than the ones that are being rerouted. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * + * Thread-safe. + * + * @param <E> Event type being logged + */ +public class ReroutingAwareConsoleAppender<E> extends ConsoleAppender<E> { + + protected OutputStreamWriter createWriter(OutputStream os) { + if (os instanceof LoggingPrintStreamWrapper) { + return super.createWriter(((LoggingPrintStreamWrapper)os).getOriginalPrintStream()); + } else { + return super.createWriter(os); + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/main/resources/EventLogMessages_en.properties b/org.eclipse.virgo.medic.core/src/main/resources/EventLogMessages_en.properties new file mode 100644 index 0000000..5931f9d --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/resources/EventLogMessages_en.properties @@ -0,0 +1,3 @@ +ME0001W=The directory '{}' does not exist and could not be created +ME0002W=Dump contributor '{}' failed during contribution to dump '{}' +ME0003I=Dump '{}' generated diff --git a/org.eclipse.virgo.medic.core/src/main/resources/logback-default.xml b/org.eclipse.virgo.medic.core/src/main/resources/logback-default.xml new file mode 100644 index 0000000..cbd6eb2 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/main/resources/logback-default.xml @@ -0,0 +1,39 @@ +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="EVENT_LOG_STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread <%X{medic.eventCode}> %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="EVENT_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>serviceability/eventlog/eventlog.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <FileNamePattern>serviceability/eventlog/eventlog_%i.log</FileNamePattern> + <MinIndex>1</MinIndex> + <MaxIndex>4</MaxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <MaxFileSize>10MB</MaxFileSize> + </triggeringPolicy> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread <%X{medic.eventCode}> %msg %ex%n</Pattern> + </layout> + </appender> + + <logger name="org.eclipse.virgo.medic.eventlog.localized"> + <appender-ref ref="EVENT_LOG_STDOUT" /> + <appender-ref ref="EVENT_LOG_FILE" /> + </logger> + + <root level="debug"> + <appender-ref ref="STDOUT" /> + </root> + +</configuration> diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/DumpContributorTrackerTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/DumpContributorTrackerTests.java new file mode 100644 index 0000000..bbf5f7b --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/DumpContributorTrackerTests.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import static org.easymock.EasyMock.createMock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import java.util.List; + +import org.junit.Test; +import org.osgi.framework.ServiceRegistration; + +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.impl.DumpContributorTracker; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext; + +public class DumpContributorTrackerTests { + + @Test + public void serviceAdditionAndRemoval() { + StubBundleContext bundleContext = new StubBundleContext(); + DumpContributor service = createMock(DumpContributor.class); + ServiceRegistration serviceRegistration = bundleContext.registerService(DumpContributor.class.getName(), service, null); + + DumpContributorTracker tracker = new DumpContributorTracker(bundleContext); + + tracker.addingService(serviceRegistration.getReference()); + List<DumpContributor> contributors = tracker.getDumpContributors(); + assertEquals(1, contributors.size()); + assertSame(service, contributors.get(0)); + + tracker.removedService(serviceRegistration.getReference(), service); + contributors = tracker.getDumpContributors(); + assertEquals(0, contributors.size()); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/HeapDumpContributorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/HeapDumpContributorTests.java new file mode 100644 index 0000000..08042c8 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/HeapDumpContributorTests.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.impl.heap.HeapDumpContributor; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class HeapDumpContributorTests { + + private final File dumpDirectory = new File("target"); + + @Before + @After + public void cleanupHeadDumps() { + File heapDumpFile = new File("target", "heap.out"); + if (heapDumpFile.exists()) { + assertTrue(heapDumpFile.delete()); + } + } + + @Test + public void dumpHeap() throws DumpContributionFailedException { + DumpContributor contributor = new HeapDumpContributor(); + + String cause = "failure"; + long timestamp = System.currentTimeMillis(); + Map<String, Object> context = new HashMap<String, Object>(); + + Dump dump = new StubDump(cause, timestamp, context, new Throwable[0], dumpDirectory); + + contributor.contribute(dump); + + boolean managementFactoryAvailable; + + try { + Class.forName("sun.management.ManagementFactory").getMethod("getDiagnosticMXBean"); + managementFactoryAvailable = true; + } catch (Exception e) { + managementFactoryAvailable = false; + } + + assertEquals(managementFactoryAvailable, new File(this.dumpDirectory, "heap.out").exists()); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/StandardDumpGeneratorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/StandardDumpGeneratorTests.java new file mode 100644 index 0000000..be37e8b --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/StandardDumpGeneratorTests.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +import java.util.Arrays; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.DumpGenerationFailedException; +import org.eclipse.virgo.medic.dump.DumpGenerator; +import org.eclipse.virgo.medic.dump.impl.DumpContributorResolver; +import org.eclipse.virgo.medic.dump.impl.StandardDumpGenerator; +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.junit.Test; + + +public class StandardDumpGeneratorTests { + + @Test + public void dumpGeneration() throws DumpGenerationFailedException { + + Map<String, Object> context = new HashMap<String, Object>(); + + EventLogger eventLogger = createMock(EventLogger.class); + + DumpContributorResolver accessor = createMock(DumpContributorResolver.class); + DumpContributor dumpContributor1 = createMock(DumpContributor.class); + + expect(accessor.getDumpContributors()).andReturn(Arrays.asList(dumpContributor1)); + dumpContributor1.contribute(isA(Dump.class)); + expectLastCall(); + + context = new HashMap<String, Object>(); + context.put("key", "value"); + + dumpContributor1.contribute(isA(Dump.class)); + expect(dumpContributor1.getName()).andReturn("dc1").anyTimes(); + + DumpContributor dumpContributor2 = createMock(DumpContributor.class); + dumpContributor2.contribute(isA(Dump.class)); + expect(dumpContributor2.getName()).andReturn("dc2").anyTimes(); + + expect(accessor.getDumpContributors()).andReturn(Arrays.asList(dumpContributor1, dumpContributor2)); + + ConfigurationProvider configurationProvider = createMock(ConfigurationProvider.class); + Dictionary<Object, Object> configuration = new Hashtable<Object, Object>(); + configuration.put(ConfigurationProvider.KEY_DUMP_ROOT_DIRECTORY, "target"); + expect(configurationProvider.getConfiguration()).andReturn(configuration).anyTimes(); + + replay(accessor, dumpContributor1, dumpContributor2, configurationProvider); + + DumpGenerator dumpGenerator = new StandardDumpGenerator(accessor, configurationProvider, eventLogger); + dumpGenerator.generateDump("foo"); + dumpGenerator.generateDump("bar", context); + + verify(accessor, dumpContributor1, dumpContributor2, configurationProvider); + } + + @Test + public void singleExclusion() throws DumpGenerationFailedException { + EventLogger eventLogger = createMock(EventLogger.class); + DumpContributorResolver accessor = createMock(DumpContributorResolver.class); + DumpContributor dumpContributor1 = createMock(DumpContributor.class); + + expect(accessor.getDumpContributors()).andReturn(Arrays.asList(dumpContributor1)).times(2); + dumpContributor1.contribute(isA(Dump.class)); + expect(dumpContributor1.getName()).andReturn("dc1").times(2); + + ConfigurationProvider configurationProvider = createMock(ConfigurationProvider.class); + Dictionary<Object, Object> configuration = new Hashtable<Object, Object>(); + configuration.put("dump.root.directory", "target"); + configuration.put("dump.exclusions.foo", "dc1"); + expect(configurationProvider.getConfiguration()).andReturn(configuration).anyTimes(); + + replay(accessor, dumpContributor1, configurationProvider); + + DumpGenerator dumpGenerator = new StandardDumpGenerator(accessor, configurationProvider, eventLogger); + dumpGenerator.generateDump("foo"); + dumpGenerator.generateDump("bar"); + + verify(accessor, dumpContributor1, configurationProvider); + } + + @Test + public void multipleExclusion() throws DumpGenerationFailedException { + EventLogger eventLogger = createMock(EventLogger.class); + DumpContributorResolver accessor = createMock(DumpContributorResolver.class); + DumpContributor dumpContributor1 = createMock(DumpContributor.class); + DumpContributor dumpContributor2 = createMock(DumpContributor.class); + + expect(accessor.getDumpContributors()).andReturn(Arrays.asList(dumpContributor1, dumpContributor2)).times(2); + dumpContributor1.contribute(isA(Dump.class)); + dumpContributor2.contribute(isA(Dump.class)); + expect(dumpContributor1.getName()).andReturn("dc1").times(2); + expect(dumpContributor2.getName()).andReturn("dc2").times(2); + + ConfigurationProvider configurationProvider = createMock(ConfigurationProvider.class); + Dictionary<Object, Object> configuration = new Hashtable<Object, Object>(); + configuration.put("dump.root.directory", "target"); + configuration.put("dump.exclusions.foo", "dc1, dc2"); + expect(configurationProvider.getConfiguration()).andReturn(configuration).anyTimes(); + + replay(accessor, dumpContributor1, dumpContributor2, configurationProvider); + + DumpGenerator dumpGenerator = new StandardDumpGenerator(accessor, configurationProvider, eventLogger); + dumpGenerator.generateDump("foo"); + dumpGenerator.generateDump("bar"); + + verify(accessor, dumpContributor1, dumpContributor2, configurationProvider); + } + + @Test + public void close() { + EventLogger eventLogger = createMock(EventLogger.class); + DumpContributorResolver accessor = createMock(DumpContributorResolver.class); + ConfigurationProvider configurationProvider = createMock(ConfigurationProvider.class); + accessor.close(); + + replay(accessor, configurationProvider); + + StandardDumpGenerator dumpGenerator = new StandardDumpGenerator(accessor, configurationProvider, eventLogger); + dumpGenerator.close(); + + verify(accessor, configurationProvider); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/StubDump.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/StubDump.java new file mode 100644 index 0000000..fc88eca --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/StubDump.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; + + +public class StubDump implements Dump { + + private final File outputDirectory; + + private final String cause; + + private final Map<String, Object> context; + + private final Throwable[] throwables; + + private final long timestamp; + + public StubDump(String cause, long timestamp, Map<String, Object> context, Throwable[] throwables, File outputDirectory) { + this.cause = cause; + this.timestamp = timestamp; + this.context = context; + this.throwables = throwables; + this.outputDirectory = outputDirectory; + } + + public File createFile(String name) { + return new File(outputDirectory, name); + } + + public FileOutputStream createFileOutputStream(String name) throws DumpContributionFailedException { + try { + return new FileOutputStream(createFile(name)); + } catch (FileNotFoundException e) { + throw new DumpContributionFailedException("Unable to open output stream '" + name + "'"); + } + } + + public FileWriter createFileWriter(String name) throws DumpContributionFailedException { + try { + return new FileWriter(createFile(name)); + } catch (IOException e) { + throw new DumpContributionFailedException("Unable to open file writer '" + name + "'"); + } + } + + public String getCause() { + return this.cause; + } + + public Map<String, Object> getContext() { + return this.context; + } + + public Throwable[] getThrowables() { + return this.throwables; + } + + public long getTimestamp() { + return this.timestamp; + } + +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/logback/LogDumpContributorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/logback/LogDumpContributorTests.java new file mode 100644 index 0000000..8a5e369 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/logback/LogDumpContributorTests.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.logback; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collections; +import java.util.Date; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.impl.logback.LogDumpContributor; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.junit.Test; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Level; + +import ch.qos.logback.classic.Logger; + + +public class LogDumpContributorTests { + + @Test + public void emptyLog() throws DumpContributionFailedException { + LogDumpContributor contributor = getContributor(); + StubDump dump = getDump(); + contributor.contribute(dump); + + File logFile = dump.createFile("log.log"); + assertTrue(logFile.exists()); + assertEquals(0, logFile.length()); + } + + @Test + public void nonEmptyLog() throws DumpContributionFailedException { + LogDumpContributor contributor = getContributor(); + StubDump dump = getDump(); + + driveLogging(contributor); + + contributor.contribute(dump); + + File logFile = dump.createFile("log.log"); + assertTrue(logFile.exists()); + assertEquals(1, countLines(logFile)); + } + + @Test + public void wrappedLog() throws DumpContributionFailedException { + LogDumpContributor contributor = getContributor(); + StubDump dump = getDump(); + driveLogging(contributor); + driveLogging(contributor); + driveLogging(contributor); + + contributor.contribute(dump); + + File logFile = dump.createFile("log.log"); + assertTrue(logFile.exists()); + assertEquals(2, countLines(logFile)); + } + + private LogDumpContributor getContributor() { + LogDumpContributor contributor = new LogDumpContributor(new StaticConfigurationProvider()); + return contributor; + } + + private StubDump getDump() { + File dumpRoot = new File("target/serviceability/dump"); + dumpRoot.mkdirs(); + return new StubDump("testCause", new Date().getTime(), Collections.<String, Object> emptyMap(), new Throwable[0], dumpRoot); + } + + private int countLines(File logFile) { + BufferedReader reader = null; + int count = 0; + try { + reader = new BufferedReader(new FileReader(logFile)); + while (reader.readLine() != null) { + count++; + } + } catch (FileNotFoundException e) { + } catch (IOException e) { + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + } + } + + return count; + } + + private static final class StaticConfigurationProvider implements ConfigurationProvider { + @SuppressWarnings("unchecked") + public Dictionary getConfiguration() { + Hashtable configuration = new Hashtable(); + configuration.put(ConfigurationProvider.KEY_LOG_DUMP_LEVEL, "debug"); + configuration.put(ConfigurationProvider.KEY_LOG_DUMP_BUFFERSIZE, "2"); + return configuration; + } + } + + private final void driveLogging(LogDumpContributor loggingContributor) { + loggingContributor.onLogging((Logger)LoggerFactory.getLogger("test"), "com.foo.bar", null, Level.INFO, "test", null, null); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/logback/StubDump.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/logback/StubDump.java new file mode 100644 index 0000000..6890508 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/logback/StubDump.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.logback; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; + + +public class StubDump implements Dump { + + private final File outputDirectory; + + private final String cause; + + private final Map<String, Object> context; + + private final Throwable[] throwables; + + private final long timestamp; + + public StubDump(String cause, long timestamp, Map<String, Object> context, Throwable[] throwables, File outputDirectory) { + this.cause = cause; + this.timestamp = timestamp; + this.context = context; + this.throwables = throwables; + this.outputDirectory = outputDirectory; + } + + public File createFile(String name) { + return new File(outputDirectory, name); + } + + public FileOutputStream createFileOutputStream(String name) throws DumpContributionFailedException { + try { + return new FileOutputStream(createFile(name)); + } catch (FileNotFoundException e) { + throw new DumpContributionFailedException("Unable to open output stream '" + name + "'"); + } + } + + public FileWriter createFileWriter(String name) throws DumpContributionFailedException { + try { + return new FileWriter(createFile(name)); + } catch (IOException e) { + throw new DumpContributionFailedException("Unable to open file writer '" + name + "'"); + } + } + + public String getCause() { + return this.cause; + } + + public Map<String, Object> getContext() { + return this.context; + } + + public Throwable[] getThrowables() { + return this.throwables; + } + + public long getTimestamp() { + return this.timestamp; + } + +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/summary/SummaryDumpContributorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/summary/SummaryDumpContributorTests.java new file mode 100644 index 0000000..5c05b8f --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/summary/SummaryDumpContributorTests.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.summary; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.impl.StubDump; +import org.eclipse.virgo.medic.dump.impl.summary.SummaryDumpContributor; +import org.junit.Test; + + +public class SummaryDumpContributorTests { + + private final DumpContributor dumpContributor = new SummaryDumpContributor(); + + private final File dumpDirectory = new File("target"); + + private final DateFormat dateFormat = DateFormat.getDateInstance(); + + private final DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.LONG); + + @Test + public void dumpWithoutThrowable() throws DumpContributionFailedException, IOException { + + String cause = "failure"; + long timestamp = System.currentTimeMillis(); + Map<String, Object> context = new HashMap<String, Object>(); + + Dump dump = new StubDump(cause, timestamp, context, new Throwable[0], dumpDirectory); + + this.dumpContributor.contribute(dump); + + File dumpFile = new File(dumpDirectory, "summary.txt"); + assertTrue(dumpFile.exists()); + assertDumpContents(dumpFile, timestamp, cause); + } + + @Test + public void dumpWithThrowable() throws DumpContributionFailedException, IOException { + + String cause = "failure"; + long timestamp = System.currentTimeMillis(); + Map<String, Object> context = new HashMap<String, Object>(); + + NullPointerException npe = new NullPointerException(); + npe.fillInStackTrace(); + + Dump dump = new StubDump(cause, timestamp, context, new Throwable[] { npe }, dumpDirectory); + + this.dumpContributor.contribute(dump); + + File dumpFile = new File(dumpDirectory, "summary.txt"); + assertTrue(dumpFile.exists()); + assertDumpContents(dumpFile, timestamp, cause, npe); + } + + private void assertDumpContents(File dumpFile, long timestamp, String cause, Throwable... throwables) throws IOException { + BufferedReader input = new BufferedReader(new FileReader(dumpFile)); + + List<String> lines = new ArrayList<String>(); + + String line; + + while ((line = input.readLine()) != null) { + lines.add(line); + } + + assertDatePresent(lines, timestamp); + assertTimePresent(lines, timestamp); + assertCausePresent(lines, cause); + assertThrowablesPresent(lines, throwables); + } + + private void assertDatePresent(List<String> lines, long timestamp) { + String expectedDate = this.dateFormat.format(new Date(timestamp)); + + for (String line : lines) { + if (line.contains(expectedDate)) { + return; + } + } + + fail(String.format("The date '%s' was not found in the dump", expectedDate)); + } + + private void assertTimePresent(List<String> lines, long timestamp) { + String expectedTime = this.timeFormat.format(new Date(timestamp)); + + for (String line : lines) { + if (line.contains(expectedTime)) { + return; + } + } + + fail(String.format("The time '%s' was not found in the dump", expectedTime)); + } + + private void assertCausePresent(List<String> lines, String cause) { + String expectedCause = "Cause: " + cause; + for (String line : lines) { + if (line.contains(expectedCause)) { + return; + } + } + fail(String.format("The expected cause entry '%s' was not found in the dump", expectedCause)); + } + + private void assertThrowablesPresent(List<String> lines, Throwable... throwables) { + String expectedException; + if (throwables.length == 0) { + expectedException = "Exception: None"; + } else { + expectedException = "Exception:"; + } + + for (String line : lines) { + if (line.equals(expectedException)) { + return; + } + } + fail(String.format("The expected exception entry '%s' was not found in the dump", expectedException)); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadDumpContributorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadDumpContributorTests.java new file mode 100644 index 0000000..480af0f --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/dump/impl/thread/ThreadDumpContributorTests.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.impl.thread; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.virgo.medic.dump.Dump; +import org.eclipse.virgo.medic.dump.DumpContributionFailedException; +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.impl.StubDump; +import org.eclipse.virgo.medic.dump.impl.thread.Java5ThreadInfoWriter; +import org.eclipse.virgo.medic.dump.impl.thread.Java5ThreadMXBeanDelegate; +import org.eclipse.virgo.medic.dump.impl.thread.StandardThreadInfoWriter; +import org.eclipse.virgo.medic.dump.impl.thread.StandardThreadMXBeanDelegate; +import org.eclipse.virgo.medic.dump.impl.thread.ThreadDumpContributor; +import org.junit.Test; + + +public class ThreadDumpContributorTests { + + private final File dumpDirectory = new File("target"); + + @Test + public void java5ThreadDump() throws DumpContributionFailedException { + DumpContributor contributor = new ThreadDumpContributor(new Java5ThreadMXBeanDelegate(), new Java5ThreadInfoWriter()); + createContribution(contributor); + } + + @Test + public void standardThreadDump() throws DumpContributionFailedException { + DumpContributor contributor = new ThreadDumpContributor(new StandardThreadMXBeanDelegate(), new StandardThreadInfoWriter()); + createContribution(contributor); + } + + private void createContribution(DumpContributor contributor) throws DumpContributionFailedException { + String cause = "failure"; + long timestamp = System.currentTimeMillis(); + Map<String, Object> context = new HashMap<String, Object>(); + + Dump dump = new StubDump(cause, timestamp, context, new Throwable[0], this.dumpDirectory); + + contributor.contribute(dump); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/BundleSearchingPropertyResourceBundleResolverTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/BundleSearchingPropertyResourceBundleResolverTests.java new file mode 100644 index 0000000..ead586b --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/BundleSearchingPropertyResourceBundleResolverTests.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.List; +import java.util.PropertyResourceBundle; +import java.util.Vector; + +import org.junit.Test; + +import org.eclipse.virgo.medic.eventlog.impl.BundleSearchingPropertyResourceBundleResolver; +import org.eclipse.virgo.medic.eventlog.impl.PropertyResourceBundleResolver; +import org.eclipse.virgo.teststubs.osgi.framework.FindEntriesDelegate; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; + +public class BundleSearchingPropertyResourceBundleResolverTests { + + private final PropertyResourceBundleResolver resourceBundleResolver = new BundleSearchingPropertyResourceBundleResolver(); + + @Test + public void entryNotFound() { + StubBundle bundle = new StubBundle().setFindEntriesDelegate(new FindEntriesDelegate() { + + public Enumeration<?> findEntries(String path, String pattern, boolean recurse) { + return null; + } + }); + List<PropertyResourceBundle> resourceBundles = this.resourceBundleResolver.getResourceBundles(bundle, "foo.properties"); + assertNotNull(resourceBundles); + assertEquals(0, resourceBundles.size()); + } + + @Test + public void nonExistentEntry() { + StubBundle bundle = new StubBundle().setFindEntriesDelegate(new FindEntriesDelegate() { + + public Enumeration<?> findEntries(String path, String pattern, boolean recurse) { + try { + Vector<URL> urls = new Vector<URL>(); + urls.add(new File("does/not/exist").toURI().toURL()); + return urls.elements(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + }); + + List<PropertyResourceBundle> resourceBundles = this.resourceBundleResolver.getResourceBundles(bundle, "foo.properties"); + assertNotNull(resourceBundles); + assertEquals(0, resourceBundles.size()); + } + + @Test + public void existingEntry() { + StubBundle bundle = new StubBundle().setFindEntriesDelegate(new FindEntriesDelegate() { + + public Enumeration<?> findEntries(String path, String pattern, boolean recurse) { + try { + Vector<URL> urls = new Vector<URL>(); + urls.add(new File("src/test/resources/messages.properties").toURI().toURL()); + return urls.elements(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + }); + + List<PropertyResourceBundle> resourceBundles = this.resourceBundleResolver.getResourceBundles(bundle, "foo.properties"); + assertNotNull(resourceBundles); + assertEquals(1, resourceBundles.size()); + assertEquals("Bar", resourceBundles.get(0).getString("ABC123")); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/ResourceBundleUtilsTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/ResourceBundleUtilsTests.java new file mode 100644 index 0000000..e6cc909 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/ResourceBundleUtilsTests.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; +import java.util.Locale; + +import org.eclipse.virgo.medic.eventlog.impl.ResourceBundleUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ResourceBundleUtilsTests { + + private Locale defaultLocale; + + @Before + public void setDefaultLocale() { + this.defaultLocale = Locale.getDefault(); + Locale.setDefault(new Locale("d", "E", "f")); + } + + @After + public void restoreDefaultLocale() { + Locale.setDefault(this.defaultLocale); + } + + @Test + public void localeWithVariant() { + Locale locale = new Locale("l", "C", "v"); + + List<String> candidates = ResourceBundleUtils.generateCandidatePropertiesFileNames("foo", locale); + + assertNotNull(candidates); + assertEquals("Expected 7 candidates but got " + candidates, 7, candidates.size()); + + assertEquals("foo_l_C_v.properties", candidates.get(0)); + assertEquals("foo_l_C.properties", candidates.get(1)); + assertEquals("foo_l.properties", candidates.get(2)); + assertEquals("foo_d_E_f.properties", candidates.get(3)); + assertEquals("foo_d_E.properties", candidates.get(4)); + assertEquals("foo_d.properties", candidates.get(5)); + assertEquals("foo.properties", candidates.get(6)); + } + + @Test + public void localeWithCountry() { + Locale locale = new Locale("l", "C"); + + List<String> candidates = ResourceBundleUtils.generateCandidatePropertiesFileNames("foo", locale); + + assertNotNull(candidates); + assertEquals("Expected 6 candidates but got " + candidates, 6, candidates.size()); + + assertEquals("foo_l_C.properties", candidates.get(0)); + assertEquals("foo_l.properties", candidates.get(1)); + assertEquals("foo_d_E_f.properties", candidates.get(2)); + assertEquals("foo_d_E.properties", candidates.get(3)); + assertEquals("foo_d.properties", candidates.get(4)); + assertEquals("foo.properties", candidates.get(5)); + } + + @Test + public void localeWithLanguage() { + Locale locale = new Locale("l"); + + List<String> candidates = ResourceBundleUtils.generateCandidatePropertiesFileNames("foo", locale); + + assertNotNull(candidates); + assertEquals("Expected 5 candidates but got " + candidates, 5, candidates.size()); + + assertEquals("foo_l.properties", candidates.get(0)); + assertEquals("foo_d_E_f.properties", candidates.get(1)); + assertEquals("foo_d_E.properties", candidates.get(2)); + assertEquals("foo_d.properties", candidates.get(3)); + assertEquals("foo.properties", candidates.get(4)); + } + + @Test + public void emptyLocale() { + Locale locale = new Locale(""); + + List<String> candidates = ResourceBundleUtils.generateCandidatePropertiesFileNames("foo", locale); + + assertNotNull(candidates); + assertEquals("Expected 4 candidates but got " + candidates, 4, candidates.size()); + + assertEquals("foo_d_E_f.properties", candidates.get(0)); + assertEquals("foo_d_E.properties", candidates.get(1)); + assertEquals("foo_d.properties", candidates.get(2)); + assertEquals("foo.properties", candidates.get(3)); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/StandardLocaleResolverTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/StandardLocaleResolverTests.java new file mode 100644 index 0000000..b26f653 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/StandardLocaleResolverTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import static org.junit.Assert.assertEquals; + +import java.util.Locale; + +import org.eclipse.virgo.medic.eventlog.impl.StandardLocaleResolver; +import org.junit.Test; + +public class StandardLocaleResolverTests { + + @Test + public void getLocale() { + assertEquals(Locale.getDefault(), new StandardLocaleResolver().getLocale()); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/StandardMessageResolverTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/StandardMessageResolverTests.java new file mode 100644 index 0000000..0c01ffe --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/StandardMessageResolverTests.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Locale; +import java.util.PropertyResourceBundle; + +import org.junit.Test; + +import org.eclipse.virgo.medic.eventlog.impl.LocaleResolver; +import org.eclipse.virgo.medic.eventlog.impl.MessageResolver; +import org.eclipse.virgo.medic.eventlog.impl.PropertyResourceBundleResolver; +import org.eclipse.virgo.medic.eventlog.impl.StandardMessageResolver; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; + +public class StandardMessageResolverTests { + + private final LocaleResolver localeResolver = createMock(LocaleResolver.class); + + private final PropertyResourceBundleResolver resourceBundleResolver = createMock(PropertyResourceBundleResolver.class); + + private final StubBundle primaryBundle = new StubBundle(); + + private final StubBundle secondaryBundle = new StubBundle(); + + private final MessageResolver messageResolver = new StandardMessageResolver(this.localeResolver, this.resourceBundleResolver, this.primaryBundle, + this.secondaryBundle); + + @Test + public void resolve() throws FileNotFoundException, IOException { + + expect(this.localeResolver.getLocale()).andReturn(Locale.GERMAN); + expect(this.resourceBundleResolver.getResourceBundles(this.primaryBundle, "EventLogMessages_de.properties")).andReturn( + Arrays.asList(new PropertyResourceBundle(new FileInputStream("src/test/resources/messages.properties")))); + replay(this.localeResolver, this.resourceBundleResolver); + assertEquals("Bar", this.messageResolver.resolveLogEventMessage("ABC123")); + verify(this.localeResolver, this.resourceBundleResolver); + } + + @Test + public void resolveWithLocale() throws FileNotFoundException, IOException { + expect(this.resourceBundleResolver.getResourceBundles(this.primaryBundle, "EventLogMessages_it.properties")).andReturn( + Arrays.asList(new PropertyResourceBundle(new FileInputStream("src/test/resources/messages.properties")))); + replay(this.localeResolver, this.resourceBundleResolver); + assertEquals("Bar", this.messageResolver.resolveLogEventMessage("ABC123", Locale.ITALIAN)); + verify(this.localeResolver, this.resourceBundleResolver); + } + + @Test + public void resolveWithMissingResourceBundle() { + expect(this.resourceBundleResolver.getResourceBundles(eq(this.primaryBundle), isA(String.class))).andReturn( + Collections.<PropertyResourceBundle> emptyList()).atLeastOnce(); + replay(this.localeResolver, this.resourceBundleResolver); + assertNull(this.messageResolver.resolveLogEventMessage("ABC123", Locale.FRANCE)); + verify(this.localeResolver, this.resourceBundleResolver); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/DefaultOutputAppender.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/DefaultOutputAppender.java new file mode 100644 index 0000000..2e142c9 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/DefaultOutputAppender.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl.logback; + +import java.util.ArrayList; +import java.util.List; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class DefaultOutputAppender extends AppenderBase<LoggingEvent> { + + private static List<LoggingEvent> loggingEvents = new ArrayList<LoggingEvent>(); + + @Override + protected void append(LoggingEvent eventObject) { + loggingEvents.add(eventObject); + } + + static List<LoggingEvent> getAndResetLoggingEvents() { + List<LoggingEvent> loggingEvents = DefaultOutputAppender.loggingEvents; + DefaultOutputAppender.loggingEvents = new ArrayList<LoggingEvent>(); + return loggingEvents; + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/LocalizedOutputAppender.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/LocalizedOutputAppender.java new file mode 100644 index 0000000..670901f --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/LocalizedOutputAppender.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl.logback; + +import java.util.ArrayList; +import java.util.List; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class LocalizedOutputAppender extends AppenderBase<LoggingEvent> { + + private static List<LoggingEvent> loggingEvents = new ArrayList<LoggingEvent>(); + + @Override + protected void append(LoggingEvent eventObject) { + loggingEvents.add(eventObject); + } + + static List<LoggingEvent> getAndResetLoggingEvents() { + List<LoggingEvent> loggingEvents = LocalizedOutputAppender.loggingEvents; + LocalizedOutputAppender.loggingEvents = new ArrayList<LoggingEvent>(); + return loggingEvents; + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLoggerTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLoggerTests.java new file mode 100644 index 0000000..64f27a7 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/eventlog/impl/logback/LogBackEventLoggerTests.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.impl.logback; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; + +import java.util.List; +import java.util.Locale; + +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.eventlog.impl.MessageResolver; +import org.eclipse.virgo.medic.eventlog.impl.logback.LogBackEventLogger; +import org.junit.Test; + +import ch.qos.logback.classic.spi.LoggingEvent; + + +public class LogBackEventLoggerTests { + + @Test + public void defaultAndLocalizedOutput() { + MessageResolver resolver = createMock(MessageResolver.class); + + EventLogger eventLogger = new LogBackEventLogger(resolver); + + expect(resolver.resolveLogEventMessage("UT0001E")).andReturn("the message {} {}"); + expect(resolver.resolveLogEventMessage("UT0002W")).andReturn("the message {} {}"); + expect(resolver.resolveLogEventMessage("UT0003I")).andReturn("the message {} {}"); + expect(resolver.resolveLogEventMessage("UT0001E", Locale.ENGLISH)).andReturn("the english message {} {}"); + expect(resolver.resolveLogEventMessage("UT0002W", Locale.ENGLISH)).andReturn("the english message {} {}"); + expect(resolver.resolveLogEventMessage("UT0003I", Locale.ENGLISH)).andReturn("the english message {} {}"); + replay(resolver); + + eventLogger.log("UT0001E", Level.ERROR, true, new Integer(63)); + eventLogger.log("UT0002W", Level.WARNING, true, new Integer(63)); + eventLogger.log("UT0003I", Level.INFO, true, new Integer(63)); + + verify(resolver); + + List<LoggingEvent> localizedEvents = LocalizedOutputAppender.getAndResetLoggingEvents(); + assertEquals(3, localizedEvents.size()); + + LoggingEvent loggingEvent = localizedEvents.get(0); + assertEquals(ch.qos.logback.classic.Level.ERROR, loggingEvent.getLevel()); + assertEquals("the message true 63", loggingEvent.getMessage()); + assertEquals("UT0001E", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + + loggingEvent = localizedEvents.get(1); + assertEquals(ch.qos.logback.classic.Level.WARN, loggingEvent.getLevel()); + assertEquals("the message true 63", loggingEvent.getMessage()); + assertEquals("UT0002W", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + + loggingEvent = localizedEvents.get(2); + assertEquals(ch.qos.logback.classic.Level.INFO, loggingEvent.getLevel()); + assertEquals("the message true 63", loggingEvent.getMessage()); + assertEquals("UT0003I", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + + List<LoggingEvent> defaultEvents = DefaultOutputAppender.getAndResetLoggingEvents(); + assertEquals(3, defaultEvents.size()); + + loggingEvent = defaultEvents.get(0); + assertEquals(ch.qos.logback.classic.Level.ERROR, loggingEvent.getLevel()); + assertEquals("the english message true 63", loggingEvent.getMessage()); + assertEquals("UT0001E", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + + loggingEvent = defaultEvents.get(1); + assertEquals(ch.qos.logback.classic.Level.WARN, loggingEvent.getLevel()); + assertEquals("the english message true 63", loggingEvent.getMessage()); + assertEquals("UT0002W", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + + loggingEvent = defaultEvents.get(2); + assertEquals(ch.qos.logback.classic.Level.INFO, loggingEvent.getLevel()); + assertEquals("the english message true 63", loggingEvent.getMessage()); + assertEquals("UT0003I", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + } + + @Test + public void handlingOfMissingMessages() { + MessageResolver resolver = createMock(MessageResolver.class); + + EventLogger eventLogger = new LogBackEventLogger(resolver); + + expect(resolver.resolveLogEventMessage("UT0001")).andReturn(null); + expect(resolver.resolveLogEventMessage("UT0001", Locale.ENGLISH)).andReturn(null); + + replay(resolver); + + eventLogger.log("UT0001", Level.ERROR, "apple", "orange", 345); + + verify(resolver); + + List<LoggingEvent> defaultEvents = DefaultOutputAppender.getAndResetLoggingEvents(); + assertEquals(1, defaultEvents.size()); + LoggingEvent loggingEvent = defaultEvents.get(0); + assertEquals(ch.qos.logback.classic.Level.WARN, loggingEvent.getLevel()); + assertEquals("A message with the key 'UT0001' was not found. The inserts for the message were '[apple, orange, 345]'", + loggingEvent.getMessage()); + assertEquals("ME0001W", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + + List<LoggingEvent> localizedEvents = LocalizedOutputAppender.getAndResetLoggingEvents(); + assertEquals(1, localizedEvents.size()); + loggingEvent = localizedEvents.get(0); + assertEquals(ch.qos.logback.classic.Level.WARN, loggingEvent.getLevel()); + assertEquals("A message with the key 'UT0001' was not found. The inserts for the message were '[apple, orange, 345]'", + loggingEvent.getMessage()); + assertEquals("ME0001W", loggingEvent.getMDCPropertyMap().get("medic.eventCode")); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/MedicActivatorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/MedicActivatorTests.java new file mode 100644 index 0000000..0711ef8 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/MedicActivatorTests.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl; + +import static org.eclipse.virgo.teststubs.osgi.framework.OSGiAssert.assertServiceListenerCount; +import static org.eclipse.virgo.teststubs.osgi.framework.OSGiAssert.assertServiceRegistrationCount; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.replay; +import static org.junit.Assert.assertEquals; + +import java.io.PrintStream; + +import org.junit.Test; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleListener; +import org.osgi.service.cm.ConfigurationListener; +import org.osgi.service.packageadmin.PackageAdmin; + + +import org.eclipse.virgo.medic.dump.DumpContributor; +import org.eclipse.virgo.medic.dump.DumpGenerator; +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.EventLoggerFactory; +import org.eclipse.virgo.medic.impl.MedicActivator; +import org.eclipse.virgo.medic.log.DelegatingPrintStream; +import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext; +import org.eclipse.virgo.teststubs.osgi.support.ObjectClassFilter; + +public class MedicActivatorTests { + + @Test + public void startAndStop() throws Exception { + BundleActivator bundleActivator = new MedicActivator(); + StubBundleContext bundleContext = new StubBundleContext().addFilter(new ObjectClassFilter(DumpContributor.class)); + + PackageAdmin packageAdmin = createNiceMock(PackageAdmin.class); + replay(packageAdmin); + + bundleContext.registerService(PackageAdmin.class.getName(), packageAdmin, null); + + bundleActivator.start(bundleContext); + assertServiceListenerCount(bundleContext, 1); + assertServiceRegistrationCount(bundleContext, DumpGenerator.class, 1); + assertServiceRegistrationCount(bundleContext, DumpContributor.class, 4); + assertServiceRegistrationCount(bundleContext, EventLoggerFactory.class, 1); + assertServiceRegistrationCount(bundleContext, EventLogger.class, 1); + assertServiceRegistrationCount(bundleContext, LoggingConfigurationPublisher.class, 1); + assertServiceRegistrationCount(bundleContext, PrintStream.class, 2); + assertServiceRegistrationCount(bundleContext, DelegatingPrintStream.class, 2); + assertServiceRegistrationCount(bundleContext, ConfigurationListener.class, 1); + assertServiceRegistrationCount(bundleContext, BundleListener.class, 1); + + bundleActivator.stop(bundleContext); + + assertEquals(1, bundleContext.getServiceRegistrations().size()); + } + + @Test + public void copeWithNullsDuringStop() throws Exception { + BundleActivator bundleActivator = new MedicActivator(); + BundleContext context = new StubBundleContext(new StubBundle()); + bundleActivator.stop(context); + } + +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProviderTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProviderTests.java new file mode 100644 index 0000000..5ecc0a8 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProviderTests.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl.config; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.junit.Test; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +import org.eclipse.virgo.medic.impl.config.ConfigurationAdminConfigurationProvider; +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext; + +public class ConfigurationAdminConfigurationProviderTests { + + private final StubBundleContext bundleContext = new StubBundleContext(); + + @Test + @SuppressWarnings("unchecked") + public void getConfigurationWithoutConfigurationAdmin() { + ConfigurationProvider configurationProvider = new ConfigurationAdminConfigurationProvider(bundleContext); + Dictionary configuration = configurationProvider.getConfiguration(); + assertNotNull(configuration); + assertEquals(".", configuration.get(ConfigurationProvider.KEY_DUMP_ROOT_DIRECTORY)); + } + + @Test + @SuppressWarnings("unchecked") + public void getConfigurationWithEmptyConfigurationAdminConfiguration() throws IOException { + ConfigurationAdmin configurationAdmin = createMock(ConfigurationAdmin.class); + Configuration configuration = createMock(Configuration.class); + + this.bundleContext.registerService(ConfigurationAdmin.class.getName(), configurationAdmin, null); + expect(configurationAdmin.getConfiguration("org.eclipse.virgo.medic", null)).andReturn(configuration); + expect(configuration.getProperties()).andReturn(null); + + replay(configurationAdmin, configuration); + + ConfigurationProvider configurationProvider = new ConfigurationAdminConfigurationProvider(bundleContext); + + Dictionary configDictionary = configurationProvider.getConfiguration(); + assertNotNull(configDictionary); + assertEquals(".", configDictionary.get(ConfigurationProvider.KEY_DUMP_ROOT_DIRECTORY)); + + verify(configurationAdmin, configuration); + } + + @Test + @SuppressWarnings("unchecked") + public void getConfigurationWithConfigurationAdminConfiguration() throws IOException { + ConfigurationAdmin configurationAdmin = createMock(ConfigurationAdmin.class); + Configuration configuration = createMock(Configuration.class); + + this.bundleContext.registerService(ConfigurationAdmin.class.getName(), configurationAdmin, null); + Dictionary properties = new Hashtable(); + properties.put(ConfigurationProvider.KEY_DUMP_ROOT_DIRECTORY, "target"); + properties.put("a.b.c", "d.e.f"); + expect(configurationAdmin.getConfiguration("org.eclipse.virgo.medic", null)).andReturn(configuration); + expect(configuration.getProperties()).andReturn(properties); + + replay(configurationAdmin, configuration); + + ConfigurationProvider configurationProvider = new ConfigurationAdminConfigurationProvider(bundleContext); + Dictionary configDictionary = configurationProvider.getConfiguration(); + assertNotNull(configDictionary); + assertEquals("target", configDictionary.get(ConfigurationProvider.KEY_DUMP_ROOT_DIRECTORY)); + assertEquals("d.e.f", configDictionary.get("a.b.c")); + + verify(configurationAdmin, configuration); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/config/DictionaryUtilsTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/config/DictionaryUtilsTests.java new file mode 100644 index 0000000..32fa55a --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/impl/config/DictionaryUtilsTests.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.impl.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Dictionary; +import java.util.Hashtable; + +import org.eclipse.virgo.medic.impl.config.DictionaryUtils; +import org.junit.Test; + + +@SuppressWarnings("unchecked") +public class DictionaryUtilsTests { + + @Test + public void emptyMerge() { + Dictionary primary = new Hashtable(); + Dictionary secondary = new Hashtable(); + + DictionaryUtils.merge(primary, secondary); + assertTrue(primary.isEmpty()); + } + + @Test + public void mergeWithoutClash() { + Dictionary primary = new Hashtable(); + primary.put("b", "c"); + Dictionary secondary = new Hashtable(); + secondary.put("a", "b"); + + DictionaryUtils.merge(primary, secondary); + assertEquals("c", primary.get("b")); + assertEquals("b", primary.get("a")); + } + + @Test + public void mergeWithClash() { + Dictionary primary = new Hashtable(); + primary.put("b", "c"); + Dictionary secondary = new Hashtable(); + secondary.put("b", "b"); + + DictionaryUtils.merge(primary, secondary); + assertEquals("c", primary.get("b")); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/CapturingAppender.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/CapturingAppender.java new file mode 100644 index 0000000..5ca3784 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/CapturingAppender.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import java.util.ArrayList; +import java.util.List; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class CapturingAppender extends AppenderBase<LoggingEvent> { + + private static List<LoggingEvent> loggingEvents = new ArrayList<LoggingEvent>(); + + @Override + protected void append(LoggingEvent eventObject) { + loggingEvents.add(eventObject); + } + + static List<LoggingEvent> getAndResetLoggingEvents() { + List<LoggingEvent> loggingEvents = CapturingAppender.loggingEvents; + CapturingAppender.loggingEvents = new ArrayList<LoggingEvent>(); + return loggingEvents; + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java new file mode 100644 index 0000000..a5f153b --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Dictionary; +import java.util.List; +import java.util.Locale; +import java.util.Properties; + +import org.eclipse.virgo.medic.impl.config.ConfigurationProvider; +import org.eclipse.virgo.medic.log.impl.ExecutionStackAccessor; +import org.eclipse.virgo.medic.log.impl.LoggingPrintStreamWrapper; +import org.eclipse.virgo.medic.log.impl.SecurityManagerExecutionStackAccessor; +import org.junit.Before; +import org.junit.Test; + +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.LoggingEvent; + + +public class LoggingPrintStreamWrapperTests { + + private PrintStream wrapper; + + @Test + public void test() { + produceOutput(this.wrapper); + + List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents(); + assertEquals(22, loggingEvents.size()); + + assertEquals("abcdefghij", loggingEvents.get(0).getMessage()); + assertEquals("Three strings", loggingEvents.get(1).getMessage()); + assertEquals("last one on a new line.", loggingEvents.get(2).getMessage()); + assertEquals("3,1416", loggingEvents.get(3).getMessage()); + assertEquals("trueklm", loggingEvents.get(4).getMessage()); + assertEquals("a123.0456.078910toString", loggingEvents.get(5).getMessage()); + assertEquals("abcdThree strings", loggingEvents.get(6).getMessage()); + assertEquals("last one on a new line.", loggingEvents.get(7).getMessage()); + assertEquals("3,1416", loggingEvents.get(8).getMessage()); + assertEquals("false", loggingEvents.get(9).getMessage()); + assertEquals("b", loggingEvents.get(10).getMessage()); + assertEquals("", loggingEvents.get(11).getMessage()); + assertEquals("", loggingEvents.get(12).getMessage()); + assertEquals("abc", loggingEvents.get(13).getMessage()); + assertEquals("de", loggingEvents.get(14).getMessage()); + assertEquals("123.0", loggingEvents.get(15).getMessage()); + assertEquals("456.0", loggingEvents.get(16).getMessage()); + assertEquals("789", loggingEvents.get(17).getMessage()); + assertEquals("101112", loggingEvents.get(18).getMessage()); + assertEquals("toString", loggingEvents.get(19).getMessage()); + assertEquals("A string with a", loggingEvents.get(20).getMessage()); + assertEquals("new line in it.", loggingEvents.get(21).getMessage()); + } + + @Test + public void testOutputWithinLoggingCode() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(baos); + PrintStream wrapper = new LoggingPrintStreamWrapper(printStream, getClass().getName(), new ExecutionStackAccessor() { + + public Class<?>[] getExecutionStack() { + return new Class[] {Logger.class}; + } + }, new StubConfigurationProvider(), "theProperty"); + + produceOutput(wrapper); + + List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents(); + assertEquals(0, loggingEvents.size()); + } + + private void produceOutput(PrintStream printStream) { + printStream.append('a'); + printStream.append("bcd"); + printStream.append("abcdefghij", 4, 10); + printStream.println(); + printStream.format("%s %s%n%s%n", "Three", "strings", "last one on a new line."); + printStream.format(Locale.FRANCE, "%.4f%n", Math.PI); + printStream.print(true); + printStream.print('k'); + printStream.print(new char[] {'l', 'm', '\r', 'a'}); + printStream.print(123d); + printStream.print(456f); + printStream.print(7); + printStream.print(8910l); + printStream.print(new Object() {public String toString() { return "toString";}}); + printStream.append('\n'); + printStream.print("abcd"); + printStream.printf("%s %s%n%s%n", "Three", "strings", "last one on a new line."); + printStream.printf(Locale.FRANCE, "%.4f%n", Math.PI); + printStream.println(false); + printStream.println('b'); + printStream.println('\n'); + printStream.println(new char[] {'a', 'b', 'c', '\n', 'd', 'e'}); + printStream.println(123d); + printStream.println(456f); + printStream.println(789); + printStream.println(101112l); + printStream.println(new Object() {public String toString() { return "toString";}}); + printStream.println("A string with a\nnew line in it."); + } + + @Test + public void testByteArrayHandling() { + String string = "Some text to be turned into bytes."; + String stringWithNewLine = string + "\n"; + byte[] stringBytes = stringWithNewLine.getBytes(); + + wrapper.write(stringBytes, 0, stringBytes.length); + + List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents(); + assertEquals(1, loggingEvents.size()); + + assertEquals("Some text to be turned into bytes.", loggingEvents.get(0).getMessage()); + } + + @Test + public void testSingleByteHandling() { + String string = "Some text to be turned into bytes."; + byte[] stringBytes = string.getBytes(); + + for (byte b: stringBytes) { + wrapper.write(b); + } + wrapper.println(); + + List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents(); + assertEquals(1, loggingEvents.size()); + + assertEquals("Some text to be turned into bytes.", loggingEvents.get(0).getMessage()); + } + + @Test + public void testPrintNullString(){ + + String imNull = null; + + wrapper.println(imNull); + wrapper.print(imNull); + wrapper.println(); + + List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents(); + assertEquals(2, loggingEvents.size()); + + assertEquals("null", loggingEvents.get(0).getMessage()); + assertEquals("null", loggingEvents.get(1).getMessage()); + } + + @Before + public void createWrapper() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(baos); + this.wrapper = new LoggingPrintStreamWrapper(printStream, getClass().getName(), new SecurityManagerExecutionStackAccessor(), new StubConfigurationProvider(), "theProperty"); + } + + private final class StubConfigurationProvider implements ConfigurationProvider { + + private final Properties configuration; + + private StubConfigurationProvider() { + this.configuration = new Properties(); + this.configuration.setProperty("theProperty", "true"); + } + + @SuppressWarnings("unchecked") + public Dictionary getConfiguration() { + return this.configuration; + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/PackageNameFilteringClassSelectorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/PackageNameFilteringClassSelectorTests.java new file mode 100644 index 0000000..9fc65b9 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/PackageNameFilteringClassSelectorTests.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; + +import org.eclipse.virgo.medic.log.impl.PackageNameFilteringClassSelector; +import org.junit.Test; + +public class PackageNameFilteringClassSelectorTests { + + @Test + public void noFiltering() { + PackageNameFilteringClassSelector classSelector = new PackageNameFilteringClassSelector(Arrays.asList("")); + Class<?> selected = classSelector.select(new Class<?>[] { getClass() }); + assertEquals(getClass(), selected); + } + + @Test + public void filterToEmpty() { + PackageNameFilteringClassSelector classSelector = new PackageNameFilteringClassSelector(Arrays.asList(getClass().getPackage().getName())); + Class<?> selected = classSelector.select(new Class<?>[] { getClass() }); + assertNull(selected); + } + + @Test + public void filtered() { + PackageNameFilteringClassSelector classSelector = new PackageNameFilteringClassSelector(Arrays.asList(getClass().getPackage().getName())); + Class<?> selected = classSelector.select(new Class<?>[] { getClass(), java.util.ArrayList.class }); + assertEquals(java.util.ArrayList.class, selected); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/SecurityManagerExecutionStackAccessorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/SecurityManagerExecutionStackAccessorTests.java new file mode 100644 index 0000000..361fdc7 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/SecurityManagerExecutionStackAccessorTests.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.virgo.medic.log.impl.ExecutionStackAccessor; +import org.eclipse.virgo.medic.log.impl.SecurityManagerExecutionStackAccessor; +import org.junit.Test; + +public class SecurityManagerExecutionStackAccessorTests { + + @Test + public void getClasses() { + ExecutionStackAccessor accessor = new SecurityManagerExecutionStackAccessor(); + Class<?>[] classes = accessor.getExecutionStack(); + assertNotNull(classes); + assertTrue(classes.length > 0); + assertEquals("Unexpected class in stack: " + classes[0], SecurityManagerExecutionStackAccessorTests.class, classes[0]); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/StandardDelegatingPrintStreamTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/StandardDelegatingPrintStreamTests.java new file mode 100644 index 0000000..f23caed --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/StandardDelegatingPrintStreamTests.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringWriter; +import java.util.Locale; + +import org.eclipse.virgo.medic.log.impl.StandardDelegatingPrintStream; +import org.junit.Before; +import org.junit.Test; + +/** + */ +public class StandardDelegatingPrintStreamTests { + + private final WriterOutputStream writerOutputStream = new WriterOutputStream(); + + private final StandardDelegatingPrintStream delegatingPrintStream = new StandardDelegatingPrintStream(new PrintStream(writerOutputStream)); + + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + @Before + public void setLocale() { + Locale.setDefault(Locale.ENGLISH); + } + + @Test + public void appendChar() { + delegatingPrintStream.append('a'); + assertEquals("a", this.writerOutputStream.getOutput()); + } + + @Test + public void append() { + delegatingPrintStream.append("a"); + assertEquals("a", this.writerOutputStream.getOutput()); + } + + @Test + public void appendSegment() { + delegatingPrintStream.append("abc", 1, 2); + assertEquals("b", this.writerOutputStream.getOutput()); + } + + @Test + public void format() { + delegatingPrintStream.format("%s", "apple"); + assertEquals("apple", this.writerOutputStream.getOutput()); + } + + @Test + public void formatWithLocale() { + delegatingPrintStream.format(Locale.FRENCH, "%f", 3.1417d); + assertEquals("3,141700", this.writerOutputStream.getOutput()); + } + + @Test + public void printBoolean() { + delegatingPrintStream.print("true"); + assertEquals("true", this.writerOutputStream.getOutput()); + } + + @Test + public void printChar() { + delegatingPrintStream.print('a'); + assertEquals("a", this.writerOutputStream.getOutput()); + } + + @Test + public void printCharArray() { + delegatingPrintStream.print(new char[] {'a', 'b', 'c'}); + assertEquals("abc", this.writerOutputStream.getOutput()); + } + + @Test + public void printDouble() { + delegatingPrintStream.print(3.1d); + assertEquals("3.1", this.writerOutputStream.getOutput()); + } + + @Test + public void printFloat() { + delegatingPrintStream.print(3.1f); + assertEquals("3.1", this.writerOutputStream.getOutput()); + } + + @Test + public void printInt() { + delegatingPrintStream.print(3); + assertEquals("3", this.writerOutputStream.getOutput()); + } + + @Test + public void printLong() { + delegatingPrintStream.print(12345678901234567L); + assertEquals("12345678901234567", this.writerOutputStream.getOutput()); + } + + @Test + public void printObject() { + delegatingPrintStream.print(new Integer(345)); + assertEquals("345", this.writerOutputStream.getOutput()); + } + + @Test + public void printString() { + delegatingPrintStream.print("hello"); + assertEquals("hello", this.writerOutputStream.getOutput()); + } + + @Test + public void printf() { + delegatingPrintStream.printf("%s", "alpha"); + assertEquals("alpha", this.writerOutputStream.getOutput()); + } + + @Test + public void printfWithLocale() { + delegatingPrintStream.printf(Locale.FRENCH, "%f", 3.1417d); + assertEquals("3,141700", this.writerOutputStream.getOutput()); + } + + @Test + public void println() { + delegatingPrintStream.println(); + assertEquals(LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnBoolean() { + delegatingPrintStream.println(true); + assertEquals("true" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnChar() { + delegatingPrintStream.println('a'); + assertEquals("a" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnCharArray() { + delegatingPrintStream.println(new char[] {'a', 'b', 'c'}); + assertEquals("abc" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnDouble() { + delegatingPrintStream.println(3.1d); + assertEquals("3.1" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnFloat() { + delegatingPrintStream.println(3.1f); + assertEquals("3.1" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnInt() { + delegatingPrintStream.println(3); + assertEquals("3" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnLong() { + delegatingPrintStream.println(12345678901234567L); + assertEquals("12345678901234567" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnObject() { + delegatingPrintStream.println(new Integer(345)); + assertEquals("345" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void printlnString() { + delegatingPrintStream.println("hello"); + assertEquals("hello" + LINE_SEPARATOR, this.writerOutputStream.getOutput()); + } + + @Test + public void write() { + delegatingPrintStream.write('a'); + assertEquals("a", this.writerOutputStream.getOutput()); + } + + @Test + public void writeByteArray() throws IOException { + delegatingPrintStream.write(new byte[] {'a', 'b', 'c'}); + assertEquals("abc", this.writerOutputStream.getOutput()); + } + + @Test + public void writeByteArraySegment() { + delegatingPrintStream.write(new byte[] {'a', 'b', 'c'}, 1, 2); + assertEquals("bc", this.writerOutputStream.getOutput()); + } + + @Test + public void setDelegate() { + delegatingPrintStream.print("hello"); + assertEquals("hello", this.writerOutputStream.getOutput()); + + delegatingPrintStream.setDelegate(null); + delegatingPrintStream.print("hello"); + assertEquals("hello", this.writerOutputStream.getOutput()); + + delegatingPrintStream.setDelegate(new PrintStream(this.writerOutputStream)); + delegatingPrintStream.print("hello"); + assertEquals("hellohello", this.writerOutputStream.getOutput()); + } + + private static final class WriterOutputStream extends OutputStream { + private final StringWriter writer = new StringWriter(); + + public void write(int b) throws IOException { + writer.write(b); + } + + public String getOutput() { + return this.writer.toString(); + } + } +} + diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/BundleResourceConfigurationLocatorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/BundleResourceConfigurationLocatorTests.java new file mode 100644 index 0000000..c9249d1 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/BundleResourceConfigurationLocatorTests.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.Test; +import org.osgi.framework.Version; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.impl.config.BundleResourceConfigurationLocator; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; + +public class BundleResourceConfigurationLocatorTests { + + private final BundleResourceConfigurationLocator locator = new BundleResourceConfigurationLocator(); + + private final StubBundle bundle = new StubBundle("foo", new Version(1, 2, 3)); + + @Test + public void configFromBundle() throws MalformedURLException { + this.bundle.addResource("logback.xml", new URL("file:src/test/resources/logback.xml")); + LoggingConfiguration configuration = this.locator.locateConfiguration(this.bundle); + assertNotNull(configuration); + assertEquals("foo_1.2.3", configuration.getName()); + } + + @Test + public void defaultConfigFromBundle() throws MalformedURLException { + this.bundle.addResource("logback-default.xml", new URL("file:src/test/resources/logback.xml")); + LoggingConfiguration configuration = this.locator.locateConfiguration(this.bundle); + assertNotNull(configuration); + assertEquals("foo_1.2.3", configuration.getName()); + } + + @Test + public void noConfigInBundle() { + LoggingConfiguration configuration = this.locator.locateConfiguration(this.bundle); + assertNull(configuration); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/CompositeConfigurationLocatorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/CompositeConfigurationLocatorTests.java new file mode 100644 index 0000000..db921d0 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/CompositeConfigurationLocatorTests.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.impl.config.CompositeConfigurationLocator; +import org.eclipse.virgo.medic.log.impl.config.ConfigurationLocator; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; + +public class CompositeConfigurationLocatorTests { + + @Test + public void configurationFromFirstLocator() { + ConfigurationLocator locator1 = createMock(ConfigurationLocator.class); + ConfigurationLocator locator2 = createMock(ConfigurationLocator.class); + + ConfigurationLocator compositeLocator = new CompositeConfigurationLocator(locator1, locator2); + + StubBundle bundle = new StubBundle(); + + LoggingConfiguration loggingConfiguration = createMock(LoggingConfiguration.class); + + expect(locator1.locateConfiguration(bundle)).andReturn(loggingConfiguration); + replay(locator1, locator2); + + assertEquals(loggingConfiguration, compositeLocator.locateConfiguration(bundle)); + + verify(locator1, locator2); + } + + @Test + public void configurationFromSubsequentLocator() { + ConfigurationLocator locator1 = createMock(ConfigurationLocator.class); + ConfigurationLocator locator2 = createMock(ConfigurationLocator.class); + + ConfigurationLocator compositeLocator = new CompositeConfigurationLocator(locator1, locator2); + + StubBundle bundle = new StubBundle(); + + LoggingConfiguration loggingConfiguration = createMock(LoggingConfiguration.class); + + expect(locator1.locateConfiguration(bundle)).andReturn(null); + expect(locator2.locateConfiguration(bundle)).andReturn(loggingConfiguration); + replay(locator1, locator2); + + assertEquals(loggingConfiguration, compositeLocator.locateConfiguration(bundle)); + + verify(locator1, locator2); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/ServiceRegistryConfigurationLocatorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/ServiceRegistryConfigurationLocatorTests.java new file mode 100644 index 0000000..aa40348 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/ServiceRegistryConfigurationLocatorTests.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import static org.easymock.EasyMock.createMock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Map; +import java.util.TreeMap; + +import org.junit.Test; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.impl.config.ServiceRegistryConfigurationLocator; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext; +import org.eclipse.virgo.teststubs.osgi.support.FalseFilter; +import org.eclipse.virgo.teststubs.osgi.support.PropertiesFilter; + +public class ServiceRegistryConfigurationLocatorTests { + + private final StubBundle bundle = new StubBundle(); + + private final StubBundleContext bundleContext = new StubBundleContext(); + + private final ServiceRegistryConfigurationLocator locator = new ServiceRegistryConfigurationLocator(this.bundleContext); + + @Test + public void noConfigurationInServiceRegistry() { + this.bundle.addHeader("Medic-LoggingConfiguration", "foo"); + this.bundleContext.addFilter(new FalseFilter("(org.eclipse.virgo.medic.log.configuration.id=foo)")); + LoggingConfiguration configuration = this.locator.locateConfiguration(this.bundle); + assertNull(configuration); + } + + @Test + public void singleConfigurationInServiceRegistry() { + this.bundle.addHeader("Medic-LoggingConfiguration", "foo"); + LoggingConfiguration loggingConfiguration = createMock(LoggingConfiguration.class); + this.bundleContext.addFilter(new PropertiesFilter(getDefaultMap())); + this.bundleContext.registerService(LoggingConfiguration.class.getName(), loggingConfiguration, getDefaultDictionary()); + LoggingConfiguration configuration = this.locator.locateConfiguration(this.bundle); + assertEquals(loggingConfiguration, configuration); + } + + @Test + public void multipleConfigurationsInServiceRegistry() { + this.bundle.addHeader("Medic-LoggingConfiguration", "foo"); + LoggingConfiguration loggingConfiguration = createMock(LoggingConfiguration.class); + this.bundleContext.addFilter(new PropertiesFilter(getDefaultMap())); + this.bundleContext.registerService(LoggingConfiguration.class.getName(), loggingConfiguration, getDefaultDictionary()); + this.bundleContext.registerService(LoggingConfiguration.class.getName(), loggingConfiguration, getDefaultDictionary()); + this.bundleContext.registerService(LoggingConfiguration.class.getName(), loggingConfiguration, getDefaultDictionary()); + LoggingConfiguration configuration = this.locator.locateConfiguration(this.bundle); + assertEquals(loggingConfiguration, configuration); + } + + @Test + public void noHeaderInManifest() { + this.locator.locateConfiguration(this.bundle); + } + + @SuppressWarnings("unchecked") + private Dictionary getDefaultDictionary() { + Dictionary properties = new Hashtable(); + properties.put("org.eclipse.virgo.medic.log.configuration.id", "foo"); + return properties; + } + + private Map<String, Object> getDefaultMap() { + Map<String, Object> properties = new TreeMap<String, Object>(); + properties.put("org.eclipse.virgo.medic.log.configuration.id", "foo"); + return properties; + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfigurationPublisherTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfigurationPublisherTests.java new file mode 100644 index 0000000..8028be8 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/config/StandardLoggingConfigurationPublisherTests.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.config; + +import java.io.File; + +import org.junit.Test; + +import org.eclipse.virgo.medic.log.ConfigurationPublicationFailedException; +import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher; +import org.eclipse.virgo.medic.log.impl.config.StandardLoggingConfigurationPublisher; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext; + +public class StandardLoggingConfigurationPublisherTests { + + private final StubBundleContext bundleContext = new StubBundleContext(); + + private final LoggingConfigurationPublisher publisher = new StandardLoggingConfigurationPublisher(this.bundleContext); + + @Test(expected = ConfigurationPublicationFailedException.class) + public void failedPublication() throws ConfigurationPublicationFailedException { + publisher.publishConfiguration(new File("does/not/exist"), "foo"); + } + + @Test + public void publication() throws ConfigurationPublicationFailedException { + this.publisher.publishConfiguration(new File("src/test/resources/logback.xml"), "foo"); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/DelegatingContextSelectorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/DelegatingContextSelectorTests.java new file mode 100644 index 0000000..523de85 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/DelegatingContextSelectorTests.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.virgo.medic.log.impl.logback.ContextSelectorDelegate; +import org.eclipse.virgo.medic.log.impl.logback.DelegatingContextSelector; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import ch.qos.logback.classic.LoggerContext; + +public class DelegatingContextSelectorTests { + + private final ContextSelectorDelegate delegate = createMock(ContextSelectorDelegate.class); + + private final LoggerContext loggerContext = new LoggerContext(); + + private DelegatingContextSelector delegatingContextSelector; + + @Before + public void resetDefaultContextConfiguredFlag() throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { + Field field = DelegatingContextSelector.class.getDeclaredField("defaultContextConfigured"); + field.setAccessible(true); + field.setBoolean(null, false); + } + + @After + public void cleanup() { + DelegatingContextSelector.setDelegate(null); + } + + @Test + public void detachLoggerContext() { + LoggerContext detachedContext = new LoggerContext(); + + expect(this.delegate.detachLoggerContext("foo")).andReturn(detachedContext); + expect(this.delegate.detachLoggerContext("foo")).andReturn(null); + this.delegate.configureDefaultContext(this.loggerContext); + + replay(this.delegate); + + this.delegatingContextSelector = new DelegatingContextSelector(this.loggerContext); + DelegatingContextSelector.setDelegate(this.delegate); + + assertEquals(detachedContext, this.delegatingContextSelector.detachLoggerContext("foo")); + assertNull(this.delegatingContextSelector.detachLoggerContext("foo")); + + verify(this.delegate); + } + + @Test + public void getContextNames() { + List<String> contextNames = Arrays.asList("a", "b", "c"); + + expect(this.delegate.getContextNames()).andReturn(contextNames); + this.delegate.configureDefaultContext(this.loggerContext); + + replay(this.delegate); + + this.delegatingContextSelector = new DelegatingContextSelector(this.loggerContext); + DelegatingContextSelector.setDelegate(this.delegate); + + assertEquals(contextNames, this.delegatingContextSelector.getContextNames()); + + verify(this.delegate); + } + + @Test + public void getDefaultLoggerContext() { + this.delegate.configureDefaultContext(this.loggerContext); + replay(this.delegate); + + this.delegatingContextSelector = new DelegatingContextSelector(this.loggerContext); + DelegatingContextSelector.setDelegate(this.delegate); + + verify(this.delegate); + + assertEquals(this.loggerContext, this.delegatingContextSelector.getDefaultLoggerContext()); + } + + @Test + public void getLoggerContext() { + LoggerContext context = new LoggerContext(); + + expect(this.delegate.getLoggerContext()).andReturn(context); + this.delegate.configureDefaultContext(this.loggerContext); + + replay(this.delegate); + + this.delegatingContextSelector = new DelegatingContextSelector(this.loggerContext); + DelegatingContextSelector.setDelegate(this.delegate); + + assertEquals(context, this.delegatingContextSelector.getLoggerContext()); + + verify(this.delegate); + } + + @Test + public void getNamedLoggerContext() { + LoggerContext context = new LoggerContext(); + + expect(this.delegate.getLoggerContext("foo")).andReturn(context); + this.delegate.configureDefaultContext(this.loggerContext); + + replay(this.delegate); + + this.delegatingContextSelector = new DelegatingContextSelector(this.loggerContext); + DelegatingContextSelector.setDelegate(this.delegate); + + assertEquals(context, this.delegatingContextSelector.getLoggerContext("foo")); + + verify(this.delegate); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/JoranLoggerContextConfigurerTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/JoranLoggerContextConfigurerTests.java new file mode 100644 index 0000000..b7afd78 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/JoranLoggerContextConfigurerTests.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import static org.junit.Assert.assertNotNull; + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.impl.logback.JoranLoggerContextConfigurer; +import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurationFailedException; +import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurer; +import org.junit.Test; + +import ch.qos.logback.classic.LoggerContext; + + +public class JoranLoggerContextConfigurerTests { + + private final LoggerContextConfigurer configurer = new JoranLoggerContextConfigurer(); + + @Test(expected = LoggerContextConfigurationFailedException.class) + public void malformedXML() throws LoggerContextConfigurationFailedException { + LoggingConfiguration configuration = new StubLoggingConfiguration("dslkjgw", "the-config"); + configurer.applyConfiguration(configuration, new LoggerContext()); + } + + @Test(expected = LoggerContextConfigurationFailedException.class) + public void malformedConfiguration() throws LoggerContextConfigurationFailedException { + LoggingConfiguration configuration = new StubLoggingConfiguration("<configuration><appender/></configuration>", "the-config"); + configurer.applyConfiguration(configuration, new LoggerContext()); + } + + @Test + public void validConfiguration() throws LoggerContextConfigurationFailedException { + LoggingConfiguration configuration = new StubLoggingConfiguration("<configuration><logger name=\"abc\"></logger></configuration>", + "the-config"); + LoggerContext loggerContext = new LoggerContext(); + configurer.applyConfiguration(configuration, loggerContext); + assertNotNull(loggerContext.getLogger("abc")); + } + + private final class StubLoggingConfiguration implements LoggingConfiguration { + + private final String configuration; + + private final String name; + + private StubLoggingConfiguration(String configuration, String name) { + this.configuration = configuration; + this.name = name; + } + + public String getConfiguration() { + return this.configuration; + } + + public String getName() { + return this.name; + } + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/StandardContextSelectorTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/StandardContextSelectorTests.java new file mode 100644 index 0000000..39bfeb6 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/logback/StandardContextSelectorTests.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import java.util.List; + +import org.junit.Test; + +import ch.qos.logback.classic.LoggerContext; + + +import org.eclipse.virgo.medic.log.LoggingConfiguration; +import org.eclipse.virgo.medic.log.impl.CallingBundleResolver; +import org.eclipse.virgo.medic.log.impl.config.ConfigurationLocator; +import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurationFailedException; +import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurer; +import org.eclipse.virgo.medic.log.impl.logback.StandardContextSelectorDelegate; +import org.eclipse.virgo.teststubs.osgi.framework.StubBundle; + +public class StandardContextSelectorTests { + + private CallingBundleResolver loggingCallerLocator = createMock(CallingBundleResolver.class); + + private ConfigurationLocator configurationLocator = createMock(ConfigurationLocator.class); + + private StubBundle bundle = new StubBundle(); + + private LoggerContextConfigurer loggerContextConfigurer = createMock(LoggerContextConfigurer.class); + + private StandardContextSelectorDelegate contextSelectorDelegate = new StandardContextSelectorDelegate(this.loggingCallerLocator, + this.configurationLocator, this.bundle, this.loggerContextConfigurer); + + @Test + public void loggerContextWithLocatedConfiguration() throws LoggerContextConfigurationFailedException { + LoggingConfiguration loggingConfiguration = createMock(LoggingConfiguration.class); + expect(loggingConfiguration.getName()).andReturn("the-configuration").atLeastOnce(); + expect(this.loggingCallerLocator.getCallingBundle()).andReturn(this.bundle).times(2); + expect(this.configurationLocator.locateConfiguration(this.bundle)).andReturn(loggingConfiguration).times(1); + this.loggerContextConfigurer.applyConfiguration(eq(loggingConfiguration), isA(LoggerContext.class)); + replay(this.configurationLocator, this.loggingCallerLocator, this.loggerContextConfigurer, loggingConfiguration); + + LoggerContext loggerContext = this.contextSelectorDelegate.getLoggerContext(); + assertEquals("the-configuration", loggerContext.getName()); + + LoggerContext reusedLoggerContext = this.contextSelectorDelegate.getLoggerContext(); + assertEquals("the-configuration", reusedLoggerContext.getName()); + + assertSame(loggerContext, reusedLoggerContext); + + List<String> contextNames = this.contextSelectorDelegate.getContextNames(); + assertEquals(1, contextNames.size()); + assertEquals("the-configuration", contextNames.get(0)); + + loggerContext = this.contextSelectorDelegate.getLoggerContext("the-configuration"); + assertNotNull(loggerContext); + assertEquals("the-configuration", loggerContext.getName()); + + verify(this.configurationLocator, this.loggingCallerLocator, this.loggerContextConfigurer, loggingConfiguration); + } + + @Test + public void loggerContextWithNoLocatedConfiguration() { + expect(this.loggingCallerLocator.getCallingBundle()).andReturn(this.bundle); + expect(this.configurationLocator.locateConfiguration(this.bundle)).andReturn(null); + replay(this.configurationLocator, this.loggingCallerLocator); + + LoggerContext loggerContext = this.contextSelectorDelegate.getLoggerContext(); + assertNull(loggerContext); + verify(this.configurationLocator, this.loggingCallerLocator); + } +} diff --git a/org.eclipse.virgo.medic.core/src/test/resources/.gitignore b/org.eclipse.virgo.medic.core/src/test/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/resources/.gitignore diff --git a/org.eclipse.virgo.medic.core/src/test/resources/logback-test.xml b/org.eclipse.virgo.medic.core/src/test/resources/logback-test.xml new file mode 100644 index 0000000..c14b954 --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/resources/logback-test.xml @@ -0,0 +1,50 @@ +<configuration> + <root level="debug"/> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread <%X{medic.eventCode}> %msg %ex%n</Pattern> + </layout> + </appender> + + <logger name="org.eclipse.virgo.medic.eventlog.localized"> + <appender-ref ref="STDOUT" /> + <appender name="stubAppender" class="org.eclipse.virgo.medic.eventlog.impl.logback.LocalizedOutputAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread <%X{medic.eventCode}> %msg %ex</Pattern> + </layout> + </appender> + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>target/serviceability/eventlog/eventlog.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <FileNamePattern>target/serviceability/eventlog/eventlog_%i.log</FileNamePattern> + <MinIndex>1</MinIndex> + <MaxIndex>4</MaxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <MaxFileSize>10MB</MaxFileSize> + </triggeringPolicy> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread <%X{medic.eventCode}> %msg %ex%n</Pattern> + </layout> + </appender> + </logger> + + <logger name="org.eclipse.virgo.medic.eventlog.default"> + <appender name="stubAppender" class="org.eclipse.virgo.medic.eventlog.impl.logback.DefaultOutputAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread <%X{medic.eventCode}> %msg %ex</Pattern> + </layout> + </appender> + </logger> + + <logger name="org.eclipse.virgo.medic.log.impl.LoggingPrintStreamWrapperTests"> + <appender name="capturingAppender" class="org.eclipse.virgo.medic.log.impl.CapturingAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>%msg</Pattern> + </layout> + </appender> + <appender-ref ref="STDOUT"/> + </logger> + +</configuration> diff --git a/org.eclipse.virgo.medic.core/src/test/resources/logback.xml b/org.eclipse.virgo.medic.core/src/test/resources/logback.xml new file mode 100644 index 0000000..f9049cf --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/resources/logback.xml @@ -0,0 +1,16 @@ +<configuration> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>Bundle1 [%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread %msg %ex%n</Pattern> + </layout> + </appender> + + <root level="debug"> + <appender-ref ref="STDOUT" /> + </root> + + <logger name="logger"> + <appender-ref ref="STDOUT" /> + </logger> + +</configuration> diff --git a/org.eclipse.virgo.medic.core/src/test/resources/messages.properties b/org.eclipse.virgo.medic.core/src/test/resources/messages.properties new file mode 100644 index 0000000..bf13b7d --- /dev/null +++ b/org.eclipse.virgo.medic.core/src/test/resources/messages.properties @@ -0,0 +1 @@ +ABC123=Bar diff --git a/org.eclipse.virgo.medic.core/template.mf b/org.eclipse.virgo.medic.core/template.mf new file mode 100644 index 0000000..a86964a --- /dev/null +++ b/org.eclipse.virgo.medic.core/template.mf @@ -0,0 +1,30 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.virgo.medic.core +Bundle-Name: Medic Core Implementation +Bundle-Vendor: SpringSource Inc. +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.virgo.medic.impl.MedicActivator +Import-Template: + org.eclipse.virgo.medic.*;version="[1.0.1,1.0.2)", + org.eclipse.virgo.util.osgi;version="${org.eclipse.virgo.util:[=.=.=, +1.0.0)}", + javax.jms;version="0";resolution:=optional, + javax.mail.*;version="0";resolution:=optional, + javax.management.*;version="0", + javax.naming;version="0", + javax.servlet.*;version="0";resolution:=optional, + javax.sql;version="0", + javax.xml.parsers;version="0", + org.aspectj.*;version="${org.aspectj:[=.=.=, +1.0.0)}", + org.osgi.framework;version="0", + org.osgi.service.*;version="0", + org.osgi.util.tracker;version="0", + org.slf4j.*;version="${org.slf4j:[=.=.=, +1.0.0)}", + org.xml.sax.*;version="0" +Excluded-Imports: + org.codehaus.janino.* +Export-Template: + org.slf4j.impl;version="1.5.10" +Excluded-Exports: + org.eclipse.virgo.medic.* +Medic-LoggingConfiguration: org.eclipse.virgo.medic diff --git a/org.eclipse.virgo.medic.integrationtest/.classpath b/org.eclipse.virgo.medic.integrationtest/.classpath new file mode 100644 index 0000000..b7196c2 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/.classpath @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" path="src/main/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-3.5.1.R35x_v20091005.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-sources-3.5.1.R35x_v20091005.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar" sourcepath="/MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-sources-1.5.10.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.classic/0.9.18/com.springsource.ch.qos.logback.classic-0.9.18.jar" sourcepath="/MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.classic/0.9.18/com.springsource.ch.qos.logback.classic-sources-0.9.18.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.core/0.9.18/com.springsource.ch.qos.logback.core-0.9.18.jar" sourcepath="/MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.core/0.9.18/com.springsource.ch.qos.logback.core-sources-0.9.18.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.virgo.test/org.eclipse.virgo.test.framework/2.1.0.D-20100420091951/org.eclipse.virgo.test.framework-2.1.0.D-20100420091951.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.virgo.test/org.eclipse.virgo.test.framework/2.1.0.D-20100420091951/org.eclipse.virgo.test.framework-sources-2.1.0.D-20100420091951.jar"/> + <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-1.2.4.jar" sourcepath="/MEDIC_IVY_CACHE/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-sources-1.2.4.jar"/> + <classpathentry kind="src" path="/org.eclipse.virgo.medic"> + <attributes> + <attribute name="org.eclipse.ajdt.aspectpath" value="org.eclipse.ajdt.aspectpath"/> + </attributes> + </classpathentry> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.common/2.1.0.D-20100420091708/org.eclipse.virgo.util.common-2.1.0.D-20100420091708.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.common/2.1.0.D-20100420091708/org.eclipse.virgo.util.common-sources-2.1.0.D-20100420091708.jar"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/org.eclipse.virgo.medic.integrationtest/.project b/org.eclipse.virgo.medic.integrationtest/.project new file mode 100644 index 0000000..445d599 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/.project @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.virgo.medic.integrationtest</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.ajdt.core.ajbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.springframework.ide.eclipse.core.springbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.springsource.server.ide.bundlor.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + <nature>com.springsource.server.ide.facet.core.bundlenature</nature> + <nature>org.springframework.ide.eclipse.core.springnature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.virgo.medic.integrationtest/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.medic.integrationtest/.settings/com.springsource.server.ide.bundlor.core.prefs new file mode 100644 index 0000000..08c417c --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/.settings/com.springsource.server.ide.bundlor.core.prefs @@ -0,0 +1,5 @@ +#Thu Nov 12 08:44:20 GMT 2009 +com.springsource.server.ide.bundlor.core.bundlor.generated.manifest.autoformatting=true +com.springsource.server.ide.bundlor.core.byte.code.scanning=true +com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions +eclipse.preferences.version=1 diff --git a/org.eclipse.virgo.medic.integrationtest/.springBeans b/org.eclipse.virgo.medic.integrationtest/.springBeans new file mode 100644 index 0000000..d079ca1 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/.springBeans @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beansProjectDescription> + <version>1</version> + <pluginVersion><![CDATA[2.2.4.RELEASE]]></pluginVersion> + <configSuffixes> + <configSuffix><![CDATA[xml]]></configSuffix> + </configSuffixes> + <enableImports><![CDATA[false]]></enableImports> + <configs> + </configs> + <configSets> + </configSets> +</beansProjectDescription> diff --git a/org.eclipse.virgo.medic.integrationtest/build.xml b/org.eclipse.virgo.medic.integrationtest/build.xml new file mode 100644 index 0000000..f22c9dd --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/build.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.medic.integrationtest"> + + <property file="${basedir}/../build.properties"/> + <property file="${basedir}/../build.versions"/> + <import file="${basedir}/../virgo-build/weaving/default.xml"/> + +</project> diff --git a/org.eclipse.virgo.medic.integrationtest/ivy.xml b/org.eclipse.virgo.medic.integrationtest/ivy.xml new file mode 100644 index 0000000..e2d576f --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/ivy.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}"/> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="compile->runtime"/> + <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="${org.slf4j}" conf="compile->runtime"/> + + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic" rev="latest.integration" conf="aspects->runtime"/> + <dependency org="org.aspectj" name="com.springsource.org.aspectj.runtime" rev="${org.aspectj}" conf="aspects->runtime"/> + + <dependency org="org.eclipse.virgo.util" name="org.eclipse.virgo.util.common" rev="${org.eclipse.virgo.util}" conf="test->runtime"/> + <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/> + <dependency org="org.eclipse.virgo.test" name="org.eclipse.virgo.test.framework" rev="${org.eclipse.virgo.test}" conf="test->runtime"/> + <dependency org="ch.qos.logback" name="com.springsource.ch.qos.logback.classic" rev="${ch.qos.logback}" conf="test->runtime"/> + <dependency org="org.apache.felix" name="org.apache.felix.configadmin" rev="${org.apache.felix.configadmin}" conf="test->runtime"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.medic.integrationtest/src/main/java/.gitignore b/org.eclipse.virgo.medic.integrationtest/src/main/java/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/main/java/.gitignore diff --git a/org.eclipse.virgo.medic.integrationtest/src/main/java/test/TestClass.java b/org.eclipse.virgo.medic.integrationtest/src/main/java/test/TestClass.java new file mode 100644 index 0000000..fb1de67 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/main/java/test/TestClass.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package test; + +public class TestClass { + + public void publicTest(boolean throwException) { + if (throwException) { + throw new RuntimeException(); + } + return; + } + + void packagePrivateTest(boolean throwException) { + if (throwException) { + throw new RuntimeException(); + } + return; + } + + @SuppressWarnings("unused") + private void privateTest(boolean throwException) { + if (throwException) { + throw new RuntimeException(); + } + return; + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/main/resources/.gitignore b/org.eclipse.virgo.medic.integrationtest/src/main/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/main/resources/.gitignore diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/dump/test/DumpIntegrationTests.java b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/dump/test/DumpIntegrationTests.java new file mode 100644 index 0000000..3ddddc8 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/dump/test/DumpIntegrationTests.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.slf4j.LoggerFactory; + +import org.eclipse.virgo.medic.dump.DumpGenerator; +import org.eclipse.virgo.test.framework.OsgiTestRunner; +import org.eclipse.virgo.test.framework.TestFrameworkUtils; + +@RunWith(OsgiTestRunner.class) +public class DumpIntegrationTests { + + private final BundleContext bundleContext = TestFrameworkUtils.getBundleContextForTestClass(getClass()); + + @Before + public void deleteDumps() { + File dumpsDir = new File("target", "dumps"); + if (dumpsDir.exists()) { + deleteRecursively(dumpsDir); + } + } + + private static void deleteRecursively(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files != null) { + for (File fileInDir : files) { + deleteRecursively(fileInDir); + } + } + } + assertTrue(file.delete()); + } + + @Test + public void dumpGeneratorAvailableFromServiceRegistry() { + ServiceReference serviceReference = this.bundleContext.getServiceReference(DumpGenerator.class.getName()); + assertNotNull(serviceReference); + } + + @Test + @SuppressWarnings("unchecked") + public void dumpDirectoryConfiguration() throws IOException, InterruptedException { + Configuration configuration = getConfiguration("org.eclipse.virgo.medic"); + assertNotNull(configuration); + + Dictionary properties = new Hashtable<String, String>(); + properties.put("dump.root.directory", "target/dumps/1"); + + configuration.update(properties); + + Thread.sleep(2000); + + ServiceReference serviceReference = this.bundleContext.getServiceReference(DumpGenerator.class.getName()); + DumpGenerator dumpGenerator = (DumpGenerator)this.bundleContext.getService(serviceReference); + dumpGenerator.generateDump("bleurgh"); + + File file = new File("target/dumps/1"); + assertTrue(file.exists()); + assertNotNull(file.list()); + assertEquals(1, file.list().length); + assertDumpContributionsMade(file.listFiles()[0], "heap.out", "summary.txt", "thread.txt"); + + properties.put("dump.root.directory", "target/dumps/2"); + configuration.update(properties); + + Thread.sleep(2000); + + dumpGenerator.generateDump("bleurgh"); + + file = new File("target/dumps/2"); + assertTrue(file.exists()); + assertNotNull(file.list()); + assertEquals(1, file.list().length); + assertDumpContributionsMade(file.listFiles()[0], "heap.out", "summary.txt", "thread.txt"); + } + + @Test + @SuppressWarnings("unchecked") + public void exclusionConfiguration() throws IOException, InterruptedException { + Configuration configuration = getConfiguration("org.eclipse.virgo.medic"); + assertNotNull(configuration); + + Dictionary properties = new Hashtable<String, String>(); + properties.put("dump.root.directory", "target/dumps/1"); + properties.put("dump.exclusions.bleurgh", "heap"); + + configuration.update(properties); + + Thread.sleep(2000); + + ServiceReference serviceReference = this.bundleContext.getServiceReference(DumpGenerator.class.getName()); + DumpGenerator dumpGenerator = (DumpGenerator)this.bundleContext.getService(serviceReference); + dumpGenerator.generateDump("bleurgh"); + + File file = new File("target/dumps/1"); + assertTrue(file.exists()); + assertNotNull(file.list()); + assertEquals(1, file.list().length); + assertDumpContributionsMade(file.listFiles()[0], "summary.txt", "thread.txt"); + } + + @Test + public void logDumpEnabled() throws IOException, InterruptedException { + Configuration configuration = getConfiguration("org.eclipse.virgo.medic"); + assertNotNull(configuration); + + Dictionary<String, String> properties = new Hashtable<String, String>(); + properties.put("dump.root.directory", "target/dumps/1"); + properties.put("log.dump.level", "ERROR"); + + configuration.update(properties); + + Thread.sleep(2000); + + LoggerFactory.getLogger(getClass()).info("Test"); + + ServiceReference serviceReference = this.bundleContext.getServiceReference(DumpGenerator.class.getName()); + DumpGenerator dumpGenerator = (DumpGenerator)this.bundleContext.getService(serviceReference); + dumpGenerator.generateDump("bleurgh"); + + File file = new File("target/dumps/1"); + assertTrue(file.exists()); + assertNotNull(file.list()); + assertEquals(1, file.list().length); + assertDumpContributionsMade(file.listFiles()[0], "heap.out", "summary.txt", "thread.txt", "log.log"); + } + + private Configuration getConfiguration(String pid) throws IOException { + ConfigurationAdmin configurationAdmin = getConfigurationAdmin(); + assertNotNull(configurationAdmin); + + return configurationAdmin.getConfiguration(pid); + } + + private ConfigurationAdmin getConfigurationAdmin() { + ServiceReference serviceReference = this.bundleContext.getServiceReference(ConfigurationAdmin.class.getName()); + assertNotNull(serviceReference); + + return (ConfigurationAdmin) this.bundleContext.getService(serviceReference); + } + + private static void assertDumpContributionsMade(File dumpDirectory, String... contributions) { + assertTrue(dumpDirectory.exists()); + File[] files = dumpDirectory.listFiles(); + assertEquals("Found '" + Arrays.toString(files) + "' but expected '" + Arrays.toString(contributions) + "'", contributions.length, files.length); + List<String> contributionsList = Arrays.asList(contributions); + for (File file : files) { + assertTrue("The file " + file.getName() + " was not expected", contributionsList.contains(file.getName())); + } + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/eventlog/test/EventLogIntegrationTests.java b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/eventlog/test/EventLogIntegrationTests.java new file mode 100644 index 0000000..4987221 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/eventlog/test/EventLogIntegrationTests.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; +import java.util.Locale; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.ServiceReference; + +import ch.qos.logback.classic.spi.LoggingEvent; + + +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.EventLoggerFactory; +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.log.appender.StubAppender; +import org.eclipse.virgo.test.framework.OsgiTestRunner; +import org.eclipse.virgo.test.framework.TestFrameworkUtils; + +@RunWith(OsgiTestRunner.class) +public class EventLogIntegrationTests { + + private BundleContext bundleContext; + + private Bundle messageBundle; + + @Before + public void before() throws BundleException { + Locale.setDefault(Locale.ITALIAN); + this.bundleContext = TestFrameworkUtils.getBundleContextForTestClass(getClass()); + messageBundle = this.bundleContext.installBundle("file:src/test/resources/message-bundle"); + this.bundleContext.installBundle("file:src/test/resources/message-fragment"); + } + + @Test + public void availabilityOfEventLoggerFactory() { + ServiceReference serviceReference = this.bundleContext.getServiceReference(EventLoggerFactory.class.getName()); + assertNotNull(serviceReference); + } + + @Test + public void availabilityOfEventLogger() { + ServiceReference serviceReference = this.bundleContext.getServiceReference(EventLogger.class.getName()); + assertNotNull(serviceReference); + } + + @Test + public void eventLoggingWithMessageFromCurrentBundle() { + ServiceReference serviceReference = this.bundleContext.getServiceReference(EventLogger.class.getName()); + assertNotNull(serviceReference); + EventLogger eventLogger = (EventLogger)this.bundleContext.getService(serviceReference); + eventLogger.log("1234", Level.WARNING, "orange", "lemon"); + + List<LoggingEvent> loggingEvent = StubAppender.getAndResetLoggingEvents("default-stub"); + assertEquals(1, loggingEvent.size()); + assertEquals("English orange and lemon", loggingEvent.get(0).getMessage()); + + loggingEvent = StubAppender.getAndResetLoggingEvents("localized-stub"); + assertEquals(1, loggingEvent.size()); + assertEquals("Italian orange and lemon", loggingEvent.get(0).getMessage()); + + } + + @Test + public void eventLoggingWithMessageFromFragment() throws Exception { + ServiceReference serviceReference = this.bundleContext.getServiceReference(EventLoggerFactory.class.getName()); + assertNotNull(serviceReference); + EventLoggerFactory eventLoggerFactory = (EventLoggerFactory)this.bundleContext.getService(serviceReference); + EventLogger eventLogger = eventLoggerFactory.createEventLogger(this.messageBundle); + eventLogger.log("3456", Level.WARNING, "oak", "sycamore"); + + List<LoggingEvent> loggingEvent = StubAppender.getAndResetLoggingEvents("default-stub"); + assertEquals(1, loggingEvent.size()); + assertEquals("Shared oak and sycamore", loggingEvent.get(0).getMessage()); + + loggingEvent = StubAppender.getAndResetLoggingEvents("localized-stub"); + assertEquals(1, loggingEvent.size()); + assertEquals("Shared oak and sycamore", loggingEvent.get(0).getMessage()); + } + + @Test + public void eventLoggingWithMessageFromSpecificBundle() throws Exception { + ServiceReference serviceReference = this.bundleContext.getServiceReference(EventLoggerFactory.class.getName()); + assertNotNull(serviceReference); + EventLoggerFactory eventLoggerFactory = (EventLoggerFactory)this.bundleContext.getService(serviceReference); + EventLogger eventLogger = eventLoggerFactory.createEventLogger(this.messageBundle); + eventLogger.log("2345", Level.WARNING, "potato", "cauliflower"); + + List<LoggingEvent> loggingEvent = StubAppender.getAndResetLoggingEvents("default-stub"); + assertEquals(1, loggingEvent.size()); + assertEquals("English potato and cauliflower", loggingEvent.get(0).getMessage()); + + loggingEvent = StubAppender.getAndResetLoggingEvents("localized-stub"); + assertEquals(1, loggingEvent.size()); + assertEquals("Italian potato and cauliflower", loggingEvent.get(0).getMessage()); + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/appender/StubAppender.java b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/appender/StubAppender.java new file mode 100644 index 0000000..68e2974 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/appender/StubAppender.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.appender; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class StubAppender extends AppenderBase<LoggingEvent> { + + private static Map<String, List<LoggingEvent>> loggingEvents = new HashMap<String, List<LoggingEvent>>(); + + @Override + protected void append(LoggingEvent eventObject) { + getLoggingEventsByName(name).add(eventObject); + } + + public static List<LoggingEvent> getAndResetLoggingEvents(String name) { + List<LoggingEvent> loggingEvents = getLoggingEventsByName(name); + List<LoggingEvent> response = new ArrayList<LoggingEvent>(loggingEvents); + loggingEvents.clear(); + return response; + } + + private static List<LoggingEvent> getLoggingEventsByName(String name) { + List<LoggingEvent> loggingEventsForName = loggingEvents.get(name); + if (loggingEventsForName == null) { + loggingEventsForName = new ArrayList<LoggingEvent>(); + loggingEvents.put(name, loggingEventsForName); + } + return loggingEventsForName; + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/EntryExitTraceTests.java b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/EntryExitTraceTests.java new file mode 100644 index 0000000..b476e80 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/EntryExitTraceTests.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.test; + +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Method; +import java.util.List; + +import org.eclipse.virgo.medic.log.appender.StubAppender; +import org.junit.BeforeClass; +import org.junit.Test; + +import test.TestClass; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.LoggingEvent; + + +public class EntryExitTraceTests { + + private final TestClass testClass = new TestClass(); + + @BeforeClass + public static void ensureConfiguredContextSelectorIsDefaultContextSelector() { + System.setProperty("logback.ContextSelector", "ch.qos.logback.classic.selector.DefaultContextSelector"); + } + + @Test + public void testPublicBefore() { + testClass.publicTest(false); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(0); + assertEquals(Level.INFO, event.getLevel()); + assertEquals("> public void test.TestClass.publicTest(boolean)", event.getFormattedMessage()); + assertEquals("public void test.TestClass.publicTest(boolean)", event.getArgumentArray()[1]); + } + + @Test + public void testPublicAfterReturn() { + testClass.publicTest(false); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(1); + assertEquals(Level.INFO, event.getLevel()); + assertEquals("< public void test.TestClass.publicTest(boolean)", event.getFormattedMessage()); + assertEquals("public void test.TestClass.publicTest(boolean)", event.getArgumentArray()[1]); + } + + @Test + public void testPublicAfterThrowing() { + try { + testClass.publicTest(true); + } catch (Exception e) { + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(1); + assertEquals(Level.INFO, event.getLevel()); + assertEquals("< public void test.TestClass.publicTest(boolean)", event.getFormattedMessage()); + assertEquals(RuntimeException.class.getName(), event.getThrowableProxy().getClassName()); + } + } + + @Test + public void testPackagePrivateBefore() throws Exception { + Method method = testClass.getClass().getDeclaredMethod("packagePrivateTest", boolean.class); + method.setAccessible(true); + method.invoke(testClass, false); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(0); + assertEquals(Level.DEBUG, event.getLevel()); + assertEquals("> void test.TestClass.packagePrivateTest(boolean)", event.getFormattedMessage()); + assertEquals("void test.TestClass.packagePrivateTest(boolean)", event.getArgumentArray()[1]); + } + + @Test + public void testPackagePrivateAfterReturn() throws Exception { + Method method = testClass.getClass().getDeclaredMethod("packagePrivateTest", boolean.class); + method.setAccessible(true); + method.invoke(testClass, false); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(1); + assertEquals(Level.DEBUG, event.getLevel()); + assertEquals("< void test.TestClass.packagePrivateTest(boolean)", event.getFormattedMessage()); + assertEquals("void test.TestClass.packagePrivateTest(boolean)", event.getArgumentArray()[1]); + } + + @Test + public void testPackagePrivateAfterThrowing() { + try { + Method method = testClass.getClass().getDeclaredMethod("packagePrivateTest", boolean.class); + method.setAccessible(true); + method.invoke(testClass, true); + } catch (Exception e) { + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(1); + assertEquals(Level.DEBUG, event.getLevel()); + assertEquals("< void test.TestClass.packagePrivateTest(boolean)", event.getFormattedMessage()); + assertEquals(RuntimeException.class.getName(), event.getThrowableProxy().getClassName()); + } + } + + @Test + public void testPrivateBefore() throws Exception { + Method method = testClass.getClass().getDeclaredMethod("privateTest", boolean.class); + method.setAccessible(true); + method.invoke(testClass, false); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(0); + assertEquals(Level.TRACE, event.getLevel()); + assertEquals("> private void test.TestClass.privateTest(boolean)", event.getFormattedMessage()); + assertEquals("private void test.TestClass.privateTest(boolean)", event.getArgumentArray()[1]); + } + + @Test + public void testPrivateAfterReturn() throws Exception { + Method method = testClass.getClass().getDeclaredMethod("privateTest", boolean.class); + method.setAccessible(true); + method.invoke(testClass, false); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(1); + assertEquals(Level.TRACE, event.getLevel()); + assertEquals("< private void test.TestClass.privateTest(boolean)", event.getFormattedMessage()); + assertEquals("private void test.TestClass.privateTest(boolean)", event.getArgumentArray()[1]); + } + + @Test + public void testPrivateAfterThrowing() { + try { + Method method = testClass.getClass().getDeclaredMethod("privateTest", boolean.class); + method.setAccessible(true); + method.invoke(testClass, true); + } catch (Exception e) { + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents(null); + assertEquals(2, loggingEvents.size()); + LoggingEvent event = loggingEvents.get(1); + assertEquals(Level.TRACE, event.getLevel()); + assertEquals("< private void test.TestClass.privateTest(boolean)", event.getFormattedMessage()); + assertEquals(RuntimeException.class.getName(), event.getThrowableProxy().getClassName()); + } + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/MedicLoggingIntegrationTests.java b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/MedicLoggingIntegrationTests.java new file mode 100644 index 0000000..2b8b5e8 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/MedicLoggingIntegrationTests.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; + + +import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher; +import org.eclipse.virgo.medic.log.appender.StubAppender; +import org.eclipse.virgo.test.framework.OsgiTestRunner; +import org.eclipse.virgo.test.framework.TestFrameworkUtils; + +@RunWith(OsgiTestRunner.class) +public class MedicLoggingIntegrationTests { + + private BundleContext bundleContext; + + @Before + public void before() { + this.bundleContext = TestFrameworkUtils.getBundleContextForTestClass(getClass()); + } + + @Test + public void test() throws BundleException { + bundleContext.installBundle("file:src/test/resources/test-bundle_1").start(); + assertEquals(1, StubAppender.getAndResetLoggingEvents("bundle1-stub").size()); + + bundleContext.installBundle("file:src/test/resources/test-bundle_2").start(); + assertEquals(1, StubAppender.getAndResetLoggingEvents("bundle2-stub").size()); + + bundleContext.installBundle("file:src/test/resources/test-bundle_3").start(); + assertEquals(1, StubAppender.getAndResetLoggingEvents("root-stub").size()); + } + + @Test + public void availabilityOfConfigurationPublisher() { + assertNotNull(bundleContext.getServiceReference(LoggingConfigurationPublisher.class.getName())); + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/PrintStreamWrappingTests.java b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/PrintStreamWrappingTests.java new file mode 100644 index 0000000..6b22ed8 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/java/org/eclipse/virgo/medic/log/test/PrintStreamWrappingTests.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.test; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +import ch.qos.logback.classic.spi.LoggingEvent; + +import org.eclipse.virgo.medic.log.appender.StubAppender; +import org.eclipse.virgo.test.framework.OsgiTestRunner; + + +@RunWith(OsgiTestRunner.class) +public class PrintStreamWrappingTests { + + @Test + @Ignore("Test fails on the CI server as it wraps System.out") + public void sysOutWrapping() { + System.out.println("Hello world!"); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents("root-stub"); + assertEquals(1, loggingEvents.size()); + assertEquals("Hello world!", loggingEvents.get(0).getMessage()); + } + + @Test + @Ignore("Test fails on the CI server as it wraps System.err") + public void sysErrWrapping() { + System.err.println("Hello world!"); + List<LoggingEvent> loggingEvents = StubAppender.getAndResetLoggingEvents("root-stub"); + assertEquals(1, loggingEvents.size()); + assertEquals("Hello world!", loggingEvents.get(0).getMessage()); + } +} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/EventLogMessages_en.properties b/org.eclipse.virgo.medic.integrationtest/src/test/resources/EventLogMessages_en.properties new file mode 100644 index 0000000..7a26421 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/EventLogMessages_en.properties @@ -0,0 +1 @@ +1234=English {} and {} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/EventLogMessages_it.properties b/org.eclipse.virgo.medic.integrationtest/src/test/resources/EventLogMessages_it.properties new file mode 100644 index 0000000..75634d3 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/EventLogMessages_it.properties @@ -0,0 +1 @@ +1234=Italian {} and {} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..97e747d --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/META-INF/MANIFEST.MF @@ -0,0 +1,23 @@ +Manifest-Version: 1.0 +Excluded-Import: ch.qos.logback.classic +Tool: Bundlor 1.0.0.M6 +Bundle-Name: Medic Logging Integration Tests +Bundle-SymbolicName: org.eclipse.virgo.medic.log.test +Import-Package: ch.qos.logback.classic.spi, + ch.qos.logback.core, + org.aspectj.lang;version="[1.6.6,2.0.0)", + org.aspectj.lang.reflect;version="[1.6.6,2.0.0)", + org.aspectj.runtime.internal;version="[1.6.6,2.0.0)", + org.aspectj.runtime.reflect;version="[1.6.6,2.0.0)", + org.eclipse.virgo.medic.dump;version="[1.0.1,1.0.2)", + org.eclipse.virgo.medic.eventlog;version="[1.0.1,1.0.2)", + org.eclipse.virgo.medic.log;version="[1.0.1,1.0.2)", + org.eclipse.virgo.medic.log.appender;version=0, + org.eclipse.virgo.test.framework, + org.junit, + org.junit.runner, + org.osgi.framework;version=0, + org.osgi.service.cm, + org.slf4j +Bundle-Version: 1.0.0 +Bundle-ManifestVersion: 2 diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/META-INF/test.config.properties b/org.eclipse.virgo.medic.integrationtest/src/test/resources/META-INF/test.config.properties new file mode 100644 index 0000000..8cfabaa --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/META-INF/test.config.properties @@ -0,0 +1,18 @@ +launcher.bundles=\ +file:../ivy-cache/repository/org.aspectj/com.springsource.org.aspectj.runtime/1.6.6.RELEASE/com.springsource.org.aspectj.runtime-1.6.6.RELEASE.jar@start,\ +file:../ivy-cache/repository/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar@start,\ +file:../ivy-cache/repository/org.eclipse.virgo.util/org.eclipse.virgo.util.common/2.1.0.D-20100420091708/org.eclipse.virgo.util.common-2.1.0.D-20100420091708.jar,\ +file:../ivy-cache/repository/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.1.0.D-20100420091708/org.eclipse.virgo.util.osgi-2.1.0.D-20100420091708.jar,\ +file:../ivy-cache/repository/org.eclipse.virgo.util/org.eclipse.virgo.util.parser.manifest/2.1.0.D-20100420091708/org.eclipse.virgo.util.parser.manifest-2.1.0.D-20100420091708.jar,\ +file:../ivy-cache/repository/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-1.2.4.jar@start,\ +file:../org.eclipse.virgo.medic/target/artifacts/org.eclipse.virgo.medic.jar@start,\ +file:../org.eclipse.virgo.medic.core/target/artifacts/org.eclipse.virgo.medic.core.jar@start,\ +file:src/test/resources/config-fragment,\ +file:src/test/resources/appender-fragment + +osgi.java.profile.bootdelegation=override +osgi.parentClassloader=fwk +osgi.context.bootdelegation=false +osgi.compatibility.bootdelegation=false +osgi.console=2401 +osgi.java.profile=file:src/test/resources/java6-server.profile diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/appender-fragment/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/appender-fragment/META-INF/MANIFEST.MF new file mode 100644 index 0000000..732bebd --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/appender-fragment/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: appender.fragment +Fragment-Host: org.eclipse.virgo.medic.core +Export-Package: org.eclipse.virgo.medic.log.appender + diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/appender-fragment/org/eclipse/virgo/medic/log/appender/StubAppender.class b/org.eclipse.virgo.medic.integrationtest/src/test/resources/appender-fragment/org/eclipse/virgo/medic/log/appender/StubAppender.class Binary files differnew file mode 100644 index 0000000..39b1b41 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/appender-fragment/org/eclipse/virgo/medic/log/appender/StubAppender.class diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/config-fragment/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/config-fragment/META-INF/MANIFEST.MF new file mode 100644 index 0000000..cb77330 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/config-fragment/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: config.fragment +Bundle-Vendor: SpringSource Inc. +Fragment-Host: org.eclipse.virgo.medic.core diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/config-fragment/logback.xml b/org.eclipse.virgo.medic.integrationtest/src/test/resources/config-fragment/logback.xml new file mode 100644 index 0000000..1332bac --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/config-fragment/logback.xml @@ -0,0 +1,42 @@ +<configuration> + + <appender name="localized-console" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>Localized: %-24.24thread <%X{medic.eventCode}> %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="default-console" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>Default: %-24.24thread <%X{medic.eventCode}> %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="root-console" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>Root: [%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="root-stub" class="org.eclipse.virgo.medic.log.appender.StubAppender"/> + + <appender name="default-stub" class="org.eclipse.virgo.medic.log.appender.StubAppender"/> + + <appender name="localized-stub" class="org.eclipse.virgo.medic.log.appender.StubAppender"/> + + <logger name="org.eclipse.virgo.medic.eventlog.localized"> + <appender-ref ref="localized-console" /> + <appender-ref ref="localized-stub" /> + </logger> + + <logger name="org.eclipse.virgo.medic.eventlog.default"> + <appender-ref ref="default-console" /> + <appender-ref ref="default-stub" /> + </logger> + + <root level="debug"> + <appender-ref ref="root-stub"/> + <appender-ref ref="root-console"/> + </root> + +</configuration> diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/java6-server.profile b/org.eclipse.virgo.medic.integrationtest/src/test/resources/java6-server.profile new file mode 100644 index 0000000..9a72f39 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/java6-server.profile @@ -0,0 +1,165 @@ +org.osgi.framework.system.packages = \ + javax.accessibility,\ + javax.crypto,\ + javax.crypto.interfaces,\ + javax.crypto.spec,\ + javax.imageio,\ + javax.imageio.event,\ + javax.imageio.metadata,\ + javax.imageio.plugins.bmp,\ + javax.imageio.plugins.jpeg,\ + javax.imageio.spi,\ + javax.imageio.stream,\ + javax.jws,\ + javax.jws;version="2.0",\ + javax.jws.soap,\ + javax.jws.soap;version="2.0",\ + javax.management,\ + javax.management.loading,\ + javax.management.modelmbean,\ + javax.management.monitor,\ + javax.management.openmbean,\ + javax.management.relation,\ + javax.management.remote,\ + javax.management.remote.rmi,\ + javax.management.timer,\ + javax.naming,\ + javax.naming.directory,\ + javax.naming.event,\ + javax.naming.ldap,\ + javax.naming.spi,\ + javax.net,\ + javax.net.ssl,\ + javax.print,\ + javax.print.attribute,\ + javax.print.attribute.standard,\ + javax.print.event,\ + javax.rmi,\ + javax.rmi.CORBA,\ + javax.rmi.ssl,\ + javax.security.auth,\ + javax.security.auth.callback,\ + javax.security.auth.kerberos,\ + javax.security.auth.login,\ + javax.security.auth.spi,\ + javax.security.auth.x500,\ + javax.security.cert,\ + javax.security.sasl,\ + javax.sound.midi,\ + javax.sound.midi.spi,\ + javax.sound.sampled,\ + javax.sound.sampled.spi,\ + javax.sql,\ + javax.sql.rowset,\ + javax.sql.rowset.serial,\ + javax.sql.rowset.spi,\ + javax.swing,\ + javax.swing.border,\ + javax.swing.colorchooser,\ + javax.swing.event,\ + javax.swing.filechooser,\ + javax.swing.plaf,\ + javax.swing.plaf.basic,\ + javax.swing.plaf.metal,\ + javax.swing.plaf.multi,\ + javax.swing.plaf.synth,\ + javax.swing.table,\ + javax.swing.text,\ + javax.swing.text.html,\ + javax.swing.text.html.parser,\ + javax.swing.text.rtf,\ + javax.swing.tree,\ + javax.swing.undo,\ + javax.transaction,\ + javax.transaction;version="1.0.1",\ + javax.transaction;version="1.1.0",\ + javax.transaction.xa,\ + javax.transaction.xa;version="1.0.1",\ + javax.transaction.xa;version="1.1.0",\ + javax.xml,\ + javax.xml;version="1.0.1",\ + javax.xml.bind,\ + javax.xml.bind;version="2.0",\ + javax.xml.bind.annotation,\ + javax.xml.bind.annotation;version="2.0",\ + javax.xml.bind.annotation.adapters,\ + javax.xml.bind.annotation.adapters;version="2.0",\ + javax.xml.bind.attachment,\ + javax.xml.bind.attachment;version="2.0",\ + javax.xml.bind.helpers,\ + javax.xml.bind.helpers;version="2.0",\ + javax.xml.bind.util,\ + javax.xml.bind.util;version="2.0",\ + javax.xml.datatype,\ + javax.xml.namespace,\ + javax.xml.parsers,\ + javax.xml.soap,\ + javax.xml.soap;version="1.3.0",\ + javax.xml.stream,\ + javax.xml.stream;version="1.0.1",\ + javax.xml.stream.events,\ + javax.xml.stream.events;version="1.0.1",\ + javax.xml.stream.util,\ + javax.xml.stream.util;version="1.0.1",\ + javax.xml.transform,\ + javax.xml.transform.dom,\ + javax.xml.transform.sax,\ + javax.xml.transform.stream,\ + javax.xml.validation,\ + javax.xml.xpath,\ + org.ietf.jgss,\ + org.omg.CORBA,\ + org.omg.CORBA_2_3,\ + org.omg.CORBA_2_3.portable,\ + org.omg.CORBA.DynAnyPackage,\ + org.omg.CORBA.ORBPackage,\ + org.omg.CORBA.portable,\ + org.omg.CORBA.TypeCodePackage,\ + org.omg.CosNaming,\ + org.omg.CosNaming.NamingContextExtPackage,\ + org.omg.CosNaming.NamingContextPackage,\ + org.omg.Dynamic,\ + org.omg.DynamicAny,\ + org.omg.DynamicAny.DynAnyFactoryPackage,\ + org.omg.DynamicAny.DynAnyPackage,\ + org.omg.IOP,\ + org.omg.IOP.CodecFactoryPackage,\ + org.omg.IOP.CodecPackage,\ + org.omg.Messaging,\ + org.omg.PortableInterceptor,\ + org.omg.PortableInterceptor.ORBInitInfoPackage,\ + org.omg.PortableServer,\ + org.omg.PortableServer.CurrentPackage,\ + org.omg.PortableServer.POAManagerPackage,\ + org.omg.PortableServer.POAPackage,\ + org.omg.PortableServer.portable,\ + org.omg.PortableServer.ServantLocatorPackage,\ + org.omg.SendingContext,\ + org.omg.stub.java.rmi,\ + org.w3c.dom,\ + org.w3c.dom.bootstrap,\ + org.w3c.dom.css,\ + org.w3c.dom.events,\ + org.w3c.dom.html,\ + org.w3c.dom.ls,\ + org.w3c.dom.ranges,\ + org.w3c.dom.stylesheets,\ + org.w3c.dom.traversal,\ + org.w3c.dom.views ,\ + org.xml.sax,\ + org.xml.sax.ext,\ + org.xml.sax.helpers +org.osgi.framework.bootdelegation = \ + com_cenqua_clover,\ + com.cenqua.*,\ + com.yourkit.*,\ + sun.reflect,\ + sun.reflect.* +org.osgi.framework.executionenvironment = \ + OSGi/Minimum-1.0,\ + OSGi/Minimum-1.1,\ + J2SE-1.3,\ + J2SE-1.4,\ + J2SE-1.5,\ + J2SE-1.6 +osgi.java.profile.name = SpringSource-dm-Server-Java6 diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/logback-test.xml b/org.eclipse.virgo.medic.integrationtest/src/test/resources/logback-test.xml new file mode 100644 index 0000000..a47881b --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/logback-test.xml @@ -0,0 +1,5 @@ +<configuration> + <root level="trace"> + <appender class="org.eclipse.virgo.medic.log.appender.StubAppender"/> + </root> +</configuration> diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/EventLogMessages_en.properties b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/EventLogMessages_en.properties new file mode 100644 index 0000000..54b2ddf --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/EventLogMessages_en.properties @@ -0,0 +1 @@ +2345=English {} and {} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/EventLogMessages_it.properties b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/EventLogMessages_it.properties new file mode 100644 index 0000000..09d1f6e --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/EventLogMessages_it.properties @@ -0,0 +1 @@ +2345=Italian {} and {} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/META-INF/MANIFEST.MF new file mode 100644 index 0000000..c4c505c --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-bundle/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Bundle-SymbolicName: message.bundle +Bundle-ManifestVersion: 2 diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-fragment/EventLogMessages.properties b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-fragment/EventLogMessages.properties new file mode 100644 index 0000000..3e78bfa --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-fragment/EventLogMessages.properties @@ -0,0 +1 @@ +3456=Shared {} and {} diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-fragment/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-fragment/META-INF/MANIFEST.MF new file mode 100644 index 0000000..49ef7bc --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/message-fragment/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0
+Bundle-SymbolicName: message.fragment
+Bundle-ManifestVersion: 2
+Fragment-Host: message.bundle
+
diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/META-INF/MANIFEST.MF new file mode 100644 index 0000000..2544d2d --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: test.bundle +Import-Package: org.osgi.framework, org.slf4j, org.slf4j.spi +Bundle-Activator: test.TestActivator +Bundle-Version: 1.0 diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/logback.xml b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/logback.xml new file mode 100644 index 0000000..2862b7b --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/logback.xml @@ -0,0 +1,15 @@ +<configuration> + <appender name="STDOUT" class="org.eclipse.virgo.medic.log.logback.ReroutingAwareConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="bundle1-stub" class="org.eclipse.virgo.medic.log.appender.StubAppender"/> + + <root level="debug"> + <appender-ref ref="STDOUT" /> + <appender-ref ref="bundle1-stub" /> + </root> + +</configuration> diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/test/TestActivator.class b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/test/TestActivator.class Binary files differnew file mode 100644 index 0000000..2f77b0a --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_1/test/TestActivator.class diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/META-INF/MANIFEST.MF new file mode 100644 index 0000000..a3d659b --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: test.bundle +Import-Package: org.osgi.framework, org.slf4j, org.slf4j.spi +Bundle-Activator: test.TestActivator +Bundle-Version: 2.0 diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/logback.xml b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/logback.xml new file mode 100644 index 0000000..2f914b7 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/logback.xml @@ -0,0 +1,15 @@ +<configuration> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <Pattern>Bundle2 [%d{yyyy-MM-dd HH:mm:ss.SSS}] %-24.24thread %msg %ex%n</Pattern> + </layout> + </appender> + + <appender name="bundle2-stub" class="org.eclipse.virgo.medic.log.appender.StubAppender"/> + + <root level="debug"> + <appender-ref ref="STDOUT" /> + <appender-ref ref="bundle2-stub"/> + </root> + +</configuration> diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/test/TestActivator.class b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/test/TestActivator.class Binary files differnew file mode 100644 index 0000000..2f77b0a --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_2/test/TestActivator.class diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_3/META-INF/MANIFEST.MF b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_3/META-INF/MANIFEST.MF new file mode 100644 index 0000000..8789b85 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_3/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: test.bundle +Import-Package: org.osgi.framework, org.slf4j, org.slf4j.spi +Bundle-Activator: test.TestActivator +Bundle-Version: 3.0 diff --git a/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_3/test/TestActivator.class b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_3/test/TestActivator.class Binary files differnew file mode 100644 index 0000000..2f77b0a --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/src/test/resources/test-bundle_3/test/TestActivator.class diff --git a/org.eclipse.virgo.medic.integrationtest/template.mf b/org.eclipse.virgo.medic.integrationtest/template.mf new file mode 100644 index 0000000..05769c2 --- /dev/null +++ b/org.eclipse.virgo.medic.integrationtest/template.mf @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.virgo.medic.log.test +Bundle-Name: Medic Logging Integration Tests +Bundle-Version: 1.0.0 +Import-Template: + org.eclipse.virgo.medic.*;version="[1.0.1, 1.0.2)", + org.aspectj.*;version="${org.aspectj:[=.=.= , +1.0.0)}" +Import-Package: + org.osgi.framework;version="0", + org.eclipse.virgo.medic.log.appender;version="0" +Excluded-Exports: + * +Excluded-Imports: + ch.qos.logback.classic diff --git a/org.eclipse.virgo.medic.test/.classpath b/org.eclipse.virgo.medic.test/.classpath new file mode 100644 index 0000000..ed078d7 --- /dev/null +++ b/org.eclipse.virgo.medic.test/.classpath @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" path="src/main/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/> + <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.medic"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/org.eclipse.virgo.medic.test/.project b/org.eclipse.virgo.medic.test/.project new file mode 100644 index 0000000..723469b --- /dev/null +++ b/org.eclipse.virgo.medic.test/.project @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.virgo.medic.test</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.springframework.ide.eclipse.core.springbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.springsource.server.ide.bundlor.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>com.springsource.server.ide.facet.core.bundlenature</nature> + <nature>org.springframework.ide.eclipse.core.springnature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.virgo.medic.test/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.medic.test/.settings/com.springsource.server.ide.bundlor.core.prefs new file mode 100644 index 0000000..03d978a --- /dev/null +++ b/org.eclipse.virgo.medic.test/.settings/com.springsource.server.ide.bundlor.core.prefs @@ -0,0 +1,5 @@ +#Thu Nov 12 08:44:28 GMT 2009 +com.springsource.server.ide.bundlor.core.bundlor.generated.manifest.autoformatting=true +com.springsource.server.ide.bundlor.core.byte.code.scanning=true +com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions +eclipse.preferences.version=1 diff --git a/org.eclipse.virgo.medic.test/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.eclipse.virgo.medic.test/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..801f856 --- /dev/null +++ b/org.eclipse.virgo.medic.test/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="com.springsource.server.bundle" version="1.0"/> +</faceted-project> diff --git a/org.eclipse.virgo.medic.test/.springBeans b/org.eclipse.virgo.medic.test/.springBeans new file mode 100644 index 0000000..5152991 --- /dev/null +++ b/org.eclipse.virgo.medic.test/.springBeans @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beansProjectDescription> + <version>1</version> + <pluginVersion><![CDATA[2.2.5.M1]]></pluginVersion> + <configSuffixes> + <configSuffix><![CDATA[xml]]></configSuffix> + </configSuffixes> + <enableImports><![CDATA[false]]></enableImports> + <configs> + </configs> + <configSets> + </configSets> +</beansProjectDescription> diff --git a/org.eclipse.virgo.medic.test/build.xml b/org.eclipse.virgo.medic.test/build.xml new file mode 100644 index 0000000..6cd0295 --- /dev/null +++ b/org.eclipse.virgo.medic.test/build.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.medic.test"> + + <property file="${basedir}/../build.properties"/> + <property file="${basedir}/../build.versions"/> + <import file="${basedir}/../virgo-build/standard/default.xml"/> + +</project> diff --git a/org.eclipse.virgo.medic.test/ivy.xml b/org.eclipse.virgo.medic.test/ivy.xml new file mode 100644 index 0000000..43762ad --- /dev/null +++ b/org.eclipse.virgo.medic.test/ivy.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}"/> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic" rev="latest.integration" conf="compile->compile"/> + <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.medic.test/src/main/java/org/eclipse/virgo/medic/test/eventlog/LoggedEvent.java b/org.eclipse.virgo.medic.test/src/main/java/org/eclipse/virgo/medic/test/eventlog/LoggedEvent.java new file mode 100644 index 0000000..72db818 --- /dev/null +++ b/org.eclipse.virgo.medic.test/src/main/java/org/eclipse/virgo/medic/test/eventlog/LoggedEvent.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.test.eventlog; + +import java.io.PrintStream; + +import org.eclipse.virgo.medic.eventlog.Level; + + +public class LoggedEvent { + + private final String code; + + private final Level level; + + private final Throwable throwable; + + private final Object[] inserts; + + LoggedEvent(String code, Level level, Object... inserts) { + this(code, level, null, inserts); + } + + LoggedEvent(String code, Level level, Throwable throwable, Object... inserts) { + this.code = code; + this.level = level; + this.throwable = throwable; + this.inserts = inserts.clone(); + } + + /** + * Returns the code of the event that was logged. + * + * @return the logged event's code. + */ + public String getCode() { + return this.code; + } + + /** + * Returns the level of the event that was logged. + * + * @return the logged event's level + */ + public Level getLevel() { + return this.level; + } + + /** + * Returns the <code>Throwable</code> that was logged as part of the event, or <code>null</code> if no + * <code>Throwable</code> was logged + * + * @return The logged <code>Throwable</code> + */ + public Throwable getThrowable() { + return throwable; + } + + /** + * Returns the inserts that were logged, or an empty array if no inserts were logged. + * + * @return The logged inserts, never <code>null</code>. + */ + public Object[] getInserts() { + return inserts.clone(); + } + + /** + * Print (to outStr) a human-readable form of the LoggedEvent, without fancy formatting. + * + * @param printStream where to print it + */ + public void print(PrintStream printStream) { + printStream.print(String.format("Code: '%s' Level: '%s'", this.code, String.valueOf(this.level))); + printInserts(printStream); + if (this.throwable!=null) { + printStream.print(" Exception: "); + this.throwable.printStackTrace(printStream); + } + } + + /** + * Print inserts. + * + * @param outStr where to print them + */ + private void printInserts(PrintStream outStr) { + if (inserts.length != 0) { + outStr.print(String.format(" Inserts: {'%s'", String.valueOf(this.inserts[0]))); + for (int ins = 1; ins < this.inserts.length; ++ins) { + outStr.print(String.format(", '%s'", String.valueOf(this.inserts[ins]))); + } + outStr.print("}"); + } + } +} diff --git a/org.eclipse.virgo.medic.test/src/main/java/org/eclipse/virgo/medic/test/eventlog/MockEventLogger.java b/org.eclipse.virgo.medic.test/src/main/java/org/eclipse/virgo/medic/test/eventlog/MockEventLogger.java new file mode 100644 index 0000000..6f7903c --- /dev/null +++ b/org.eclipse.virgo.medic.test/src/main/java/org/eclipse/virgo/medic/test/eventlog/MockEventLogger.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.test.eventlog; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.virgo.medic.eventlog.EventLogger; +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.eventlog.LogEvent; + + +/** + * A mock implementation of {@link EventLogger} for testing purposes. The events that have been logged can be accessed + * by calling {@link #getLoggedEvents()}.<br/> + * This implementation saves all events for subsequent analysis, and has an option to clear the log for re-use.<br/> + * This version also has an operation for asserting that the sequence of events matches a supplied array. This is for + * convenient unit tests. + * <p/> + * + * <strong>Concurrent Semantics:</strong><br/> + * Thread-safe during logging, but not for retrieval and re-initialisation. + */ +public class MockEventLogger implements EventLogger { + + private final List<LoggedEvent> loggedEvents = new CopyOnWriteArrayList<LoggedEvent>(); + + private final boolean noisy; + + private volatile boolean called = false; + + private final PrintStream printStream; + + public MockEventLogger() { + this(false, null); + } + + public MockEventLogger(boolean noisy, PrintStream printStream) { + this.noisy = noisy; + this.printStream = printStream; + } + + public void log(LogEvent logEvent, Object... inserts) { + this.log(logEvent.getEventCode(), logEvent.getLevel(), inserts); + } + + public void log(LogEvent logEvent, Throwable throwable, Object... inserts) { + this.log(logEvent.getEventCode(), logEvent.getLevel(), throwable, inserts); + } + + public void log(String code, Level level, Object... inserts) { + LoggedEvent loggedEvent = new LoggedEvent(code, level, inserts); + this.loggedEvents.add(loggedEvent); + this.called = true; + if (noisy) { + loggedEvent.print(this.printStream); + } + } + + public void log(String code, Level level, Throwable throwable, Object... inserts) { + LoggedEvent loggedEvent = new LoggedEvent(code, level, throwable, inserts); + this.loggedEvents.add(loggedEvent); + this.called = true; + if (noisy) { + loggedEvent.print(this.printStream); + } + } + + /** + * Returns a <code>List</code> of the events that have been logged. The order of the items in the list corresponds + * to the order in which the events were logged. If no events have been logged an empty list is returned. + * + * @return the logged events + */ + public List<LoggedEvent> getLoggedEvents() { + return this.loggedEvents; + } + + /** + * @return true if this EventLogger has been called since (re)initialisation. + */ + public boolean getCalled() { + return this.called; + } + + /** + * Reinitialise this EventLogger. + */ + public void reinitialise() { + this.called = false; + this.loggedEvents.clear(); + } + + /** + * Helper method for unit tests to check sequence of logged events after a test. + * + * @param codes sequence of message codes expected + * @return true iff sequence of codes matches logged events exactly + */ + public boolean isLogged(String... codes) { + if (this.loggedEvents.size() != codes.length) { + return false; + } + int index = 0; + for (String code : codes) { + if (!code.equals(this.loggedEvents.get(index++).getCode())) { + return false; + } + } + return true; + } + + /** + * Helper method for unit tests to check superset of logged events after a test. + * + * @param codes sequence of message codes expected to be contained in logged events (in any order) + * @return true iff the codes are all in the saved {@link LoggedEvent}s. + */ + public boolean containsLogged(String... codes) { + List<String> codeList = new ArrayList<String>(); + for (LoggedEvent event : this.loggedEvents) { + codeList.add(event.getCode()); + } + for (String code : codes) { + if (!codeList.contains(code)){ + return false; + } + } + return true; + } + + /** + * Helper method for unit tests to retrieve specific logged events from saved events. + * + * @param codes sequence of message codes to have events extracted, in order. + * @return LoggedEvents with supplied codes in same sequence from log. + */ + public List<LoggedEvent> getEventsWithCodes(String... codes) { + List<LoggedEvent> eventList = new ArrayList<LoggedEvent>(); + int eventIndex = 0; + int loggedEventsSize = this.loggedEvents.size(); + for (String code : codes) { + while (eventIndex < loggedEventsSize) { + LoggedEvent loggedEvent = this.loggedEvents.get(eventIndex++); + if (code.equals(loggedEvent.getCode())) { + eventList.add(loggedEvent); + break; + } + } + } + return eventList; + } +} diff --git a/org.eclipse.virgo.medic.test/src/main/resources/.gitignore b/org.eclipse.virgo.medic.test/src/main/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.test/src/main/resources/.gitignore diff --git a/org.eclipse.virgo.medic.test/src/test/java/org/eclipse/virgo/medic/test/eventlog/LoggedEventTests.java b/org.eclipse.virgo.medic.test/src/test/java/org/eclipse/virgo/medic/test/eventlog/LoggedEventTests.java new file mode 100644 index 0000000..7ad8333 --- /dev/null +++ b/org.eclipse.virgo.medic.test/src/test/java/org/eclipse/virgo/medic/test/eventlog/LoggedEventTests.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.test.eventlog; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringWriter; +import java.io.Writer; + +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.test.eventlog.LoggedEvent; +import org.junit.Test; + + +public class LoggedEventTests { + + @Test + public void print() { + StringWriter printedWriter = new StringWriter(); + PrintStream printStream = new PrintStream(new WriterOutputStream(printedWriter)); + + new LoggedEvent("code", Level.WARNING, "a", 5, true).print(printStream); + + String printed = printedWriter.toString(); + assertEquals("Code: 'code' Level: 'WARNING' Inserts: {'a', '5', 'true'}", printed); + } + + @Test + public void printWithOneInsert() { + StringWriter printedWriter = new StringWriter(); + PrintStream printStream = new PrintStream(new WriterOutputStream(printedWriter)); + + new LoggedEvent("code", Level.WARNING, 5).print(printStream); + + String printed = printedWriter.toString(); + System.out.println(printed); + assertEquals("Code: 'code' Level: 'WARNING' Inserts: {'5'}", printed); + } + + @Test + public void printWithNoInserts() { + StringWriter printedWriter = new StringWriter(); + PrintStream printStream = new PrintStream(new WriterOutputStream(printedWriter)); + + new LoggedEvent("code", Level.WARNING).print(printStream); + + String printed = printedWriter.toString(); + System.out.println(printed); + assertEquals("Code: 'code' Level: 'WARNING'", printed); + } + + private static final class WriterOutputStream extends OutputStream { + + private final Writer writer; + + private WriterOutputStream(Writer writer) { + this.writer = writer; + } + + @Override + public void write(int b) throws IOException { + writer.write(b); + } + } +} diff --git a/org.eclipse.virgo.medic.test/src/test/java/org/eclipse/virgo/medic/test/eventlog/MockEventLoggerTests.java b/org.eclipse.virgo.medic.test/src/test/java/org/eclipse/virgo/medic/test/eventlog/MockEventLoggerTests.java new file mode 100644 index 0000000..933e5c0 --- /dev/null +++ b/org.eclipse.virgo.medic.test/src/test/java/org/eclipse/virgo/medic/test/eventlog/MockEventLoggerTests.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.test.eventlog; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.virgo.medic.eventlog.Level; +import org.eclipse.virgo.medic.test.eventlog.LoggedEvent; +import org.eclipse.virgo.medic.test.eventlog.MockEventLogger; +import org.junit.Test; + + +public class MockEventLoggerTests { + + private final MockEventLogger eventLogger = new MockEventLogger(); + + @Test + public void emptyList() { + List<LoggedEvent> loggedEvents = this.eventLogger.getLoggedEvents(); + assertNotNull(loggedEvents); + assertEquals(0, loggedEvents.size()); + } + + @Test + public void eventWithoutThrowableWithInserts() { + this.eventLogger.log("123", Level.INFO, "a", "b", true); + + List<LoggedEvent> loggedEvents = this.eventLogger.getLoggedEvents(); + assertNotNull(loggedEvents); + assertEquals(1, loggedEvents.size()); + + LoggedEvent loggedEvent = loggedEvents.get(0); + assertEquals("123", loggedEvent.getCode()); + assertEquals(Level.INFO, loggedEvent.getLevel()); + assertNull(loggedEvent.getThrowable()); + assertArrayEquals(new Object[] { "a", "b", true }, loggedEvent.getInserts()); + } + + @Test + public void eventWithoutThrowableWithoutInserts() { + this.eventLogger.log("234", Level.ERROR); + + List<LoggedEvent> loggedEvents = this.eventLogger.getLoggedEvents(); + assertNotNull(loggedEvents); + assertEquals(1, loggedEvents.size()); + + LoggedEvent loggedEvent = loggedEvents.get(0); + assertEquals("234", loggedEvent.getCode()); + assertEquals(Level.ERROR, loggedEvent.getLevel()); + assertNull(loggedEvent.getThrowable()); + assertNotNull(loggedEvent.getInserts()); + assertEquals(0, loggedEvent.getInserts().length); + } + + @Test + public void eventWithThrowableWithInserts() { + Throwable throwable = new Throwable(); + this.eventLogger.log("345", Level.WARNING, throwable, "a", "b", true); + + List<LoggedEvent> loggedEvents = this.eventLogger.getLoggedEvents(); + assertNotNull(loggedEvents); + assertEquals(1, loggedEvents.size()); + + LoggedEvent loggedEvent = loggedEvents.get(0); + assertEquals("345", loggedEvent.getCode()); + assertEquals(Level.WARNING, loggedEvent.getLevel()); + assertEquals(throwable, loggedEvent.getThrowable()); + assertArrayEquals(new Object[] { "a", "b", true }, loggedEvent.getInserts()); + } + + @Test + public void eventWithThrowableWithoutInserts() { + Throwable throwable = new Throwable(); + this.eventLogger.log("456", Level.ERROR, throwable); + + List<LoggedEvent> loggedEvents = this.eventLogger.getLoggedEvents(); + assertNotNull(loggedEvents); + assertEquals(1, loggedEvents.size()); + + LoggedEvent loggedEvent = loggedEvents.get(0); + assertEquals("456", loggedEvent.getCode()); + assertEquals(Level.ERROR, loggedEvent.getLevel()); + assertEquals(throwable, loggedEvent.getThrowable()); + assertNotNull(loggedEvent.getInserts()); + assertEquals(0, loggedEvent.getInserts().length); + } + + @Test + public void multipleEventsIncludingDuplicates() { + this.eventLogger.log("123", Level.INFO); + this.eventLogger.log("234", Level.INFO); + this.eventLogger.log("345", Level.INFO); + this.eventLogger.log("345", Level.INFO); + this.eventLogger.log("123", Level.INFO); + + List<LoggedEvent> loggedEvents = this.eventLogger.getLoggedEvents(); + assertNotNull(loggedEvents); + assertEquals(5, loggedEvents.size()); + assertLoggedEventMatch(loggedEvents.get(0), "123", null, null); + assertLoggedEventMatch(loggedEvents.get(1), "234", null, null); + assertLoggedEventMatch(loggedEvents.get(2), "345", null, null); + assertLoggedEventMatch(loggedEvents.get(3), "345", null, null); + assertLoggedEventMatch(loggedEvents.get(4), "123", null, null); + assertTrue("Correct event code sequence not detected", this.eventLogger.isLogged("123", "234", "345", "345", "123")); + assertFalse("Incorrect event code sequence not detected", this.eventLogger.isLogged("123", "234", "345", "123")); + assertFalse("Incorrect event code sequence not detected", this.eventLogger.isLogged("123", "234", "345", "123", "123")); + } + + @Test + public void retrieveEventSequenceWithCodes() { + this.eventLogger.log("123", Level.INFO, new Integer(1)); + this.eventLogger.log("234", Level.INFO, new Integer(2)); + this.eventLogger.log("345", Level.INFO, new Integer(3)); + this.eventLogger.log("345", Level.INFO, new Integer(4)); + this.eventLogger.log("123", Level.INFO, new Integer(5)); + + List<LoggedEvent> loggedEvents = this.eventLogger.getEventsWithCodes("345", "123", "345", "xyz"); + assertNotNull(loggedEvents); + assertEquals(2, loggedEvents.size()); + assertLoggedEventMatch(loggedEvents.get(0), "345", Level.INFO, null, 3); + assertLoggedEventMatch(loggedEvents.get(1), "123", Level.INFO, null, 5); + } + + @Test + public void containsEventCodeSequence() { + this.eventLogger.log("123", Level.INFO); + this.eventLogger.log("234", Level.INFO); + this.eventLogger.log("345", Level.INFO); + this.eventLogger.log("345", Level.INFO); + this.eventLogger.log("123", Level.INFO); + + assertTrue("Failed to detect codes 234, 123, 345", this.eventLogger.containsLogged("234","123","345")); + assertFalse("Erroneously detected all codes 123, xyz, 234", this.eventLogger.containsLogged("123", "xyz", "234")); + this.eventLogger.reinitialise(); + assertFalse("Detected code 123 after reinitialisation", this.eventLogger.containsLogged("123")); + assertTrue("eventLogger not empty after reinitialisation", this.eventLogger.getLoggedEvents().isEmpty()); + } + + private static void assertLoggedEventMatch(LoggedEvent loggedEvent, String code, Level level, Throwable throwable, Object... inserts) { + assertNotNull(loggedEvent); + assertEquals("LoggedEvent code", code, loggedEvent.getCode()); + if (level != null) { + assertEquals("LoggedEvent level in " + code, level, loggedEvent.getLevel()); + } + assertEquals("LoggedEvent throwable in " + code, throwable, loggedEvent.getThrowable()); + assertEquals("Number of inserts in " + code, inserts.length, loggedEvent.getInserts().length); + int index = 0; + for (Object insert : inserts) { + assertEquals("LoggedEvent insert in " + code, insert, loggedEvent.getInserts()[index++]); + } + } +} diff --git a/org.eclipse.virgo.medic.test/src/test/resources/.gitignore b/org.eclipse.virgo.medic.test/src/test/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.test/src/test/resources/.gitignore diff --git a/org.eclipse.virgo.medic.test/template.mf b/org.eclipse.virgo.medic.test/template.mf new file mode 100644 index 0000000..fb6042a --- /dev/null +++ b/org.eclipse.virgo.medic.test/template.mf @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.virgo.medic.eventlog.test +Bundle-Name: Medic Event Log Test Bundle +Bundle-Vendor: SpringSource Inc. +Bundle-Version: 1.0.0 +Import-Template: + org.eclipse.virgo.medic.*;version="0" +Excluded-Imports: + org.junit.* diff --git a/org.eclipse.virgo.medic.testfragment/.classpath b/org.eclipse.virgo.medic.testfragment/.classpath new file mode 100644 index 0000000..6635d80 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/.classpath @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" path="src/main/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-3.5.1.R35x_v20091005.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-sources-3.5.1.R35x_v20091005.jar"/> + <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar" sourcepath="/MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-sources-1.5.10.jar"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/org.eclipse.virgo.medic.testfragment/.project b/org.eclipse.virgo.medic.testfragment/.project new file mode 100644 index 0000000..80226e7 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/.project @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.virgo.medic.testfragment</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.ajdt.core.ajbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.springsource.server.ide.bundlor.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.springframework.ide.eclipse.core.springbuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + <nature>com.springsource.server.ide.facet.core.bundlenature</nature> + <nature>org.springframework.ide.eclipse.core.springnature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.virgo.medic.testfragment/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.medic.testfragment/.settings/com.springsource.server.ide.bundlor.core.prefs new file mode 100644 index 0000000..16863b5 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/.settings/com.springsource.server.ide.bundlor.core.prefs @@ -0,0 +1,5 @@ +#Thu Nov 12 08:44:57 GMT 2009 +com.springsource.server.ide.bundlor.core.bundlor.generated.manifest.autoformatting=true +com.springsource.server.ide.bundlor.core.byte.code.scanning=true +com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions +eclipse.preferences.version=1 diff --git a/org.eclipse.virgo.medic.testfragment/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.eclipse.virgo.medic.testfragment/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..801f856 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="com.springsource.server.bundle" version="1.0"/> +</faceted-project> diff --git a/org.eclipse.virgo.medic.testfragment/.springBeans b/org.eclipse.virgo.medic.testfragment/.springBeans new file mode 100644 index 0000000..5152991 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/.springBeans @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beansProjectDescription> + <version>1</version> + <pluginVersion><![CDATA[2.2.5.M1]]></pluginVersion> + <configSuffixes> + <configSuffix><![CDATA[xml]]></configSuffix> + </configSuffixes> + <enableImports><![CDATA[false]]></enableImports> + <configs> + </configs> + <configSets> + </configSets> +</beansProjectDescription> diff --git a/org.eclipse.virgo.medic.testfragment/build.xml b/org.eclipse.virgo.medic.testfragment/build.xml new file mode 100644 index 0000000..daa4411 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/build.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.medic.testfragment"> + + <property name="clover.coverage" value="0%"/> + + <property file="${basedir}/../build.properties"/> + <property file="${basedir}/../build.versions"/> + <import file="${basedir}/../virgo-build/aspect/default.xml"/> + +</project> diff --git a/org.eclipse.virgo.medic.testfragment/ivy.xml b/org.eclipse.virgo.medic.testfragment/ivy.xml new file mode 100644 index 0000000..482ad18 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/ivy.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}"/> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="provided->runtime"/> + <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="${org.slf4j}" conf="aspects->runtime"/> + <dependency org="org.aspectj" name="com.springsource.org.aspectj.runtime" rev="${org.aspectj}" conf="aspects->runtime"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/Dump.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/Dump.java new file mode 100644 index 0000000..2dd3a81 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/Dump.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.Writer; +import java.util.Map; + +/** + * A <code>Dump</code> represents a dump being generated by a {@link DumpGenerator}. During dump generation + * {@link DumpContributor DumpContributors} are called to contribute to the dump. Contributors can request a + * {@link Writer}, {@link File}, etc. which they may use to write out their contribution to the dump. + */ +public interface Dump { + + /** + * Returns a timestamp that identifies that time at which this dump was generated. + * + * @return The timestamp of the dump's generation + */ + long getTimestamp(); + + /** + * Returns the context that is associated with this dump. If there is no associated context an empty + * <code>Map</code> is returned. + * + * @return The dump's context + */ + Map<String, Object> getContext(); + + /** + * Returns the {@link Throwable Throwables} associated with this dump. + * + * @return The dump's <code>Throwable</code>s + */ + Throwable[] getThrowables(); + + /** + * Returns the cause of this dump. + * + * @return The dump's cause. + */ + String getCause(); + + /** + * Creates a {@link FileWriter} that writes to a file with the supplied name, within this dump's output location. + * @param name + * + * @return a <code>FileWriter</code> to which a contribution to the dump can be written + * @throws DumpContributionFailedException + */ + FileWriter createFileWriter(String name) throws DumpContributionFailedException; + + /** + * Creates a {@link FileOutputStream} that writes to a file with the supplied name, within this dump's output + * location. + * @param name + * + * @return a <code>FileOutputStream</code> to which a contribution to the dump can be written + * @throws DumpContributionFailedException + */ + FileOutputStream createFileOutputStream(String name) throws DumpContributionFailedException; + + /** + * Creates a {@link File} with the supplied name, within this dump's output location. + * @param name + * + * @return a <code>File</code> to which a contribution to the dump can be written + */ + File createFile(String name); + +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpContributionFailedException.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpContributionFailedException.java new file mode 100644 index 0000000..edaf464 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpContributionFailedException.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +/** + * A <code>DumpContributionFailedException</code> is thrown by a {@link DumpContributor} to indicate that a failure has + * occurred when it was attempting to make a contribution to a dump. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public class DumpContributionFailedException extends DumpGenerationFailedException { + + private static final long serialVersionUID = -3196511149954617337L; + + /** + * Create a new DumpContributionFailedException with the supplied message that describes the failure + * + * @param message The message describing the failure + */ + public DumpContributionFailedException(String message) { + super(message); + } + + /** + * Create a new DumpContributionFailedException with the supplied failure cause and message that describes the + * failure + * + * @param message The message describing the failure + * @param cause The cause of the contribution failure + */ + public DumpContributionFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpContributor.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpContributor.java new file mode 100644 index 0000000..ddffe7c --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpContributor.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +/** + * A <code>DumpContributor</code> is implemented to contribute information to a dump. Contributors are 'registered' with + * a {@link DumpGenerator} by publishing them in the service registry. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * <code>DumpContributor</code>s must be thread-safe. + */ +public interface DumpContributor { + + /** + * Contribute to the supplied {@link Dump}. + * + * @param dump The dump to which a contribution may be made. + * @throws DumpContributionFailedException if the dump contribution cannot be created + */ + void contribute(Dump dump) throws DumpContributionFailedException; + + /** + * Returns the name of this <code>DumpContributor</code>. The name is used by a {@link DumpGenerator} when + * determining which contributors should be excluded from contributing to a dump. + * + * @return The contributor's name + */ + String getName(); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerationFailedException.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerationFailedException.java new file mode 100644 index 0000000..5dded04 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerationFailedException.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +/** + * A <code>DumpGenerationFailedException</code> is thrown by a {@link DumpGenerator} to indicate that a failure has + * occurred during dump generation. + * + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public class DumpGenerationFailedException extends Exception { + + private static final long serialVersionUID = -3196511149954617337L; + + /** + * Create a new DumpGenerationFailedException with the supplied message that describes the failure + * + * @param message The message describing the failure + */ + public DumpGenerationFailedException(String message) { + super(message); + } + + /** + * Create a new DumpGenerationFailedException with the supplied failure cause and message that describes the failure + * + * @param message The message describing the failure + * @param cause The cause of the generation failure + */ + public DumpGenerationFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerator.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerator.java new file mode 100644 index 0000000..2a2d530 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerator.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +import java.util.Map; + +/** + * A <code>DumpGenerator</code> can be used to programatically request the generation of a dump. A + * <code>DumpGenerator</code> instance can be obtained from the service registry. + * <p /> + * + * When a dump is requested, the <code>DumpGenerator</code> will, by default, provide all {@link DumpContributor + * DumpContributors} that are known to it with an opportunity to contribute to the dump. <code>DumpContributor</code> + * instances are made known to a <code>DumpGeneraator</code> by publishing them in the service registry. + * <p /> + * + * A <code>DumpGenerator</code> can be configured to exclude <code>DumpContributor</code>s from contributing to dumps + * with a particular cause. TODO Expand the documentation on contributor exclusion + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * <code>DumpGenerator</code>s must be thread-safe. + */ +public interface DumpGenerator { + + /** + * Generates a dump + * + * @param cause the cause of the dump + * @param throwables {@link Throwable} instances to be associated with the dump + */ + void generateDump(String cause, Throwable... throwables); + + /** + * Generates a dump, with additional context. + * + * @param cause the cause of the dump + * @param context additional context that can be used by the <code>DumpProvider</code>s + * @param throwables {@link Throwable} instances to be associated with the dump + */ + void generateDump(String cause, Map<String, Object> context, Throwable... throwables); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/JmxDumpContributionParticipant.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/JmxDumpContributionParticipant.java new file mode 100644 index 0000000..28a897d --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/dump/JmxDumpContributionParticipant.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.management.DescriptorKey; + +/** + * Indicates that this MBean should be treated as a JmxDumpContributionParticipant + * <p /> + * + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface JmxDumpContributionParticipant { + + @DescriptorKey("jmxDumpContributionParticipant") + boolean value() default true; +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/EventLogger.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/EventLogger.java new file mode 100644 index 0000000..8e09071 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/EventLogger.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +import java.util.ResourceBundle; + +/** + * An <code>EventLogger</code> provides support for logging events as human-readable, potentially internationalized, + * messages identified by a unique code. + * <p /> + * An <code>EventLogger</code> instance can be obtained directly from the service registry. Such instances will search + * the <code>Bundle</code> that obtained the instance, and the <code>EventLogger</code> implementations <code>Bundle</code> + * for a properties file that contains entry for the an event's code. The implementation bundle is searched to support + * providing properties files in fragment bundles which are attached to the implementation. + * <p /> + * Alternatively, an <code>EventLogger</code> can be obtained from an {@link EventLoggerFactory} allowing a specific + * <code>Bundle</code> to be supplied that will be used to search for properties files. + * <p /> + * The algorithm used to find properties files matches that described in + * {@link ResourceBundle#getBundle(String, java.util.Locale, ClassLoader) ResourceBundle}, with the exception that no + * searching for class files is performed. + * <p /> + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + */ +public interface EventLogger { + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. + * + * @param code The code of the message to be logged + * @param level The level at which the event should be logged + * @param inserts The inserts for the message + */ + void log(String code, Level level, Object... inserts); + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. + * + * @param logEvent The log event to be logged + * @param inserts The inserts for the message + */ + void log(LogEvent logEvent, Object... inserts); + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. The supplied + * <code>Throwable</code> is logged with the message. + * + * @param code The code of the message to be logged + * @param level The level at which the event should be logged + * @param throwable The <code>Throwable</code> to be logged + * @param inserts The inserts for the message + */ + void log(String code, Level level, Throwable throwable, Object... inserts); + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. The supplied + * <code>Throwable</code> is logged with the message. + * + * @param logEvent The log event to be logged + * @param throwable The <code>Throwable</code> to be logged + * @param inserts The inserts for the message + */ + void log(LogEvent logEvent, Throwable throwable, Object... inserts); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/EventLoggerFactory.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/EventLoggerFactory.java new file mode 100644 index 0000000..da99120 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/EventLoggerFactory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +import java.util.ResourceBundle; + +import org.osgi.framework.Bundle; + +/** + * An <code>EventLoggerFactory</code> is used to create an <code>EventLogger</code> instance that will search a specific + * bundle, in addition to the EventLogger implementation's bundle, for {@link ResourceBundle ResourceBundles}. + * <p /> + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + */ +public interface EventLoggerFactory { + + /** + * Creates a new <code>EventLogger</code> that will search the supplied bundle, in addition to the + * <code>EventLogger</code> implementation's bundle, for {@link ResourceBundle ResourceBundles}. + * + * @param bundle The <code>Bundle</code> to search for <code>ResourceBundle</code>s. + * + * @return The <code>EventLogger</code> + */ + public EventLogger createEventLogger(Bundle bundle); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/Level.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/Level.java new file mode 100644 index 0000000..b8d9eae --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/Level.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +public enum Level { + ERROR, WARNING, INFO +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/LogEvent.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/LogEvent.java new file mode 100644 index 0000000..3387160 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/eventlog/LogEvent.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +/** + * A <code>LogEvent</code> encapsulates the details of an event that is to be logged. + * <p/> + * + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + * + */ +public interface LogEvent { + + /** + * Returns the code that uniquely identifies this <code>LogEvent</code>. Typically, this code is used to locate the + * message for the event in a resource bundle. + * + * @return The event's code + */ + public String getEventCode(); + + /** + * Returns the {@link Level} at which this <code>LogEvent</code> should be published. + * + * @return The level of the event. + */ + public Level getLevel(); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/ConfigurationPublicationFailedException.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/ConfigurationPublicationFailedException.java new file mode 100644 index 0000000..e2bbf0e --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/ConfigurationPublicationFailedException.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +/** + * Thrown by {@link LoggingConfigurationPublisher} when a request to publish logging configuration fails. + */ +public class ConfigurationPublicationFailedException extends Exception { + + private static final long serialVersionUID = 4317804271280636565L; + + /** + * Creates a new exception with the supplied message and cause. + * + * @param message The exception's message + * @param cause The exception's cause + */ + public ConfigurationPublicationFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/DelegatingPrintStream.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/DelegatingPrintStream.java new file mode 100644 index 0000000..131f597 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/DelegatingPrintStream.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +import java.io.PrintStream; + +/** + * A <code>DelegatingPrintStream</code> is a {@link PrintStream} implementation that delegates to another + * {@link PrintStream} instance and allows the delegate to be changed at runtime. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public interface DelegatingPrintStream { + + /** + * Sets the {@link PrintStream} to be used as a delegate. The given <code>printStream</code> may be + * <code>null</code> to disable delegation. + * + * @param printStream The delegate, or <code>null</code> to disable delegation. + */ + void setDelegate(PrintStream printStream); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/EntryExitTrace.aj b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/EntryExitTrace.aj new file mode 100644 index 0000000..ed2b3aa --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/EntryExitTrace.aj @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +import org.aspectj.lang.JoinPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An aspect that will advise any method with entry and exit trace logging. + * + * <strong>Concurrent Semantics</strong><br /> + * + * Threadsafe + * + */ +public aspect EntryExitTrace pertypewithin(*) { + + private volatile Logger logger; + + pointcut medic() : within(org.eclipse.virgo.medic..*); + + pointcut logback() : within(ch.qos.logback..*) || within(org.slf4j.impl..*); + + pointcut infoCandidate() : execution(public * *(..)) && !medic() && !logback(); + + pointcut debugCandidate() : execution(!public !private * *(..)) && !medic() && !logback(); + + pointcut traceCandidate() : execution(private * *(..)) && !medic() && !logback(); + + before() : infoCandidate() { + getLogger(thisJoinPointStaticPart).info("{} {}", ">", getSignature(thisJoinPointStaticPart)); + } + + after() returning : infoCandidate() { + getLogger(thisJoinPointStaticPart).info("{} {}", "<", getSignature(thisJoinPointStaticPart)); + } + + after() throwing(Throwable t) : infoCandidate() { + Logger logger = getLogger(thisJoinPointStaticPart); + if (logger.isInfoEnabled()) { + logger.info(String.format("< %s", getSignature(thisJoinPointStaticPart)), t); + } + } + + before() : debugCandidate() { + getLogger(thisJoinPointStaticPart).debug("{} {}", ">", getSignature(thisJoinPointStaticPart)); + } + + after() returning : debugCandidate() { + getLogger(thisJoinPointStaticPart).debug("{} {}", "<", getSignature(thisJoinPointStaticPart)); + } + + after() throwing(Throwable t) : debugCandidate() { + Logger logger = getLogger(thisJoinPointStaticPart); + if (logger.isDebugEnabled()) { + logger.debug(String.format("< %s", getSignature(thisJoinPointStaticPart)), t); + } + } + + before() : traceCandidate() { + getLogger(thisJoinPointStaticPart).trace("{} {}", ">", getSignature(thisJoinPointStaticPart)); + } + + after() returning : traceCandidate() { + getLogger(thisJoinPointStaticPart).trace("{} {}", "<", getSignature(thisJoinPointStaticPart)); + } + + after() throwing(Throwable t) : traceCandidate() { + Logger logger = getLogger(thisJoinPointStaticPart); + if (logger.isTraceEnabled()) { + logger.trace(String.format("< %s", getSignature(thisJoinPointStaticPart)), t); + } + } + + private Logger getLogger(JoinPoint.StaticPart sp) { + if (this.logger == null) { + this.logger = LoggerFactory.getLogger(sp.getSignature().getDeclaringType()); + } + return this.logger; + } + + private String getSignature(JoinPoint.StaticPart sp) { + return sp.getSignature().toLongString(); + } +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/LoggingConfiguration.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/LoggingConfiguration.java new file mode 100644 index 0000000..4156c90 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/LoggingConfiguration.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +public interface LoggingConfiguration { + + String getConfiguration(); + + String getName(); +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/LoggingConfigurationPublisher.java b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/LoggingConfigurationPublisher.java new file mode 100644 index 0000000..e0d3c90 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/java/org/eclipse/virgo/medic/log/LoggingConfigurationPublisher.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +import java.io.File; + +/** + * A <code>LoggingConfigurationPublisher</code> is used to publish {@link LoggingConfiguration} into the service + * registry. <code>LoggingConfiguration</code> instances in the service registry are referenced by bundles using the + * <code>Medic-LoggingConfiguration</code> manifest header. + */ +public interface LoggingConfigurationPublisher { + + /** + * Publishes the configuration in the supplied <code>File</code> as a <code>LoggingConfiguration</code> instance, + * identified with the supplied id. The published configuration can then be referenced by a bundle using the + * <code>Medic-LoggingConfiguration</code> manifest header with a value equal to the supplied id. + * + * @param configuration The configuration to be published + * @param id The identifier to be applied to the configuration when its published + * + * @throws ConfigurationPublicationFailedException if the publication of the configuration fails + */ + void publishConfiguration(File configuration, String id) throws ConfigurationPublicationFailedException; +} diff --git a/org.eclipse.virgo.medic.testfragment/src/main/resources/.gitignore b/org.eclipse.virgo.medic.testfragment/src/main/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/main/resources/.gitignore diff --git a/org.eclipse.virgo.medic.testfragment/src/test/java/.gitignore b/org.eclipse.virgo.medic.testfragment/src/test/java/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/test/java/.gitignore diff --git a/org.eclipse.virgo.medic.testfragment/src/test/resources/.gitignore b/org.eclipse.virgo.medic.testfragment/src/test/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/src/test/resources/.gitignore diff --git a/org.eclipse.virgo.medic.testfragment/template.mf b/org.eclipse.virgo.medic.testfragment/template.mf new file mode 100644 index 0000000..36875d2 --- /dev/null +++ b/org.eclipse.virgo.medic.testfragment/template.mf @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.virgo.medic.testfragment +Bundle-Vendor: SpringSource Inc. +Import-Template: + org.aspectj.lang.*;version="${org.aspectj:[=.=.= , +1.0.0)}", + javax.management.*;version="0", + org.osgi.framework;version="0", + org.slf4j.*;version="${org.slf4j:[=.=.=, =.+1.0)}" +Bundle-Version: 1.0.0 +Bundle-Name: Medic API +Excluded-Imports: + ch.qos.logback.classic.* diff --git a/org.eclipse.virgo.medic.weaving/.classpath b/org.eclipse.virgo.medic.weaving/.classpath new file mode 100644 index 0000000..e1203ef --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/.classpath @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" path="src/main/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.core/0.9.18/com.springsource.ch.qos.logback.core-0.9.18.jar" sourcepath="/MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.core/0.9.18/com.springsource.ch.qos.logback.core-sources-0.9.18.jar"/> + <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar" sourcepath="/MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-sources-1.5.10.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.classic/0.9.18/com.springsource.ch.qos.logback.classic-0.9.18.jar" sourcepath="/MEDIC_IVY_CACHE/ch.qos.logback/com.springsource.ch.qos.logback.classic/0.9.18/com.springsource.ch.qos.logback.classic-sources-0.9.18.jar"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-3.5.1.R35x_v20091005.jar"/> + <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.medic"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/MEDIC_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/org.eclipse.virgo.medic.weaving/.project b/org.eclipse.virgo.medic.weaving/.project new file mode 100644 index 0000000..980b181 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/.project @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.virgo.medic.weaving</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.ajdt.core.ajbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.springframework.ide.eclipse.core.springbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.springsource.server.ide.bundlor.core.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + <nature>com.springsource.server.ide.facet.core.bundlenature</nature> + <nature>org.springframework.ide.eclipse.core.springnature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.virgo.medic.weaving/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.medic.weaving/.settings/com.springsource.server.ide.bundlor.core.prefs new file mode 100644 index 0000000..008eb6b --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/.settings/com.springsource.server.ide.bundlor.core.prefs @@ -0,0 +1,5 @@ +#Thu Nov 12 08:45:04 GMT 2009 +com.springsource.server.ide.bundlor.core.bundlor.generated.manifest.autoformatting=true +com.springsource.server.ide.bundlor.core.byte.code.scanning=true +com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions +eclipse.preferences.version=1 diff --git a/org.eclipse.virgo.medic.weaving/.settings/org.springframework.ide.eclipse.core.prefs b/org.eclipse.virgo.medic.weaving/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 0000000..00626fc --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,67 @@ +#Wed Aug 19 13:16:35 BST 2009 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true +org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=false +org.springframework.ide.eclipse.core.enable.project.preferences=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/org.eclipse.virgo.medic.weaving/.springBeans b/org.eclipse.virgo.medic.weaving/.springBeans new file mode 100644 index 0000000..8ce1035 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/.springBeans @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beansProjectDescription> + <version>1</version> + <pluginVersion><![CDATA[2.2.5.200906231226-RC1]]></pluginVersion> + <configSuffixes> + <configSuffix><![CDATA[xml]]></configSuffix> + </configSuffixes> + <enableImports><![CDATA[false]]></enableImports> + <configs> + </configs> + <configSets> + </configSets> +</beansProjectDescription> diff --git a/org.eclipse.virgo.medic.weaving/build.xml b/org.eclipse.virgo.medic.weaving/build.xml new file mode 100644 index 0000000..3756372 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/build.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.medic.weaving"> + + <property name="clover.coverage" value="0%"/> + <property name="disable.bundlor" value="true"/> + + <property file="${basedir}/../build.properties" /> + <property file="${basedir}/../build.versions" /> + + <import file="${basedir}/../virgo-build/aspect/default.xml" /> + +</project> diff --git a/org.eclipse.virgo.medic.weaving/ivy.xml b/org.eclipse.virgo.medic.weaving/ivy.xml new file mode 100644 index 0000000..fbddf56 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/ivy.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}" /> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + <conf name="bundleclasspath" description="Dependencies to be packaged within the bundle"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="ch.qos.logback" name="com.springsource.ch.qos.logback.core" rev="${ch.qos.logback}" conf="provided, runtime"/> + <dependency org="ch.qos.logback" name="com.springsource.ch.qos.logback.classic" rev="${ch.qos.logback}" conf="provided, runtime"/> + <dependency org="org.aspectj" name="com.springsource.org.aspectj.runtime" rev="${org.aspectj}" conf="aspects->runtime"/> + <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="${org.slf4j}" conf="aspects->runtime"/> + <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic" rev="latest.integration" conf="compile->compile"/> + <dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="provided->runtime"/> + <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggingInterceptor.aj b/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggingInterceptor.aj new file mode 100644 index 0000000..43e080f --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggingInterceptor.aj @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; + +public aspect LoggingInterceptor { + + private volatile LoggingListener loggingListener = new NoOpLoggingListener(); + + pointcut withinLoggingInterception() : cflowbelow(within(LoggingInterceptor) && adviceexecution()); + + pointcut filteringAndAppendingWithZeroOr3PlusParams(Logger logger, String fqcn, Marker marker, Level level, String message, Object[] params, Throwable throwable) + : execution(private void ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(String, Marker, Level, String, Object[], Throwable)) + && this(logger) + && args(fqcn, marker, level, message, params, throwable) + && !withinLoggingInterception(); + + pointcut filteringAndAppendingWithOneParam(Logger logger, String fqcn, Marker marker, Level level, String message, Object param, Throwable throwable) + : execution(private void ch.qos.logback.classic.Logger.filterAndLog_1(String, Marker, Level, String, Object, Throwable)) + && this(logger) + && args(fqcn, marker, level, message, param, throwable) + && !withinLoggingInterception(); + + pointcut filteringAndAppendingWithTwoParams(Logger logger, String fqcn, Marker marker, Level level, String message, Object param1, Object param2, Throwable throwable) + : execution(private void ch.qos.logback.classic.Logger.filterAndLog_2(String, Marker, Level, String, Object, Object, Throwable)) + && this(logger) + && args(fqcn, marker, level, message, param1, param2, throwable) + && !withinLoggingInterception(); + + before(Logger logger, String fqcn, Marker marker, Level level, String message, Object[] params, Throwable throwable) : + filteringAndAppendingWithZeroOr3PlusParams(logger, fqcn, marker, level, message, params, throwable) { + + this.loggingListener.onLogging(logger, fqcn, marker, level, message, params, throwable); + } + + before(Logger logger, String fqcn, Marker marker, Level level, String message, Object param, Throwable throwable) : + filteringAndAppendingWithOneParam(logger, fqcn, marker, level, message, param, throwable) { + + this.loggingListener.onLogging(logger, fqcn, marker, level, message, param, throwable); + } + + before(Logger logger, String fqcn, Marker marker, Level level, String message, Object param1, Object param2, Throwable throwable) : + filteringAndAppendingWithTwoParams(logger, fqcn, marker, level, message, param1, param2, throwable) { + + this.loggingListener.onLogging(logger, fqcn, marker, level, message, param1, param2, throwable); + } + + public void setLoggingListener(LoggingListener listener) { + if (listener == null) { + listener = new NoOpLoggingListener(); + } + this.loggingListener = listener; + } +} diff --git a/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggingListener.java b/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggingListener.java new file mode 100644 index 0000000..5ab3d95 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/LoggingListener.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; + +public interface LoggingListener { + + void onLogging(Logger logger, String fqcn, Marker marker, Level level, String message, Object param, Throwable throwable); + + void onLogging(Logger logger, String fqcn, Marker marker, Level level, String message, Object param1, Object param2, Throwable throwable); + + void onLogging(Logger logger, String fqcn, Marker marker, Level level, String message, Object[] params, Throwable throwable); +} diff --git a/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/NoOpLoggingListener.java b/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/NoOpLoggingListener.java new file mode 100644 index 0000000..a16e19e --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/src/main/java/org/eclipse/virgo/medic/log/impl/logback/NoOpLoggingListener.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log.impl.logback; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; + +public class NoOpLoggingListener implements LoggingListener { + + public void onLogging(Logger logger, String fqcn, Marker marker, + Level level, String message, Object param, Throwable throwable) { + } + + public void onLogging(Logger logger, String fqcn, Marker marker, + Level level, String message, Object param1, Object param2, + Throwable throwable) { + } + + public void onLogging(Logger logger, String fqcn, Marker marker, + Level level, String message, Object[] params, Throwable throwable) { + } +} diff --git a/org.eclipse.virgo.medic.weaving/src/main/resources/.gitignore b/org.eclipse.virgo.medic.weaving/src/main/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/src/main/resources/.gitignore diff --git a/org.eclipse.virgo.medic.weaving/src/test/java/.gitignore b/org.eclipse.virgo.medic.weaving/src/test/java/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/src/test/java/.gitignore diff --git a/org.eclipse.virgo.medic.weaving/src/test/resources/.gitignore b/org.eclipse.virgo.medic.weaving/src/test/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic.weaving/src/test/resources/.gitignore diff --git a/org.eclipse.virgo.medic/.classpath b/org.eclipse.virgo.medic/.classpath new file mode 100644 index 0000000..6635d80 --- /dev/null +++ b/org.eclipse.virgo.medic/.classpath @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" path="src/main/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-3.5.1.R35x_v20091005.jar" sourcepath="/MEDIC_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-sources-3.5.1.R35x_v20091005.jar"/> + <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/> + <classpathentry kind="var" path="MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar" sourcepath="/MEDIC_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-sources-1.5.10.jar"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/org.eclipse.virgo.medic/.project b/org.eclipse.virgo.medic/.project new file mode 100644 index 0000000..10bb2cb --- /dev/null +++ b/org.eclipse.virgo.medic/.project @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.virgo.medic</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.ajdt.core.ajbuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.springsource.server.ide.bundlor.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.springframework.ide.eclipse.core.springbuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.ajdt.ui.ajnature</nature> + <nature>com.springsource.server.ide.facet.core.bundlenature</nature> + <nature>org.springframework.ide.eclipse.core.springnature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.virgo.medic/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.medic/.settings/com.springsource.server.ide.bundlor.core.prefs new file mode 100644 index 0000000..a43d19e --- /dev/null +++ b/org.eclipse.virgo.medic/.settings/com.springsource.server.ide.bundlor.core.prefs @@ -0,0 +1,5 @@ +#Thu Nov 12 08:44:05 GMT 2009 +com.springsource.server.ide.bundlor.core.bundlor.generated.manifest.autoformatting=true +com.springsource.server.ide.bundlor.core.byte.code.scanning=true +com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions +eclipse.preferences.version=1 diff --git a/org.eclipse.virgo.medic/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.eclipse.virgo.medic/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..801f856 --- /dev/null +++ b/org.eclipse.virgo.medic/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="com.springsource.server.bundle" version="1.0"/> +</faceted-project> diff --git a/org.eclipse.virgo.medic/.settings/org.springframework.ide.eclipse.core.prefs b/org.eclipse.virgo.medic/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 0000000..a145ba0 --- /dev/null +++ b/org.eclipse.virgo.medic/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,68 @@ +#Thu Nov 12 08:44:05 GMT 2009 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true +org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=false +org.springframework.ide.eclipse.core.enable.project.preferences=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.autowire.autowire-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.toolAnnotation-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/org.eclipse.virgo.medic/.springBeans b/org.eclipse.virgo.medic/.springBeans new file mode 100644 index 0000000..5152991 --- /dev/null +++ b/org.eclipse.virgo.medic/.springBeans @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beansProjectDescription> + <version>1</version> + <pluginVersion><![CDATA[2.2.5.M1]]></pluginVersion> + <configSuffixes> + <configSuffix><![CDATA[xml]]></configSuffix> + </configSuffixes> + <enableImports><![CDATA[false]]></enableImports> + <configs> + </configs> + <configSets> + </configSets> +</beansProjectDescription> diff --git a/org.eclipse.virgo.medic/build.xml b/org.eclipse.virgo.medic/build.xml new file mode 100644 index 0000000..af86144 --- /dev/null +++ b/org.eclipse.virgo.medic/build.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="org.eclipse.virgo.medic"> + + <property name="clover.coverage" value="0%"/> + + <property file="${basedir}/../build.properties"/> + <property file="${basedir}/../build.versions"/> + <import file="${basedir}/../virgo-build/aspect/default.xml"/> + +</project> diff --git a/org.eclipse.virgo.medic/ivy.xml b/org.eclipse.virgo.medic/ivy.xml new file mode 100644 index 0000000..482ad18 --- /dev/null +++ b/org.eclipse.virgo.medic/ivy.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?> +<ivy-module + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" + version="1.3"> + + <info organisation="org.eclipse.virgo.medic" module="${ant.project.name}"/> + + <configurations> + <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/> + </configurations> + + <publications> + <artifact name="${ant.project.name}"/> + <artifact name="${ant.project.name}-sources" type="src" ext="jar"/> + </publications> + + <dependencies> + <dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="provided->runtime"/> + <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="${org.slf4j}" conf="aspects->runtime"/> + <dependency org="org.aspectj" name="com.springsource.org.aspectj.runtime" rev="${org.aspectj}" conf="aspects->runtime"/> + </dependencies> + +</ivy-module> diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/Dump.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/Dump.java new file mode 100644 index 0000000..2d631c2 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/Dump.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.Writer; +import java.util.Map; + +/** + * A <code>Dump</code> represents a dump being generated by a {@link DumpGenerator}. During dump generation + * {@link DumpContributor DumpContributors} are called to contribute to the dump. Contributors can request a + * {@link Writer}, {@link File}, etc. which they may use to write out their contribution to the dump. + */ +public interface Dump { + + /** + * Returns a timestamp that identifies that time at which this dump was generated. + * + * @return The timestamp of the dump's generation + */ + long getTimestamp(); + + /** + * Returns the context that is associated with this dump. If there is no associated context an empty + * <code>Map</code> is returned. + * + * @return The dump's context + */ + Map<String, Object> getContext(); + + /** + * Returns the {@link Throwable Throwables} associated with this dump. + * + * @return The dump's <code>Throwable</code>s + */ + Throwable[] getThrowables(); + + /** + * Returns the cause of this dump. + * + * @return The dump's cause. + */ + String getCause(); + + /** + * Creates a {@link FileWriter} that writes to a file with the supplied name, within this dump's output location. + * @param name of file to write to + * + * @return a <code>FileWriter</code> to which a contribution to the dump can be written + * @throws DumpContributionFailedException + */ + FileWriter createFileWriter(String name) throws DumpContributionFailedException; + + /** + * Creates a {@link FileOutputStream} that writes to a file with the supplied name, within this dump's output + * location. + * @param name of file to write to + * + * @return a <code>FileOutputStream</code> to which a contribution to the dump can be written + * @throws DumpContributionFailedException + */ + FileOutputStream createFileOutputStream(String name) throws DumpContributionFailedException; + + /** + * Creates a {@link File} with the supplied name, within this dump's output location. + * @param name of file to write to + * + * @return a <code>File</code> to which a contribution to the dump can be written + */ + File createFile(String name); + +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpContributionFailedException.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpContributionFailedException.java new file mode 100644 index 0000000..edaf464 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpContributionFailedException.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +/** + * A <code>DumpContributionFailedException</code> is thrown by a {@link DumpContributor} to indicate that a failure has + * occurred when it was attempting to make a contribution to a dump. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public class DumpContributionFailedException extends DumpGenerationFailedException { + + private static final long serialVersionUID = -3196511149954617337L; + + /** + * Create a new DumpContributionFailedException with the supplied message that describes the failure + * + * @param message The message describing the failure + */ + public DumpContributionFailedException(String message) { + super(message); + } + + /** + * Create a new DumpContributionFailedException with the supplied failure cause and message that describes the + * failure + * + * @param message The message describing the failure + * @param cause The cause of the contribution failure + */ + public DumpContributionFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpContributor.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpContributor.java new file mode 100644 index 0000000..ddffe7c --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpContributor.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +/** + * A <code>DumpContributor</code> is implemented to contribute information to a dump. Contributors are 'registered' with + * a {@link DumpGenerator} by publishing them in the service registry. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * <code>DumpContributor</code>s must be thread-safe. + */ +public interface DumpContributor { + + /** + * Contribute to the supplied {@link Dump}. + * + * @param dump The dump to which a contribution may be made. + * @throws DumpContributionFailedException if the dump contribution cannot be created + */ + void contribute(Dump dump) throws DumpContributionFailedException; + + /** + * Returns the name of this <code>DumpContributor</code>. The name is used by a {@link DumpGenerator} when + * determining which contributors should be excluded from contributing to a dump. + * + * @return The contributor's name + */ + String getName(); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerationFailedException.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerationFailedException.java new file mode 100644 index 0000000..5dded04 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerationFailedException.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +/** + * A <code>DumpGenerationFailedException</code> is thrown by a {@link DumpGenerator} to indicate that a failure has + * occurred during dump generation. + * + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public class DumpGenerationFailedException extends Exception { + + private static final long serialVersionUID = -3196511149954617337L; + + /** + * Create a new DumpGenerationFailedException with the supplied message that describes the failure + * + * @param message The message describing the failure + */ + public DumpGenerationFailedException(String message) { + super(message); + } + + /** + * Create a new DumpGenerationFailedException with the supplied failure cause and message that describes the failure + * + * @param message The message describing the failure + * @param cause The cause of the generation failure + */ + public DumpGenerationFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerator.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerator.java new file mode 100644 index 0000000..c07f9bc --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/dump/DumpGenerator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.dump; + +import java.util.Map; + +/** + * A <code>DumpGenerator</code> can be used to request the generation of a dump. A + * <code>DumpGenerator</code> instance can be obtained from the service registry. + * <p /> + * + * When a dump is requested, the <code>DumpGenerator</code> will, by default, provide all {@link DumpContributor}s + * that are known to it with an opportunity to contribute to the dump. <code>DumpContributor</code> + * instances are made known to a {@link DumpGenerator} by publishing them in the service registry. + * <p /> + * + * A {@link DumpGenerator} can be configured to exclude {@link DumpContributor}s from contributing to dumps + * with a particular cause. <br/> + * TODO Expand the documentation on contributor exclusion + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * <code>DumpGenerator</code>s must be thread-safe. + */ +public interface DumpGenerator { + + /** + * Generates a dump + * + * @param cause the cause of the dump + * @param throwables {@link Throwable} instances to be associated with the dump + */ + void generateDump(String cause, Throwable... throwables); + + /** + * Generates a dump, with additional context. + * + * @param cause the cause of the dump + * @param context additional context that can be used by the {@link DumpContributor}s + * @param throwables {@link Throwable} instances to be associated with the dump + */ + void generateDump(String cause, Map<String, Object> context, Throwable... throwables); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/EventLogger.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/EventLogger.java new file mode 100644 index 0000000..1ffd641 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/EventLogger.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +import java.util.ResourceBundle; + +/** + * An <code>EventLogger</code> provides support for logging events as human-readable, potentially internationalized, + * messages identified by a unique code. + * <p /> + * An <code>EventLogger</code> instance can be obtained directly from the service registry. Such instances will search + * the {@link org.osgi.framework.Bundle} that obtained the instance, and the <code>EventLogger</code> implementations <code>Bundle</code> + * for a properties file that contains entry for the an event's code. The implementation bundle is searched to support + * providing properties files in fragment bundles which are attached to the implementation. + * <p /> + * Alternatively, an <code>EventLogger</code> can be obtained from an {@link EventLoggerFactory} allowing a specific + * <code>Bundle</code> to be supplied that will be used to search for properties files. + * <p /> + * The algorithm used to find properties files matches that described in + * {@link ResourceBundle#getBundle(String, java.util.Locale, ClassLoader) ResourceBundle}, with the exception that no + * searching for class files is performed. + * <p /> + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + */ +public interface EventLogger { + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. + * + * @param code The code of the message to be logged + * @param level The level at which the event should be logged + * @param inserts The inserts for the message + */ + void log(String code, Level level, Object... inserts); + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. + * + * @param logEvent The log event to be logged + * @param inserts The inserts for the message + */ + void log(LogEvent logEvent, Object... inserts); + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. The supplied + * <code>Throwable</code> is logged with the message. + * + * @param code The code of the message to be logged + * @param level The level at which the event should be logged + * @param throwable The <code>Throwable</code> to be logged + * @param inserts The inserts for the message + */ + void log(String code, Level level, Throwable throwable, Object... inserts); + + /** + * Logs an event in the form of a message identified by the supplied code. The message is resolved by searching the + * available {@link ResourceBundle ResourceBundles} for an entry with the key that matches the code. + * + * The event is logged at the supplied level, with the supplied inserts being applied to the message. The supplied + * <code>Throwable</code> is logged with the message. + * + * @param logEvent The log event to be logged + * @param throwable The <code>Throwable</code> to be logged + * @param inserts The inserts for the message + */ + void log(LogEvent logEvent, Throwable throwable, Object... inserts); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/EventLoggerFactory.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/EventLoggerFactory.java new file mode 100644 index 0000000..da99120 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/EventLoggerFactory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +import java.util.ResourceBundle; + +import org.osgi.framework.Bundle; + +/** + * An <code>EventLoggerFactory</code> is used to create an <code>EventLogger</code> instance that will search a specific + * bundle, in addition to the EventLogger implementation's bundle, for {@link ResourceBundle ResourceBundles}. + * <p /> + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + */ +public interface EventLoggerFactory { + + /** + * Creates a new <code>EventLogger</code> that will search the supplied bundle, in addition to the + * <code>EventLogger</code> implementation's bundle, for {@link ResourceBundle ResourceBundles}. + * + * @param bundle The <code>Bundle</code> to search for <code>ResourceBundle</code>s. + * + * @return The <code>EventLogger</code> + */ + public EventLogger createEventLogger(Bundle bundle); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/Level.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/Level.java new file mode 100644 index 0000000..b8d9eae --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/Level.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +public enum Level { + ERROR, WARNING, INFO +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/LogEvent.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/LogEvent.java new file mode 100644 index 0000000..3387160 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/eventlog/LogEvent.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.eventlog; + +/** + * A <code>LogEvent</code> encapsulates the details of an event that is to be logged. + * <p/> + * + * <strong>Concurrent Semantics</strong><br /> + * Implementations <strong>must</strong> be thread-safe. + * + */ +public interface LogEvent { + + /** + * Returns the code that uniquely identifies this <code>LogEvent</code>. Typically, this code is used to locate the + * message for the event in a resource bundle. + * + * @return The event's code + */ + public String getEventCode(); + + /** + * Returns the {@link Level} at which this <code>LogEvent</code> should be published. + * + * @return The level of the event. + */ + public Level getLevel(); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/ConfigurationPublicationFailedException.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/ConfigurationPublicationFailedException.java new file mode 100644 index 0000000..e2bbf0e --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/ConfigurationPublicationFailedException.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +/** + * Thrown by {@link LoggingConfigurationPublisher} when a request to publish logging configuration fails. + */ +public class ConfigurationPublicationFailedException extends Exception { + + private static final long serialVersionUID = 4317804271280636565L; + + /** + * Creates a new exception with the supplied message and cause. + * + * @param message The exception's message + * @param cause The exception's cause + */ + public ConfigurationPublicationFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/DelegatingPrintStream.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/DelegatingPrintStream.java new file mode 100644 index 0000000..131f597 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/DelegatingPrintStream.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +import java.io.PrintStream; + +/** + * A <code>DelegatingPrintStream</code> is a {@link PrintStream} implementation that delegates to another + * {@link PrintStream} instance and allows the delegate to be changed at runtime. + * <p /> + * + * <strong>Concurrent Semantics</strong><br /> + * Thread-safe. + * + */ +public interface DelegatingPrintStream { + + /** + * Sets the {@link PrintStream} to be used as a delegate. The given <code>printStream</code> may be + * <code>null</code> to disable delegation. + * + * @param printStream The delegate, or <code>null</code> to disable delegation. + */ + void setDelegate(PrintStream printStream); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/EntryExitTrace.aj b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/EntryExitTrace.aj new file mode 100644 index 0000000..5e4d2c0 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/EntryExitTrace.aj @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +import org.aspectj.lang.JoinPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An aspect that will advise any method with entry and exit trace logging. + * + * <strong>Concurrent Semantics</strong><br /> + * + * Threadsafe + * + */ +public aspect EntryExitTrace pertypewithin(*) { + + private volatile Logger logger; + + pointcut performingEntryExitTrace() : cflowbelow(adviceexecution() && within(EntryExitTrace)); + + pointcut medic() : within(org.eclipse.virgo.medic..*); + + pointcut util() : within(org.eclipse.virgo.util..*); + + pointcut logback() : within(ch.qos.logback..*) || within(org.slf4j.impl..*); + + pointcut infoCandidate() : execution(public * *(..)) && !medic() && !util() && !logback() && !performingEntryExitTrace(); + + pointcut debugCandidate() : execution(!public !private * *(..)) && !medic() && !util() && !logback() && !performingEntryExitTrace(); + + pointcut traceCandidate() : execution(private * *(..)) && !medic() && !util() && !logback() && !performingEntryExitTrace(); + + before() : infoCandidate() { + getLogger(thisJoinPointStaticPart).info("{} {}", ">", getSignature(thisJoinPointStaticPart)); + } + + after() returning : infoCandidate() { + getLogger(thisJoinPointStaticPart).info("{} {}", "<", getSignature(thisJoinPointStaticPart)); + } + + after() throwing(Throwable t) : infoCandidate() { + Logger logger = getLogger(thisJoinPointStaticPart); + if (logger.isInfoEnabled()) { + logger.info(String.format("< %s", getSignature(thisJoinPointStaticPart)), t); + } + } + + before() : debugCandidate() { + getLogger(thisJoinPointStaticPart).debug("{} {}", ">", getSignature(thisJoinPointStaticPart)); + } + + after() returning : debugCandidate() { + getLogger(thisJoinPointStaticPart).debug("{} {}", "<", getSignature(thisJoinPointStaticPart)); + } + + after() throwing(Throwable t) : debugCandidate() { + Logger logger = getLogger(thisJoinPointStaticPart); + if (logger.isDebugEnabled()) { + logger.debug(String.format("< %s", getSignature(thisJoinPointStaticPart)), t); + } + } + + before() : traceCandidate() { + getLogger(thisJoinPointStaticPart).trace("{} {}", ">", getSignature(thisJoinPointStaticPart)); + } + + after() returning : traceCandidate() { + getLogger(thisJoinPointStaticPart).trace("{} {}", "<", getSignature(thisJoinPointStaticPart)); + } + + after() throwing(Throwable t) : traceCandidate() { + Logger logger = getLogger(thisJoinPointStaticPart); + if (logger.isTraceEnabled()) { + logger.trace(String.format("< %s", getSignature(thisJoinPointStaticPart)), t); + } + } + + private Logger getLogger(JoinPoint.StaticPart sp) { + if (this.logger == null) { + this.logger = LoggerFactory.getLogger(sp.getSignature().getDeclaringType()); + } + return this.logger; + } + + private String getSignature(JoinPoint.StaticPart sp) { + return sp.getSignature().toLongString(); + } +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/LoggingConfiguration.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/LoggingConfiguration.java new file mode 100644 index 0000000..4156c90 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/LoggingConfiguration.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +public interface LoggingConfiguration { + + String getConfiguration(); + + String getName(); +} diff --git a/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/LoggingConfigurationPublisher.java b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/LoggingConfigurationPublisher.java new file mode 100644 index 0000000..e0d3c90 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/java/org/eclipse/virgo/medic/log/LoggingConfigurationPublisher.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +package org.eclipse.virgo.medic.log; + +import java.io.File; + +/** + * A <code>LoggingConfigurationPublisher</code> is used to publish {@link LoggingConfiguration} into the service + * registry. <code>LoggingConfiguration</code> instances in the service registry are referenced by bundles using the + * <code>Medic-LoggingConfiguration</code> manifest header. + */ +public interface LoggingConfigurationPublisher { + + /** + * Publishes the configuration in the supplied <code>File</code> as a <code>LoggingConfiguration</code> instance, + * identified with the supplied id. The published configuration can then be referenced by a bundle using the + * <code>Medic-LoggingConfiguration</code> manifest header with a value equal to the supplied id. + * + * @param configuration The configuration to be published + * @param id The identifier to be applied to the configuration when its published + * + * @throws ConfigurationPublicationFailedException if the publication of the configuration fails + */ + void publishConfiguration(File configuration, String id) throws ConfigurationPublicationFailedException; +} diff --git a/org.eclipse.virgo.medic/src/main/resources/.gitignore b/org.eclipse.virgo.medic/src/main/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic/src/main/resources/.gitignore diff --git a/org.eclipse.virgo.medic/src/test/java/.gitignore b/org.eclipse.virgo.medic/src/test/java/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic/src/test/java/.gitignore diff --git a/org.eclipse.virgo.medic/src/test/resources/.gitignore b/org.eclipse.virgo.medic/src/test/resources/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/org.eclipse.virgo.medic/src/test/resources/.gitignore diff --git a/org.eclipse.virgo.medic/template.mf b/org.eclipse.virgo.medic/template.mf new file mode 100644 index 0000000..aead093 --- /dev/null +++ b/org.eclipse.virgo.medic/template.mf @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.virgo.medic +Bundle-Vendor: SpringSource Inc. +Import-Template: + org.aspectj.*;version="${org.aspectj:[=.=.= , +1.0.0)}", + javax.management.*;version="0", + org.osgi.framework;version="0", + org.slf4j.*;version="${org.slf4j:[=.=.=, =.+1.0)}" +Bundle-Version: 1.0.0 +Bundle-Name: Medic API |