[jboss-cvs] JBossAS SVN: r83545 - in projects/ejb3/trunk: timerservice-quartz and 35 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Jan 28 04:04:25 EST 2009


Author: wolfc
Date: 2009-01-28 04:04:24 -0500 (Wed, 28 Jan 2009)
New Revision: 83545

Added:
   projects/ejb3/trunk/timerservice-quartz/
   projects/ejb3/trunk/timerservice-quartz/.classpath
   projects/ejb3/trunk/timerservice-quartz/.project
   projects/ejb3/trunk/timerservice-quartz/.settings/
   projects/ejb3/trunk/timerservice-quartz/.settings/org.eclipse.jdt.core.prefs
   projects/ejb3/trunk/timerservice-quartz/.settings/org.maven.ide.eclipse.prefs
   projects/ejb3/trunk/timerservice-quartz/pom.xml
   projects/ejb3/trunk/timerservice-quartz/src/
   projects/ejb3/trunk/timerservice-quartz/src/main/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimedObjectInvokerRegistry.java
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java
   projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html
   projects/ejb3/trunk/timerservice-quartz/src/main/resources/
   projects/ejb3/trunk/timerservice-quartz/src/main/resources/META-INF/
   projects/ejb3/trunk/timerservice-quartz/src/main/resources/META-INF/jboss-beans.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/DerbyService.java
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/HSQLDBService.java
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/SimpleClassLoaderDeployer.java
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/simple/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/simple/unit/
   projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/simple/unit/SimpleUnitTestCase.java
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/derby.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/hsqldb.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/jmx-jdk.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/maindeployer.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/naming.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/transactionmanager.xml
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/jndi.properties
   projects/ejb3/trunk/timerservice-quartz/src/test/resources/log4j.xml
   projects/ejb3/trunk/timerservice-spi/
   projects/ejb3/trunk/timerservice-spi/.classpath
   projects/ejb3/trunk/timerservice-spi/.project
   projects/ejb3/trunk/timerservice-spi/.settings/
   projects/ejb3/trunk/timerservice-spi/.settings/org.eclipse.jdt.core.prefs
   projects/ejb3/trunk/timerservice-spi/pom.xml
   projects/ejb3/trunk/timerservice-spi/src/
   projects/ejb3/trunk/timerservice-spi/src/main/
   projects/ejb3/trunk/timerservice-spi/src/main/java/
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimedObjectInvoker.java
   projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimerServiceFactory.java
Log:
EJBTHREE-1697: initial commit of timerservice-quartz and timerservice-spi


Property changes on: projects/ejb3/trunk/timerservice-quartz
___________________________________________________________________
Name: svn:ignore
   + eclipse-target
target
FileHandler@*


Added: projects/ejb3/trunk/timerservice-quartz/.classpath
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/.classpath	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/.classpath	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,9 @@
+<classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
+  <classpathentry kind="src" path="src/test/java" output="eclipse-target/tests-classes"/>
+  <classpathentry kind="src" path="src/test/resources" output="eclipse-target/tests-classes" excluding="**/*.java"/>
+  <classpathentry kind="output" path="eclipse-target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+</classpath>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-quartz/.project
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/.project	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/.project	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,17 @@
+<projectDescription>
+  <name>jboss-ejb3-timerservice-quartz</name>
+  <comment>An unsupported implementation of an EJB TimerService using Quartz</comment>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.maven.ide.eclipse.maven2Builder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>org.maven.ide.eclipse.maven2Nature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-quartz/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/.settings/org.eclipse.jdt.core.prefs	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,5 @@
+#Tue Jan 27 13:10:28 CET 2009
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5

Added: projects/ejb3/trunk/timerservice-quartz/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/.settings/org.maven.ide.eclipse.prefs	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,8 @@
+#Tue Jan 27 16:35:21 CET 2009
+activeProfiles=eclipse
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=false
+resourceFilterGoals=process-resources resources\:testResources
+version=1

Added: projects/ejb3/trunk/timerservice-quartz/pom.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/pom.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/pom.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  vi:ts=2:sw=2:expandtab:
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.jboss.ejb3</groupId>
+    <artifactId>jboss-ejb3-build</artifactId>
+    <version>1.0.0</version>
+    <relativePath>../build/pom.xml</relativePath>
+  </parent>
+
+  <!-- Maven POM Model Version -->
+  <modelVersion>4.0.0</modelVersion>
+
+  <!-- Artifact Information -->
+  <artifactId>jboss-ejb3-timerservice-quartz</artifactId>
+  <packaging>jar</packaging>
+  <version>0.1.0-SNAPSHOT</version>
+  <name>JBoss EJB 3.x TimerService Quartz</name>
+  <description>An unsupported implementation of an EJB TimerService using Quartz</description>
+  <url>http://labs.jboss.com/jbossejb3/</url>
+
+  <dependencies>
+    <!-- For 'mocking' a DataSource we use Hypersonic -->
+    <dependency>
+      <groupId>hsqldb</groupId>
+      <artifactId>hsqldb</artifactId>
+      <version>1.8.0.8-brew</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>jboss.jbossts</groupId>
+      <artifactId>jbossjta-integration</artifactId>
+      <version>4.4.0.GA</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- For 'mocking' a DataSource we use Derby -->
+    <dependency>
+      <groupId>org.apache.derby</groupId>
+      <artifactId>derby</artifactId>
+      <version>10.4.1.3</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.bootstrap</groupId>
+      <artifactId>jboss-bootstrap</artifactId>
+      <version>0.1.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.deployers</groupId>
+      <artifactId>jboss-deployers-vfs</artifactId>
+      <version>${version.org.jboss.deployers}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.ejb3</groupId>
+      <artifactId>jboss-ejb3-timerservice-spi</artifactId>
+      <version>[0,)</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.logging</groupId>
+      <artifactId>jboss-logging-spi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.logging</groupId>
+      <artifactId>jboss-logging-log4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.naming</groupId>
+      <artifactId>jnpserver</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>quartz</groupId>
+      <artifactId>quartz</artifactId>
+      <version>1.5.2</version>
+    </dependency>
+    
+    <!-- For Arjuna -->
+    <dependency>
+      <groupId>apache-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.1.0.jboss</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>jboss.jbossts</groupId>
+      <artifactId>jbossjta</artifactId>
+      <version>4.4.0.GA</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>jboss.jbossts</groupId>
+      <artifactId>jbossts-common</artifactId>
+      <version>4.4.0.GA</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.integration</groupId>
+      <artifactId>jboss-transaction-spi</artifactId>
+      <version>5.0.3.GA</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>oswego-concurrent</groupId>
+      <artifactId>concurrent</artifactId>
+      <version>1.3.4-jboss-update1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

Copied: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz;
+
+import java.io.Serializable;
+
+import javax.ejb.EJBException;
+import javax.ejb.NoSuchObjectLocalException;
+import javax.ejb.Timer;
+import javax.ejb.TimerHandle;
+
+import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker;
+import org.jboss.logging.Logger;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+
+/**
+ * This class contains all the info for find a persistent timer.
+ *
+ * @author <a href="mailto:carlo at nerdnet.nl">Carlo de Wolf</a>
+ * @version $Revision$
+ */
+public class PersistentTimer implements Serializable, TimerHandle
+{
+   private static final Logger log = Logger.getLogger(PersistentTimer.class);
+   
+   private static final long serialVersionUID = 1L;
+
+   //private String schedulerName;
+   //private String jobName;
+   //private String jobGroup;
+   private String triggerName;
+   private String triggerGroup;
+   private String containerGuid;
+   
+   private Serializable info;
+   
+   protected PersistentTimer(Trigger trigger, String containerGuid, Serializable info)
+   {
+      assert trigger != null;
+      assert containerGuid != null;
+      
+      this.triggerName = trigger.getName();
+      this.triggerGroup = trigger.getGroup();
+      this.info = info;
+      this.containerGuid = containerGuid;
+   }
+   
+   protected TimedObjectInvoker getTimedObjectInvoker()
+   {
+      // TODO: a hack to get back the container. This needs thinking.
+      TimedObjectInvoker invoker = TimedObjectInvokerRegistry.getTimedObjectInvoker(containerGuid);
+      assert invoker != null;
+      return invoker;
+   }
+   
+   public Timer getTimer() throws IllegalStateException, NoSuchObjectLocalException, EJBException
+   {
+      // TODO: check state
+      try
+      {
+         Scheduler scheduler = QuartzTimerServiceFactory.getScheduler();
+         Trigger trigger = scheduler.getTrigger(triggerName, triggerGroup);
+         if(trigger == null)
+            throw new NoSuchObjectLocalException("can't find trigger '" + triggerName + "' in group '" + triggerGroup + "'");
+         return new TimerImpl(scheduler, trigger, info);
+      }
+      catch(SchedulerException e)
+      {
+         log.error("getTimer failed", e);
+         throw new EJBException(e);
+      }
+   }
+}

Copied: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz;
+
+import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+/**
+ * Comment
+ *
+ * @author <a href="mailto:carlo at nerdnet.nl">Carlo de Wolf</a>
+ * @version $Revision$
+ */
+public class QuartzTimerJob implements Job
+{
+   public void execute(JobExecutionContext context) throws JobExecutionException
+   {
+      PersistentTimer timer = (PersistentTimer) context.getJobDetail().getJobDataMap().get("timer");
+      TimedObjectInvoker invoker = timer.getTimedObjectInvoker();
+      try {
+         invoker.callTimeout(timer.getTimer());
+      }
+      catch(Exception e) {
+         throw new JobExecutionException(e);
+      }
+   }  
+}

Copied: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,314 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.ejb.TimerService;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker;
+import org.jboss.ejb3.timerservice.spi.TimerServiceFactory;
+import org.jboss.logging.Logger;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.SchedulerFactory;
+import org.quartz.impl.StdSchedulerFactory;
+import org.quartz.utils.DBConnectionManager;
+import org.quartz.utils.JNDIConnectionProvider;
+
+/**
+ * Creates timer service objects for use in EJB3 containers. For this
+ * two methods are provided: createTimerService and removeTimerService.
+ * 
+ * The factory can be started and stopped within both an embedded and full stack.
+ * 
+ * For now only one scheduler is supported. Each bean container has its own
+ * job and trigger group within Quartz.
+ * 
+ * @author <a href="mailto:carlo at nerdnet.nl">Carlo de Wolf</a>
+ * @version $Revision: 56116 $
+ */
+public class QuartzTimerServiceFactory implements TimerServiceFactory
+{
+   @SuppressWarnings("unused")
+   private static final Logger log = Logger.getLogger(QuartzTimerServiceFactory.class);
+   
+   private TransactionManager tm;
+   
+   private static Scheduler scheduler;
+   
+   private Properties properties;
+   
+   /**
+    * Contains the sql statements to create the database schema.
+    */
+   private Properties sqlProperties;
+   
+   private void createSchema()
+   {
+      try
+      {
+         tm.begin();
+         try
+         {
+            Connection conn = getConnection();
+            try
+            {
+               boolean success = execute(conn, "CREATE_TABLE_JOB_DETAILS");
+               if(success)
+               {
+                  execute(conn, "CREATE_TABLE_JOB_LISTENERS");
+                  execute(conn, "CREATE_TABLE_TRIGGERS");
+                  execute(conn, "CREATE_TABLE_SIMPLE_TRIGGERS");
+                  execute(conn, "CREATE_TABLE_CRON_TRIGGERS");
+                  execute(conn, "CREATE_TABLE_BLOB_TRIGGERS");
+                  execute(conn, "CREATE_TABLE_TRIGGER_LISTENERS");
+                  execute(conn, "CREATE_TABLE_CALENDARS");
+                  execute(conn, "CREATE_TABLE_PAUSED_TRIGGER_GRPS");
+                  execute(conn, "CREATE_TABLE_FIRED_TRIGGERS");
+                  execute(conn, "CREATE_TABLE_SCHEDULER_STATE");
+                  execute(conn, "CREATE_TABLE_LOCKS");
+                  
+                  execute(conn, "INSERT_TRIGGER_ACCESS");
+                  execute(conn, "INSERT_JOB_ACCESS");
+                  execute(conn, "INSERT_CALENDAR_ACCESS");
+                  execute(conn, "INSERT_STATE_ACCESS");
+                  execute(conn, "INSERT_MISFIRE_ACCESS");
+               }
+            }
+            finally
+            {
+               conn.close();
+            }
+            tm.commit();
+         }
+         catch(SQLException e)
+         {
+            throw new RuntimeException(e);
+         }
+         catch (RollbackException e)
+         {
+            throw new RuntimeException(e);
+         }
+         catch (HeuristicMixedException e)
+         {
+            throw new RuntimeException(e);
+         }
+         catch (HeuristicRollbackException e)
+         {
+            throw new RuntimeException(e);
+         }
+         finally
+         {
+            if(tm.getStatus() == Status.STATUS_ACTIVE)
+               tm.rollback();
+         }
+      }
+      catch(SystemException e)
+      {
+         throw new RuntimeException(e);
+      }
+      catch (NotSupportedException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+   
+   /**
+    * Create a TimerService for use in a bean container.
+    * 
+    * @param objectName the name of the bean container
+    * @param invoker    the invoker to call on timeouts
+    * @return           an EJB TimerService
+    */
+   public TimerService createTimerService(TimedObjectInvoker invoker)
+   {
+      Scheduler scheduler = getScheduler();
+      if (scheduler == null) return null;
+      
+      TimedObjectInvokerRegistry.register(invoker);
+      
+      return new TimerServiceImpl(scheduler, invoker);
+   }
+   
+   private void destroyAllTimers() throws SchedulerException
+   {
+      String groupNames[] = scheduler.getJobGroupNames();
+      for(String groupName : groupNames)
+      {
+         String jobNames[] = scheduler.getJobNames(groupName);
+         for(String jobName : jobNames)
+         {
+            scheduler.deleteJob(jobName, groupName);
+         }
+      }
+   }
+   
+   private boolean execute(Connection conn, String stmtName) throws SQLException
+   {
+      String sql = sqlProperties.getProperty(stmtName);
+      if(sql == null)
+         throw new IllegalStateException("No sql set for '" + stmtName + "'");
+      
+      try
+      {
+         PreparedStatement stmt = conn.prepareStatement(sql);
+         try
+         {
+            stmt.execute();
+            return true;
+         }
+         finally
+         {
+            stmt.close();
+         }
+      }
+      catch(SQLException e)
+      {
+         log.warn("sql failed: " + sql);
+         if(log.isDebugEnabled())
+            log.debug("sql failed: " + sql, e);
+         return false;
+      }
+   }
+   
+   private Connection getConnection() throws SQLException
+   {
+      return DBConnectionManager.getInstance().getConnection("myDS");
+   }
+   
+   /**
+    * @return   the scheduler for package use
+    */
+   protected static Scheduler getScheduler()
+   {
+      if(scheduler == null)
+      {
+         return null;
+         //throw new IllegalStateException("TimerServiceFactory hasn't been started yet");
+      }
+      
+      return scheduler;
+   }
+   
+   public void removeTimerService(TimerService aTimerService)
+   {
+      TimerServiceImpl timerService = (TimerServiceImpl) aTimerService;
+      timerService.shutdown();
+   }
+   
+   public void restoreTimerService(TimerService aTimerService)
+   {
+      // TODO: implement Quartz restore timer service
+   }
+   
+   public void setDataSource(String jndiName)
+   {
+      if(jndiName == null)
+         return;
+      JNDIConnectionProvider connectionProvider = new JNDIConnectionProvider(jndiName, false);
+      // FIXME: remove hardcoding
+      DBConnectionManager.getInstance().addConnectionProvider("myDS", connectionProvider);
+   }
+   
+   public void setProperties(final Properties props)
+   {
+//      if(scheduler != null)
+//         throw new IllegalStateException("already started");
+      
+      // TODO: precondition the prop
+      properties = props;
+   }
+   
+   public void setSqlProperties(Properties props)
+   {
+      this.sqlProperties = props;
+   }
+   
+   public void setTransactionManager(TransactionManager tm)
+   {
+      this.tm = tm;
+   }
+   
+   public synchronized void start() throws Exception
+   {
+      if(scheduler != null)
+         throw new IllegalStateException("already started");
+      
+      log.debug("properties = " + properties);
+      
+      if(tm == null)
+         throw new IllegalStateException("transactionManager is not set");
+            
+      createSchema();
+      
+      // TODO: bind in JNDI, or is this done by the JMX bean?
+      SchedulerFactory factory;
+      if(properties == null)
+         factory = new StdSchedulerFactory();
+      else
+         factory = new StdSchedulerFactory(properties);
+      scheduler = factory.getScheduler();
+      
+      // There is a bug in Quartz that makes it unable to restore timers
+      destroyAllTimers();
+      
+      // TODO: really start right away?
+      scheduler.start();
+   }
+   
+   public synchronized void stop() throws Exception
+   {
+      if(scheduler == null)
+         throw new IllegalStateException("already stopped");
+      
+      // TODO: unbind from JNDI
+      
+      // TODO: standby or shutdown?
+      scheduler.shutdown();
+      
+      scheduler = null;
+   }
+   
+   public void suspendTimerService(TimerService aTimerService)
+   {
+      TimerServiceImpl timerService = (TimerServiceImpl) aTimerService;
+      try
+      {
+         removeTimerService(timerService);
+      }
+      finally
+      {
+         TimedObjectInvokerRegistry.unregister(timerService.getTimedObjectInvoker());
+      }
+   }
+}

Added: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimedObjectInvokerRegistry.java
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimedObjectInvokerRegistry.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimedObjectInvokerRegistry.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker;
+import org.jboss.logging.Logger;
+
+/**
+ * @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class TimedObjectInvokerRegistry
+{
+   private static final Logger log = Logger.getLogger(TimedObjectInvokerRegistry.class);
+   
+   private static Map<String, TimedObjectInvoker> registry = new HashMap<String, TimedObjectInvoker>();
+   
+   static TimedObjectInvoker getTimedObjectInvoker(String id)
+   {
+      TimedObjectInvoker invoker = registry.get(id);
+      if(invoker == null)
+         throw new IllegalStateException("TimedObjectInvoker " + id + " + is not registered");
+      return invoker;
+   }
+   
+   static boolean hasTimedObjectInvoker(String id)
+   {
+      return registry.containsKey(id);
+   }
+   
+   static void register(TimedObjectInvoker invoker)
+   {
+      String id = invoker.getTimedObjectId();
+      if(hasTimedObjectInvoker(id))
+         throw new IllegalStateException("TimedObjectInvoker " + id + " + is already registered");
+      
+      registry.put(id, invoker);
+      
+      log.debug("Registered " + id);
+   }
+   
+   static void unregister(TimedObjectInvoker invoker)
+   {
+      String id = invoker.getTimedObjectId();
+      if(!hasTimedObjectInvoker(id))
+         throw new IllegalStateException("TimedObjectInvoker " + id + " + is not registered");
+      
+      registry.put(id, invoker);
+      
+      log.debug("Unregistered " + id);
+   }
+}

Copied: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.ejb.EJBException;
+import javax.ejb.NoSuchObjectLocalException;
+import javax.ejb.Timer;
+import javax.ejb.TimerHandle;
+
+import org.jboss.logging.Logger;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+
+/**
+ * A view on an actual (persistent) timer.
+ * 
+ * This object must never be serializable (EJB3 18.4.1)
+ *
+ * @author <a href="mailto:carlo at nerdnet.nl">Carlo de Wolf</a>
+ * @version $Revision$
+ */
+public class TimerImpl implements Timer
+{
+   private static final Logger log = Logger.getLogger(TimerImpl.class);
+   
+   private Scheduler scheduler;
+   private Trigger trigger;
+   private Serializable info;
+   
+   protected TimerImpl(Scheduler scheduler, Trigger trigger, Serializable info) {
+      assert scheduler != null;
+      assert trigger != null;
+      
+      this.scheduler = scheduler;
+      this.trigger = trigger;
+      this.info = info;
+   }
+   
+   protected void checkState()
+   {
+      // TODO: implement bean state checking to see if a call is allowed
+      
+      if(trigger.getNextFireTime() == null)
+         throw new NoSuchObjectLocalException("timer has expired");
+   }
+   
+   /**
+    * Cause the timer and all its associated expiration notifications to be cancelled.
+    * 
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   NoSuchObjectLocalException  If invoked on a timer that has expired or has been cancelled. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public void cancel() throws IllegalStateException, NoSuchObjectLocalException, EJBException
+   {
+      checkState();
+      
+      try {
+         // TODO: call TimerServiceImpl.cancelTimer instead
+         scheduler.unscheduleJob(trigger.getName(), trigger.getGroup());
+      }
+      catch(SchedulerException e) {
+         log.error("cancel failed", e);
+         throw new EJBException(e.getMessage());
+      }
+   }
+
+   /**
+    * Get the number of milliseconds that will elapse before the next scheduled timer expiration.
+    * 
+    * @return   The number of milliseconds that will elapse before the next scheduled timer expiration.
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   NoSuchObjectLocalException  If invoked on a timer that has expired or has been cancelled. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public long getTimeRemaining() throws IllegalStateException, NoSuchObjectLocalException, EJBException
+   {
+      // leave all checks to getNextTimeout
+      return getNextTimeout().getTime() - System.currentTimeMillis();
+   }
+
+   /**
+    * Get the point in time at which the next timer expiration is scheduled to occur.
+    * 
+    * @return   The point in time at which the next timer expiration is scheduled to occur.
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   NoSuchObjectLocalException  If invoked on a timer that has expired or has been cancelled. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public Date getNextTimeout() throws IllegalStateException, NoSuchObjectLocalException, EJBException
+   {
+      checkState();
+      
+      Date nextTimeout = trigger.getNextFireTime();
+      if(nextTimeout == null)
+         throw new IllegalStateException("trigger does not have a next fire time"); // TODO: proper EJB3 state check & exception
+      return nextTimeout;
+   }
+
+   /**
+    * Get the information associated with the timer at the time of creation.
+    * 
+    * @return   The Serializable object that was passed in at timer creation, or null if the info argument passed in at timer creation was null.
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   NoSuchObjectLocalException  If invoked on a timer that has expired or has been cancelled. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public Serializable getInfo() throws IllegalStateException, NoSuchObjectLocalException, EJBException
+   {
+      checkState();
+      
+      return info;
+   }
+
+   /**
+    * Get a serializable handle to the timer. This handle can be used at a later time to re-obtain the timer reference.
+    * 
+    * @return   A serializable handle to the timer.
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   NoSuchObjectLocalException  If invoked on a timer that has expired or has been cancelled. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public TimerHandle getHandle() throws IllegalStateException, NoSuchObjectLocalException, EJBException
+   {
+      checkState();
+      
+      return null; // FIXME: implement getHandle
+   }
+}

Copied: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,236 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Date;
+
+import javax.ejb.EJBException;
+import javax.ejb.Timer;
+import javax.ejb.TimerService;
+
+import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker;
+import org.jboss.logging.Logger;
+import org.quartz.JobDetail;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.SimpleTrigger;
+import org.quartz.Trigger;
+
+/**
+ * Implements the EJB3 Timer Service specification (EJB3 chapter 18).
+ * 
+ * Each bean container has its own job and trigger group.
+ *
+ * @author <a href="mailto:carlo at nerdnet.nl">Carlo de Wolf</a>
+ * @version $Revision$
+ */
+public class TimerServiceImpl implements TimerService
+{
+   private static final Logger log = Logger.getLogger(TimerServiceImpl.class);
+   
+   private Scheduler scheduler;
+   private TimedObjectInvoker invoker;
+   private String groupName;
+   private long jobNum = 0;
+   private long triggerNum = 0;
+   
+   protected TimerServiceImpl(Scheduler scheduler, TimedObjectInvoker invoker) {
+      assert scheduler != null;
+      assert invoker != null;
+      
+      this.scheduler = scheduler;
+      this.invoker = invoker;
+      this.groupName = "ejb3";
+   }
+   
+   protected Timer createTimer(Trigger trigger, Serializable info)
+   {
+      try {
+         String name = "myJob" + jobNum;
+         jobNum++;
+         
+         Class jobClass = QuartzTimerJob.class;
+         
+         Timer timer = new TimerImpl(scheduler, trigger, info);
+         
+         PersistentTimer persistentTimer = new PersistentTimer(trigger, invoker.getTimedObjectId(), info);
+         
+         JobDetail jobDetail = new JobDetail(name, groupName, jobClass);
+         jobDetail.getJobDataMap().put("timer", persistentTimer);
+         
+         scheduler.scheduleJob(jobDetail, trigger);
+         
+         return timer;
+      }
+      catch(SchedulerException e) {
+         // translate the exception, because the client might not have quartz
+         log.error("createTimer failed", e);
+         throw new EJBException(e.getMessage());
+      }
+      
+   }
+   
+   /**
+    * Create a single-action timer that expires after a specified duration.
+    * 
+    * @param    duration    The number of milliseconds that must elapse before the timer expires.
+    * @param    info        Application information to be delivered along with the timer expiration notification. This can be null.
+    * @return   The newly created Timer.
+    * @throws   IllegalArgumentException    If duration is negative.
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method.
+    * @throws   EJBException                If this method fails due to a system-level failure.
+    */
+   public Timer createTimer(long duration, Serializable info) throws IllegalArgumentException, IllegalStateException,
+         EJBException
+   {
+      if(duration < 0) throw new IllegalArgumentException("duration must not be negative");
+      // TODO: check state
+      
+      Date expiration = new Date(System.currentTimeMillis() + duration);
+      return createTimer(expiration, info);
+   }
+
+   /**
+    * Create an interval timer whose first expiration occurs after a specified duration, 
+    * and whose subsequent expirations occur after a specified interval.
+    * 
+    * @param    initialDuration     The number of milliseconds that must elapse before the first timer expiration notification.
+    * @param    intervalDuration    The number of milliseconds that must elapse between timer expiration notifications. Expiration notifications are scheduled relative to the time of the first expiration. If expiration is delayed(e.g. due to the interleaving of other method calls on the bean) two or more expiration notifications may occur in close succession to "catch up".
+    * @param    info                Application information to be delivered along with the timer expiration. This can be null.
+    * @return   The newly created Timer.
+    * @throws   IllegalArgumentException    If initialDuration is negative, or intervalDuration is negative. 
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public Timer createTimer(long initialDuration, long intervalDuration, Serializable info)
+         throws IllegalArgumentException, IllegalStateException, EJBException
+   {
+      if(initialDuration < 0) throw new IllegalArgumentException("initialDuration must not be negative");
+      if(intervalDuration < 0) throw new IllegalArgumentException("intervalDuration must not be negative");
+      // TODO: check state
+      
+      Date initialExpiration = new Date(System.currentTimeMillis() + initialDuration);
+      
+      return createTimer(initialExpiration, intervalDuration, info);
+   }
+
+   /**
+    * Create a single-action timer that expires at a given point in time.
+    * 
+    * @param    expiration  The point in time at which the timer must expire.
+    * @param    info        Application information to be delivered along with the timer expiration notification. This can be null. 
+    * @return   The newly created Timer. 
+    * @throws   IllegalArgumentException    If expiration is null, or expiration.getTime() is negative. 
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public Timer createTimer(Date expiration, Serializable info) throws IllegalArgumentException, IllegalStateException,
+         EJBException
+   {
+      if(expiration == null) throw new IllegalArgumentException("expiration must not be null");
+      if(expiration.getTime() < 0) throw new IllegalArgumentException("expiration.time must not be negative");
+      // TODO: check state
+      
+      String triggerName = "myTrigger" + triggerNum;
+      triggerNum++;
+      
+      Trigger trigger = new SimpleTrigger(triggerName, groupName, expiration);
+      
+      return createTimer(trigger, info);
+   }
+
+   /**
+    * Create an interval timer whose first expiration occurs at a given point in time and whose subsequent expirations occur after a specified interval.
+    * 
+    * @param    initialExpiration   The point in time at which the first timer expiration must occur.
+    * @param    intervalDuration    The number of milliseconds that must elapse between timer expiration notifications. Expiration notifications are scheduled relative to the time of the first expiration. If expiration is delayed(e.g. due to the interleaving of other method calls on the bean) two or more expiration notifications may occur in close succession to "catch up".
+    * @param    info                Application information to be delivered along with the timer expiration notification. This can be null. 
+    * @return   The newly created Timer. 
+    * @throws   IllegalArgumentException    If initialExpiration is null, or initialExpiration.getTime() is negative, or intervalDuration is negative. 
+    * @throws   IllegalStateException       If this method is invoked while the instance is in a state that does not allow access to this method. 
+    * @throws   EJBException                If this method could not complete due to a system-level failure.
+    */
+   public Timer createTimer(Date initialExpiration, long intervalDuration, Serializable info)
+         throws IllegalArgumentException, IllegalStateException, EJBException
+   {
+      if(initialExpiration == null) throw new IllegalArgumentException("initialExpiration must not be null");
+      if(initialExpiration.getTime() < 0) throw new IllegalArgumentException("initialExpiration.time must not be negative");
+      if(intervalDuration < 0) throw new IllegalArgumentException("intervalDuration must not be negative");
+      // TODO: check state
+      
+      String triggerName = "myTrigger" + triggerNum;
+      triggerNum++;
+      Date endTime = null;
+      
+      Trigger trigger = new SimpleTrigger(triggerName, groupName, initialExpiration, endTime, SimpleTrigger.REPEAT_INDEFINITELY, intervalDuration);
+      
+      return createTimer(trigger, info);
+   }
+
+   protected Scheduler getScheduler()
+   {
+      return scheduler;
+   }
+
+   protected TimedObjectInvoker getTimedObjectInvoker()
+   {
+      return invoker;
+   }
+   
+   /**
+    * Get all the active timers associated with this bean.
+    * 
+    * @return   A collection of javax.ejb.Timer objects.
+    * @throws   IllegalStateException   If this method is invoked while the instance is in a state that does not allow access to this method.
+    * @throws   EJBException            If this method could not complete due to a system-level failure.
+    */
+   public Collection getTimers() throws IllegalStateException, EJBException
+   {
+      throw new RuntimeException("NYI");
+   }
+
+   protected void shutdown()
+   {
+      log.debug("shutting down " + this);
+      try
+      {
+         String triggerNames[] = scheduler.getTriggerNames(groupName);
+         for(String triggerName : triggerNames)
+            scheduler.unscheduleJob(triggerName, groupName);
+         String jobNames[] = scheduler.getJobNames(groupName);
+         for(String jobName : jobNames)
+            scheduler.deleteJob(jobName, groupName);
+      }
+      catch(SchedulerException e)
+      {
+         log.error("shutdown failed", e);
+         // TODO: ignore?
+      }
+   }
+   
+   public String toString()
+   {
+      return "Timer Service " + invoker;
+   }
+}

Copied: projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,17 @@
+<head>
+	<body>
+		This package provides the EJB Timer Service to the EJB3 stack.
+		<p/>
+		It replaces the org.jboss.ejb.txtimer package.
+		<p/>
+		The Jboss EJB3 Timer Service package depends on:
+		<ul>
+			<li>EJB3 API</li>
+			<li>Quartz</li>
+			<li>JTA</li>
+		</ul>
+		<p/>
+		Note that almost all exceptions are caught and rethrown as EJBExceptions, thus
+		making sure that no Quartz API is exposed either compile time or run time.
+	</body>
+</head>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-quartz/src/main/resources/META-INF/jboss-beans.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/main/resources/META-INF/jboss-beans.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/main/resources/META-INF/jboss-beans.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <bean name="QuartzTimerServiceFactory" class="org.jboss.ejb3.timerservice.quartz.QuartzTimerServiceFactory">
+      <property name="dataSource">java:/DefaultDS</property>
+      <property name="properties">
+         <map class="java.util.Properties" keyClass="java.lang.String" valueClass="java.lang.String">
+            <entry><key>org.quartz.jobStore.class</key><value>org.quartz.impl.jdbcjobstore.JobStoreCMT</value></entry>
+            <entry><key>org.quartz.jobStore.nonManagedTXDataSource</key><value>myDS</value></entry>
+            <!-- We're using a non managed TX data source -->
+            <!-- TODO: in testing we're not using a JCA compliant data source as well -->
+            <entry><key>org.quartz.jobStore.dontSetAutoCommitFalse</key><value>true</value></entry>
+            <entry><key>org.quartz.jobStore.driverDelegateClass</key><value>org.quartz.impl.jdbcjobstore.HSQLDBDelegate</value></entry>
+            <entry><key>org.quartz.jobStore.tablePrefix</key><value>QRTZ_</value></entry>
+            <entry><key>org.quartz.jobStore.dataSource</key><value>myDS</value></entry>
+            
+            <!-- To get it to work with hypersonic -->
+            <!-- FIXME: this doesn't lock the row -->
+            <entry><key>org.quartz.jobStore.selectWithLockSQL</key><value>SELECT * FROM QRTZ_LOCKS WHERE lock_name = ?</value></entry>
+            
+            <!-- from quartz.properties -->
+            <entry><key>org.quartz.scheduler.instanceName</key><value>JBossEJB3QuartzScheduler</value></entry>
+            <entry><key>org.quartz.scheduler.rmi.export</key><value>false</value></entry>
+            <entry><key>org.quartz.scheduler.rmi.proxy</key><value>false</value></entry>
+            <entry><key>org.quartz.scheduler.wrapJobExecutionInUserTransaction</key><value>false</value></entry>
+               
+            <entry><key>org.quartz.threadPool.class</key><value>org.quartz.simpl.SimpleThreadPool</value></entry>
+            <entry><key>org.quartz.threadPool.threadCount</key><value>10</value></entry>
+            <entry><key>org.quartz.threadPool.threadPriority</key><value>5</value></entry>
+            <entry><key>org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread</key><value>true</value></entry>
+               
+            <entry><key>org.quartz.jobStore.misfireThreshold</key><value>60000</value></entry>
+         </map>
+      </property>
+      <property name="sqlProperties">
+         <map class="java.util.Properties" keyClass="java.lang.String" valueClass="java.lang.String">
+         <entry><key>CREATE_DB_ON_STARTUP</key><value>TRUE</value></entry>
+         
+         <entry><key>CREATE_TABLE_JOB_DETAILS</key><value>CREATE TABLE QRTZ_JOB_DETAILS(JOB_NAME VARCHAR(80) NOT NULL, JOB_GROUP VARCHAR(80) NOT NULL, 
+                        DESCRIPTION VARCHAR(120), JOB_CLASS_NAME VARCHAR(128) NOT NULL, IS_DURABLE VARCHAR(1) NOT NULL, 
+                        IS_VOLATILE VARCHAR(1) NOT NULL, IS_STATEFUL VARCHAR(1) NOT NULL, REQUESTS_RECOVERY VARCHAR(1) NOT NULL, 
+                        JOB_DATA BINARY NULL, PRIMARY KEY (JOB_NAME,JOB_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_JOB_LISTENERS</key><value>CREATE TABLE QRTZ_JOB_LISTENERS(JOB_NAME VARCHAR(80) NOT NULL, JOB_GROUP VARCHAR(80) NOT NULL, 
+                        JOB_LISTENER VARCHAR(80) NOT NULL, PRIMARY KEY (JOB_NAME,JOB_GROUP,JOB_LISTENER), FOREIGN KEY (JOB_NAME,JOB_GROUP) 
+                        REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_TRIGGERS</key><value>CREATE TABLE QRTZ_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, TRIGGER_GROUP VARCHAR(80) NOT NULL, 
+                        JOB_NAME VARCHAR(80) NOT NULL, JOB_GROUP VARCHAR(80) NOT NULL, IS_VOLATILE VARCHAR(1) NOT NULL, DESCRIPTION VARCHAR(120), 
+                        NEXT_FIRE_TIME NUMERIC(13), PREV_FIRE_TIME NUMERIC(13), TRIGGER_STATE VARCHAR(16) NOT NULL, 
+                        TRIGGER_TYPE VARCHAR(8) NOT NULL, START_TIME NUMERIC(13) NOT NULL, END_TIME NUMERIC(13), CALENDAR_NAME VARCHAR(80), 
+                        MISFIRE_INSTR NUMERIC(2), JOB_DATA BINARY NULL, PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (JOB_NAME,JOB_GROUP) 
+                        REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_SIMPLE_TRIGGERS</key><value>CREATE TABLE QRTZ_SIMPLE_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, 
+                        TRIGGER_GROUP VARCHAR(80) NOT NULL, REPEAT_COUNT NUMERIC(7) NOT NULL, REPEAT_INTERVAL NUMERIC(12) NOT NULL, 
+                        TIMES_TRIGGERED NUMERIC(7) NOT NULL, PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) 
+                        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_CRON_TRIGGERS</key><value>CREATE TABLE QRTZ_CRON_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, 
+                        TRIGGER_GROUP VARCHAR(80) NOT NULL, CRON_EXPRESSION VARCHAR(80) NOT NULL, TIME_ZONE_ID VARCHAR(80), 
+                        PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) 
+                        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_BLOB_TRIGGERS</key><value>CREATE TABLE QRTZ_BLOB_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, 
+                        TRIGGER_GROUP VARCHAR(80) NOT NULL, BLOB_DATA BINARY NULL, PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), 
+                        FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_TRIGGER_LISTENERS</key><value>CREATE TABLE QRTZ_TRIGGER_LISTENERS(TRIGGER_NAME VARCHAR(80) NOT NULL, 
+                        TRIGGER_GROUP VARCHAR(80) NOT NULL, TRIGGER_LISTENER VARCHAR(80) NOT NULL, 
+                        PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_LISTENER), FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) 
+                        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_CALENDARS</key><value>CREATE TABLE QRTZ_CALENDARS(CALENDAR_NAME VARCHAR(80) NOT NULL, CALENDAR BINARY NOT NULL, 
+                        PRIMARY KEY (CALENDAR_NAME))</value></entry>
+         <entry><key>CREATE_TABLE_PAUSED_TRIGGER_GRPS</key><value>CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS(TRIGGER_GROUP VARCHAR(80) NOT NULL, 
+                        PRIMARY KEY (TRIGGER_GROUP))</value></entry>
+         <entry><key>CREATE_TABLE_FIRED_TRIGGERS</key><value>CREATE TABLE QRTZ_FIRED_TRIGGERS(ENTRY_ID VARCHAR(95) NOT NULL, TRIGGER_NAME VARCHAR(80) NOT NULL, 
+                        TRIGGER_GROUP VARCHAR(80) NOT NULL, IS_VOLATILE VARCHAR(1) NOT NULL, INSTANCE_NAME VARCHAR(80) NOT NULL, 
+                        FIRED_TIME NUMERIC(13) NOT NULL, STATE VARCHAR(16) NOT NULL, JOB_NAME VARCHAR(80), JOB_GROUP VARCHAR(80), 
+                        IS_STATEFUL VARCHAR(1), REQUESTS_RECOVERY VARCHAR(1), PRIMARY KEY (ENTRY_ID))</value></entry>
+         <entry><key>CREATE_TABLE_SCHEDULER_STATE</key><value>CREATE TABLE QRTZ_SCHEDULER_STATE(INSTANCE_NAME VARCHAR(80) NOT NULL, 
+                        LAST_CHECKIN_TIME NUMERIC(13) NOT NULL, CHECKIN_INTERVAL NUMERIC(13) NOT NULL, RECOVERER VARCHAR(80), 
+                        PRIMARY KEY (INSTANCE_NAME))</value></entry>
+         <entry><key>CREATE_TABLE_LOCKS</key><value>CREATE TABLE QRTZ_LOCKS(LOCK_NAME VARCHAR(40) NOT NULL, PRIMARY KEY (LOCK_NAME))</value></entry>
+         <entry><key>INSERT_TRIGGER_ACCESS</key><value>INSERT INTO QRTZ_LOCKS values('TRIGGER_ACCESS')</value></entry>
+         <entry><key>INSERT_JOB_ACCESS</key><value>INSERT INTO QRTZ_LOCKS values('JOB_ACCESS')</value></entry>
+         <entry><key>INSERT_CALENDAR_ACCESS</key><value>INSERT INTO QRTZ_LOCKS values('CALENDAR_ACCESS')</value></entry>
+         <entry><key>INSERT_STATE_ACCESS</key><value>INSERT INTO QRTZ_LOCKS values('STATE_ACCESS')</value></entry>
+         <entry><key>INSERT_MISFIRE_ACCESS</key><value>INSERT INTO QRTZ_LOCKS values('MISFIRE_ACCESS')</value></entry>
+         </map>
+      </property>
+      <property name="transactionManager"><inject bean="XRealTransactionManager"/></property>
+   </bean>
+</deployment>

Copied: projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/DerbyService.java (from rev 83459, projects/jpa/trunk/deployers/src/test/java/org/jboss/jpa/deployers/test/common/DerbyService.java)
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/DerbyService.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/DerbyService.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz.test.common;
+
+import java.sql.Connection;
+
+import javax.naming.InitialContext;
+
+import org.apache.derby.jdbc.EmbeddedDataSource;
+import org.jboss.logging.Logger;
+
+/**
+ * @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class DerbyService
+{
+   private static final Logger log = Logger.getLogger(DerbyService.class);
+   
+   private String className = "org.apache.derby.jdbc.EmbeddedDataSource";
+   private String databaseName = "./target/derby.db";
+   private boolean createDatabase = true;
+   private String jndiName = "java:/DefaultDS";
+   
+   private EmbeddedDataSource ds;
+   private InitialContext ctx;
+   
+   public void create() throws Exception
+   {
+      log.info("Creating derby service");
+      
+      System.setProperty("derby.stream.error.file", "target/derby.log");
+      
+      Class<? extends EmbeddedDataSource> cls = (Class<? extends EmbeddedDataSource>) Class.forName(className);
+      this.ds = cls.newInstance();
+      ds.setDatabaseName(databaseName);
+      if(createDatabase)
+         ds.setCreateDatabase("create");
+      
+      ctx = new InitialContext();
+   }
+   
+   public void destroy() throws Exception
+   {
+      log.info("Destroying derby service");
+      
+      ctx.close();
+      ctx = null;
+      ds = null;
+   }
+   
+   public void setJndiName(String jndiName)
+   {
+      this.jndiName = jndiName;
+   }
+   
+   public void start() throws Exception
+   {
+      log.info("Starting derby service");
+      
+      // Make sure that database is created before we go on.
+      Connection con = ds.getConnection();
+      con.close();
+      
+      ctx.bind(jndiName, ds);
+   }
+   
+   public void stop() throws Exception
+   {
+      log.info("Stopping derby service");
+      
+      ctx.unbind(jndiName);
+   }
+}

Added: projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/HSQLDBService.java
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/HSQLDBService.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/HSQLDBService.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz.test.common;
+
+import java.sql.Connection;
+
+import javax.naming.InitialContext;
+
+import org.hsqldb.jdbc.jdbcDataSource;
+import org.jboss.logging.Logger;
+
+/**
+ * @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class HSQLDBService
+{
+   private static final Logger log = Logger.getLogger(HSQLDBService.class);
+   
+   private String jndiName = "java:/DefaultDS";
+   
+   private jdbcDataSource ds;
+   private InitialContext ctx;
+   private Connection conn;
+   
+   public void create() throws Exception
+   {
+      log.info("Creating HSQLDB service");
+      
+      ds = new jdbcDataSource();
+      ds.setDatabase("jdbc:hsqldb:file:target/hsqldb/db");
+      ds.setUser("sa");
+      ds.setPassword("");
+      
+      ctx = new InitialContext();
+   }
+   
+   public void destroy() throws Exception
+   {
+      log.info("Destroying HSQLDB service");
+      
+      if(ctx != null)
+      {
+         ctx.close();
+         ctx = null;
+      }
+      ds = null;
+   }
+   
+   public void start() throws Exception
+   {
+      log.info("Starting HSQLDB service");
+      
+      conn = ds.getConnection();
+      
+      ctx.bind(jndiName, ds);
+   }
+   
+   public void stop() throws Exception
+   {
+      log.info("Stopping HSQLDB service");
+      
+      ctx.unbind(jndiName);
+      
+      if(conn != null)
+      {
+         conn.close();
+         conn = null;
+      }
+   }
+}

Added: projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/SimpleClassLoaderDeployer.java
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/SimpleClassLoaderDeployer.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/common/SimpleClassLoaderDeployer.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz.test.common;
+
+import org.jboss.deployers.spi.deployer.helpers.AbstractTopLevelClassLoaderDeployer;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+
+/**
+ * @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class SimpleClassLoaderDeployer extends AbstractTopLevelClassLoaderDeployer
+{
+   @Override
+   protected ClassLoader createTopLevelClassLoader(DeploymentUnit unit) throws Exception
+   {
+      return Thread.currentThread().getContextClassLoader();
+   }
+}

Added: projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/simple/unit/SimpleUnitTestCase.java
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/simple/unit/SimpleUnitTestCase.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/java/org/jboss/ejb3/timerservice/quartz/test/simple/unit/SimpleUnitTestCase.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,165 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.quartz.test.simple.unit;
+
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import javax.ejb.Timer;
+import javax.ejb.TimerService;
+
+import org.jboss.bootstrap.microcontainer.ServerImpl;
+import org.jboss.bootstrap.spi.ServerConfig;
+import org.jboss.bootstrap.spi.microcontainer.MCServer;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.deployers.client.spi.main.MainDeployer;
+import org.jboss.deployers.vfs.spi.client.VFSDeployment;
+import org.jboss.deployers.vfs.spi.client.VFSDeploymentFactory;
+import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker;
+import org.jboss.ejb3.timerservice.spi.TimerServiceFactory;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.logging.Logger;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class SimpleUnitTestCase
+{
+   private static Logger log = Logger.getLogger(SimpleUnitTestCase.class);
+   
+   private static MCServer server;
+   
+   private static String findDir(String path) throws IOException
+   {
+      File file = new File(path);
+      boolean success = file.isDirectory();
+      if(!success)
+         throw new IOException("failed to find " + path);
+      return file.toURI().toString();
+   }
+   
+   private static String mkdir(String path) throws IOException
+   {
+      File file = new File(path);
+      boolean success = file.mkdirs() || file.isDirectory();
+      if(!success)
+         throw new IOException("failed to create " + path);
+      return file.toURI().toURL().toString();
+   }
+   
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception
+   {
+      server = new ServerImpl();
+      
+      Properties props = new Properties();
+      String dir = mkdir("target/bootstrap");
+      mkdir("target/bootstrap/server/default");
+      //mkdir("target/bootstrap/server/default/deploy");
+      mkdir("target/bootstrap/server/default/data");
+      mkdir("target/bootstrap/server/default/log");
+      mkdir("target/bootstrap/server/default/tmp");
+      mkdir("target/bootstrap/server/default/tmp/deploy");
+      mkdir("target/bootstrap/server/default/tmp/native");
+      log.info("dir = " + dir);
+      props.put(ServerConfig.HOME_DIR, dir);
+      props.put(ServerConfig.SERVER_CONFIG_URL, findDir("src/test/resources/conf"));
+      server.init(props);
+      
+      server.start();
+      
+      MainDeployer mainDeployer = (MainDeployer) server.getKernel().getController().getContext("MainDeployer", ControllerState.INSTALLED).getTarget();
+      
+      URL url = new File("src/main/resources").toURI().toURL();
+      log.debug("url = " + url);
+      VirtualFile root = VFS.getRoot(url);
+      VFSDeployment deployment = VFSDeploymentFactory.getInstance().createVFSDeployment(root);
+      mainDeployer.deploy(deployment);
+      mainDeployer.checkComplete(deployment);
+   }
+
+   @AfterClass
+   public static void tearDownAfterClass() throws Exception
+   {
+      if(server != null)
+         server.shutdown();
+   }
+   
+   @Test
+   public void test1() throws Exception
+   {
+      final Semaphore semaphore = new Semaphore(0);
+      
+      TimedObjectInvoker dummy = new TimedObjectInvoker()
+      {
+         public void callTimeout(Timer timer) throws Exception
+         {
+            log.info("Timeout " + timer);
+            semaphore.release();
+         }
+
+         public String getTimedObjectId()
+         {
+            return "dummy";
+         }
+      };
+      
+      TimerServiceFactory factory = getTimerServiceFactory();
+      
+      TimerService timerService = factory.createTimerService(dummy);
+      
+      factory.restoreTimerService(timerService);
+      
+      Timer timer = timerService.createTimer(1000, "Hello world");
+      log.info("timer = " + timer);
+      
+      boolean success = semaphore.tryAcquire(10, TimeUnit.SECONDS);
+      
+      factory.suspendTimerService(timerService);
+      
+      assertTrue(success);
+   }
+
+   private static TimerServiceFactory getTimerServiceFactory()
+   {
+      Set<KernelControllerContext> candidates = server.getKernel().getController().getContexts(TimerServiceFactory.class, ControllerState.INSTALLED);
+      if(candidates.size() == 0)
+         throw new IllegalStateException("No TimerServiceFactory installed");
+      if(candidates.size() > 1)
+         throw new IllegalStateException("Multiple TimerServiceFactories found " + candidates);
+      return (TimerServiceFactory) candidates.iterator().next().getTarget();
+   }
+}

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/derby.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/derby.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/derby.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <!-- As a 'mock' DataSource we use Derby -->
+   <bean name="DerbyService" class="org.jboss.ejb3.timerservice.quartz.test.common.DerbyService">
+      <depends>NamingServer</depends>
+   </bean>
+</deployment>

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/hsqldb.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/hsqldb.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/hsqldb.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <!-- As a 'mock' DataSource we use HSQLDB -->
+   <bean name="HSQLDBService" class="org.jboss.ejb3.timerservice.quartz.test.common.HSQLDBService">
+      <depends>NamingServer</depends>
+   </bean>
+</deployment>

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/jmx-jdk.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/jmx-jdk.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/jmx-jdk.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <bean name="MBeanServer" class="javax.management.MBeanServer">
+      <constructor factoryClass="javax.management.MBeanServerFactory" factoryMethod="newMBeanServer"/>
+   </bean>
+</deployment>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/maindeployer.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/maindeployer.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/maindeployer.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <bean name="SimpleClassLoaderDeployer" class="org.jboss.ejb3.timerservice.quartz.test.common.SimpleClassLoaderDeployer"/>
+   
+   <!-- The MainDeployer -->
+   <bean name="MainDeployer" class="org.jboss.deployers.plugins.main.MainDeployerImpl">
+      <property name="structuralDeployers"><inject bean="StructuralDeployers"/></property>
+      <property name="deployers"><inject bean="Deployers"/></property>
+      <!--property name="mgtDeploymentCreator"><inject bean="ManagedDeploymentCreator"/></property-->
+   </bean>
+      
+   <!-- The holder for deployers that determine structure -->
+   <bean name="StructuralDeployers" class="org.jboss.deployers.vfs.plugins.structure.VFSStructuralDeployersImpl">
+      <property name="structureBuilder">
+         <!-- The consolidator of the structure information -->
+         <bean name="StructureBuilder" class="org.jboss.deployers.vfs.plugins.structure.VFSStructureBuilder"/>
+      </property>
+      <!-- Accept any implementor of structure deployer -->
+      <incallback method="addDeployer"/>
+      <uncallback method="removeDeployer"/>
+   </bean>
+   
+   <!-- The holder for deployers that do real deployment -->
+   <bean name="Deployers" class="org.jboss.deployers.plugins.deployers.DeployersImpl">
+      <constructor><parameter><inject bean="jboss.kernel:service=KernelController"/></parameter></constructor>
+      <!-- Accept any implementor of deployer -->
+      <incallback method="addDeployer"/>
+      <uncallback method="removeDeployer"/>
+   </bean>
+   
+   <!-- File Structure -->
+   <bean name="FileStructure" class="org.jboss.deployers.vfs.plugins.structure.file.FileStructure"/>
+   
+   <!-- File Structure -->
+   <bean name="JARStructure" class="org.jboss.deployers.vfs.plugins.structure.jar.JARStructure"/>
+   
+   <!-- POJO Deployment -->
+   <bean name="BeanDeployer" class="org.jboss.deployers.vfs.deployer.kernel.BeanDeployer"/>
+   <bean name="KernelDeploymentDeployer" class="org.jboss.deployers.vfs.deployer.kernel.KernelDeploymentDeployer"/>
+   <bean name="BeanMetaDataDeployer" class="org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer">
+      <constructor><parameter class="org.jboss.kernel.Kernel"><inject bean="jboss.kernel:service=Kernel"/></parameter></constructor>
+   </bean>
+</deployment>

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/naming.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/naming.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/naming.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <!-- JNDI -->
+   <bean name="NamingServer" class="org.jnp.server.SingletonNamingServer"/>
+   
+   <bean name="JavaCompInitializer" class="org.jboss.naming.JavaCompInitializer">
+      <depends>NamingServer</depends>
+   </bean>
+</deployment>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/transactionmanager.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/transactionmanager.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap/transactionmanager.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   <!-- JTA -->
+   <!-- 
+   <bean name="TransactionManager" class="org.jboss.ejb3.embedded.service.SimpleTransactionService">
+      <depends>NamingServer</depends>
+   </bean>
+   -->
+   
+   <bean name="TransactionManager" class="com.arjuna.ats.jbossatx.jta.TransactionManagerService">
+      <!-- 
+      <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss:service=TransactionManager",exposedInterface=com.arjuna.ats.jbossatx.jta.TransactionManagerServiceMBean.class,registerDirectly=true)</annotation>
+      -->
+
+      <property name="transactionTimeout">300</property>
+      <property name="objectStoreDir">${jboss.server.data.dir}/tx-object-store</property>
+      <property name="mbeanServer"><inject bean="MBeanServer"/></property>
+
+      <property name="transactionStatusManagerInetAddress">localhost</property>
+      <property name="transactionStatusManagerPort">5712</property>
+
+      <property name="recoveryInetAddress">localhost</property>
+      <property name="recoveryPort">5713</property>
+
+      <property name="socketProcessIdPort">0</property>
+
+   </bean>
+
+   <bean name="RealTransactionManager">
+      <constructor factoryMethod="getTransactionManager">
+         <factory bean="TransactionManager"/>
+      </constructor>
+   </bean>
+</deployment>

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/conf/bootstrap.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bootstrap xmlns="urn:jboss:bootstrap:1.0">
+<!-- 
+   <url>bootstrap/vfs.xml</url>
+   <url>bootstrap/classloader.xml</url>
+   <url>bootstrap/aop.xml</url>
+   <url>bootstrap/jmx.xml</url>
+   <url>bootstrap/deployers.xml</url>
+   <url>bootstrap/bindings.xml</url>
+   <url>bootstrap/profile-service.xml</url>
+-->
+   <url>bootstrap/naming.xml</url>
+   <url>bootstrap/jmx-jdk.xml</url>
+   <url>bootstrap/transactionmanager.xml</url>
+   <url>bootstrap/maindeployer.xml</url>
+   <url>bootstrap/hsqldb.xml</url>
+</bootstrap>

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/jndi.properties
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/jndi.properties	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/jndi.properties	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,2 @@
+java.naming.factory.initial=org.jnp.interfaces.LocalOnlyContextFactory
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Added: projects/ejb3/trunk/timerservice-quartz/src/test/resources/log4j.xml
===================================================================
--- projects/ejb3/trunk/timerservice-quartz/src/test/resources/log4j.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-quartz/src/test/resources/log4j.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!--                                                                       -->
+<!--  Log4j Configuration                                                  -->
+<!--                                                                       -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml 68671 2008-01-08 10:04:25Z wolfc $ -->
+
+<!--
+   | For more configuration infromation and examples see the Jakarta Log4j
+   | owebsite: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+  <!-- ================================= -->
+  <!-- Preserve messages in a local file -->
+  <!-- ================================= -->
+
+  <!-- A time/date based rolling appender -->
+  <appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
+    <param name="File" value="target/test.log"/>
+    <param name="Append" value="false"/>
+
+    <!-- Rollover at midnight each day -->
+    <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+    <!-- Rollover at the top of each hour
+    <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
+    -->
+
+    <layout class="org.apache.log4j.PatternLayout">
+      <!-- The default pattern: Date Priority [Category] Message\n -->
+      <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+
+      <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
+      <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+       -->
+    </layout>	    
+  </appender>
+
+  <!-- A size based file rolling appender
+  <appender name="FILE" class="org.jboss.logging.appender.RollingFileAppender">
+    <param name="File" value="${jboss.server.home.dir}/log/server.log"/>
+    <param name="Append" value="false"/>
+    <param name="MaxFileSize" value="500KB"/>
+    <param name="MaxBackupIndex" value="1"/>
+
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+    </layout>	    
+  </appender>
+  -->
+
+  <!-- ============================== -->
+  <!-- Append messages to the console -->
+  <!-- ============================== -->
+
+  <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.out"/>
+    <param name="Threshold" value="ALL"/>
+
+    <layout class="org.apache.log4j.PatternLayout">
+      <!-- The default pattern: Date Priority [Category] Message\n -->
+      <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+    </layout>
+  </appender>
+
+
+  <!-- ================ -->
+  <!-- Limit categories -->
+  <!-- ================ -->
+
+  <!-- Limit JBoss categories to INFO
+  <category name="org.jboss">
+    <priority value="INFO" class="org.jboss.logging.XLevel"/>
+  </category>
+  -->
+
+  <!-- Increase the priority threshold for the DefaultDS category
+  <category name="DefaultDS">
+    <priority value="FATAL"/>
+  </category>
+  -->
+
+  <!-- Decrease the priority threshold for the org.jboss.varia category
+  <category name="org.jboss.varia">
+    <priority value="DEBUG"/>
+  </category>
+  -->
+
+  <!--
+     | An example of enabling the custom TRACE level priority that is used
+     | by the JBoss internals to diagnose low level details. This example
+     | turns on TRACE level msgs for the org.jboss.ejb.plugins package and its
+     | subpackages. This will produce A LOT of logging output.
+  <category name="org.jboss.system">
+    <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+  </category>
+  -->
+
+  <category name="org.jboss">
+    <priority value="INFO"/>
+  </category>
+  
+  <category name="org.quartz">
+    <priority value="INFO"/>
+  </category>
+  
+  <!-- ======================= -->
+  <!-- Setup the Root category -->
+  <!-- ======================= -->
+
+  <root>
+    <priority value="WARN" />
+    <appender-ref ref="CONSOLE"/>
+    <appender-ref ref="FILE"/>
+  </root>
+  
+</log4j:configuration>


Property changes on: projects/ejb3/trunk/timerservice-spi
___________________________________________________________________
Name: svn:ignore
   + eclipse-target
target


Added: projects/ejb3/trunk/timerservice-spi/.classpath
===================================================================
--- projects/ejb3/trunk/timerservice-spi/.classpath	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-spi/.classpath	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,6 @@
+<classpath>
+  <classpathentry kind="src" path="src/main/java"/>
+  <classpathentry kind="output" path="eclipse-target/classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+</classpath>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-spi/.project
===================================================================
--- projects/ejb3/trunk/timerservice-spi/.project	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-spi/.project	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,17 @@
+<projectDescription>
+  <name>jboss-ejb3-timerservice-spi</name>
+  <comment>JBoss EJB 3.0 TimerService SPI</comment>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.maven.ide.eclipse.maven2Builder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>org.maven.ide.eclipse.maven2Nature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Added: projects/ejb3/trunk/timerservice-spi/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- projects/ejb3/trunk/timerservice-spi/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-spi/.settings/org.eclipse.jdt.core.prefs	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,5 @@
+#Tue Jan 27 12:43:19 CET 2009
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5

Added: projects/ejb3/trunk/timerservice-spi/pom.xml
===================================================================
--- projects/ejb3/trunk/timerservice-spi/pom.xml	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-spi/pom.xml	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  vi:ts=2:sw=2:expandtab:
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.jboss.ejb3</groupId>
+    <artifactId>jboss-ejb3-build</artifactId>
+    <version>1.0.0</version>
+    <relativePath>../build/pom.xml</relativePath>
+  </parent>
+
+  <!-- Maven POM Model Version -->
+  <modelVersion>4.0.0</modelVersion>
+
+  <!-- Artifact Information -->
+  <artifactId>jboss-ejb3-timerservice-spi</artifactId>
+  <packaging>jar</packaging>
+  <version>0.1.0-SNAPSHOT</version>
+  <name>JBoss EJB 3.x TimerService SPI</name>
+  <description>JBoss EJB 3.x TimerService SPI</description>
+  <url>http://labs.jboss.com/jbossejb3/</url>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.javaee</groupId>
+      <artifactId>jboss-ejb-api</artifactId>
+    </dependency>    
+  </dependencies>
+</project>

Copied: projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimedObjectInvoker.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/TimedObjectInvoker.java)
===================================================================
--- projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimedObjectInvoker.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimedObjectInvoker.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.spi;
+
+import javax.ejb.Timer;
+
+/**
+ * An implementation can invoke the ejbTimeout method on a TimedObject.
+ *
+ * The TimedObjectInvoker has knowledge of the TimedObjectId, it
+ * knows which object to invoke.
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
+ */
+public interface TimedObjectInvoker
+{
+   /**
+    * The globally unique identifier for this timed object invoker.
+    * 
+    * @return the identifier
+    */
+   String getTimedObjectId();
+   
+   /**
+    * Invokes the ejbTimeout method on the TimedObject with the given id.
+    *
+    * @param timer the Timer that is passed to ejbTimeout
+    */
+   void callTimeout(Timer timer) throws Exception;
+
+}

Copied: projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimerServiceFactory.java (from rev 83454, projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/timerservice/TimerServiceFactory.java)
===================================================================
--- projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimerServiceFactory.java	                        (rev 0)
+++ projects/ejb3/trunk/timerservice-spi/src/main/java/org/jboss/ejb3/timerservice/spi/TimerServiceFactory.java	2009-01-28 09:04:24 UTC (rev 83545)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.timerservice.spi;
+
+import javax.ejb.TimerService;
+
+/**
+ * Creates an EJB TimerService for TimedObjectInvokers.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public interface TimerServiceFactory
+{
+   /**
+    * Create an EJB TimerService for the given TimedObjectInvoker.
+    * 
+    * @param invoker the TimerObjectInvoker for which a TimerService must be created
+    * @return the EJB TimerService for the TimerObjectInvoker
+    * @throws NullPointerException if invoker is null
+    */
+   TimerService createTimerService(TimedObjectInvoker invoker);
+   
+   /**
+    * Restores the timers held by the specified timer service.
+    * Once a TimerObjectInvoker is ready to receive callbacks, it should call this function.
+    * 
+    * @param timerService the timerService that should restore its timers
+    * @throws NullPointerException if timerService is null
+    */
+   void restoreTimerService(TimerService timerService);
+   
+   /**
+    * Suspends the timers held by the specified timer service.
+    * Note that after this method there should be reference anymore to the TimerObjectInvoker.
+    * 
+    * @param timerService
+    * @throws NullPointerException if timerService is null
+    */
+   void suspendTimerService(TimerService timerService);
+}




More information about the jboss-cvs-commits mailing list