activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r479145 - in /incubator/activemq/trunk: ./ activemq-core/ activemq-core/src/main/java/org/apache/activemq/store/jpa/ activemq-core/src/test/java/org/apache/activemq/broker/store/ activemq-jpa-store/ activemq-jpa-store/src/ activemq-jpa-stor...
Date Sat, 25 Nov 2006 16:56:13 GMT
Author: chirino
Date: Sat Nov 25 08:56:12 2006
New Revision: 479145

URL: http://svn.apache.org/viewvc?view=rev&rev=479145
Log:
Moved the new JPA module to it's own directory.


Added:
    incubator/activemq/trunk/activemq-jpa-store/
    incubator/activemq/trunk/activemq-jpa-store/pom.xml   (with props)
    incubator/activemq/trunk/activemq-jpa-store/src/
    incubator/activemq/trunk/activemq-jpa-store/src/main/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAMessageStore.java
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAPersistenceAdapter.java   (with props)
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPATopicMessageStore.java
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredMessage.java
    incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredSubscription.java
    incubator/activemq/trunk/activemq-jpa-store/src/main/resources/
    incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/
    incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/DISCLAIMER.txt
    incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/LICENSE.txt   (with props)
    incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/NOTICE.txt
    incubator/activemq/trunk/activemq-jpa-store/src/test/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/store/
    incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/store/JPARecoveryBrokerTest.java
    incubator/activemq/trunk/activemq-jpa-store/src/test/resources/
Removed:
    incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/store/jpa/
    incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/broker/store/JPARecoveryBrokerTest.java
Modified:
    incubator/activemq/trunk/activemq-core/pom.xml
    incubator/activemq/trunk/pom.xml

Modified: incubator/activemq/trunk/activemq-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-core/pom.xml?view=diff&rev=479145&r1=479144&r2=479145
==============================================================================
--- incubator/activemq/trunk/activemq-core/pom.xml (original)
+++ incubator/activemq/trunk/activemq-core/pom.xml Sat Nov 25 08:56:12 2006
@@ -162,10 +162,6 @@
       <version>1.2.24</version>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.openjpa</groupId>
-      <artifactId>openjpa-persistence-jdbc</artifactId>
-    </dependency>    
   </dependencies>
 
   <build>
@@ -279,7 +275,6 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-antrun-plugin</artifactId>
-        <!-- 
         <configuration>
           <tasks>
             <taskdef name="generate" classname="org.apache.activemq.openwire.tool.JavaGeneratorTask"/>
@@ -293,37 +288,6 @@
             <version>${activemq-version}</version>
           </dependency>
         </dependencies>
-         -->
-        
-        <executions>
-          <execution>
-            <phase>process-classes</phase>
-            <configuration>
-              <tasks>
-                <path id="cp">
-                  <path refid="maven.test.classpath"/>
-                  <path refid="maven.compile.classpath"/>
-                  <path refid="maven.dependency.classpath"/>
-                </path>
-                <taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
-                  <classpath refid="cp"/>
-                </taskdef>
-                <openjpac directory="${basedir}/target/jpa-classes">
-                  <classpath refid="cp"/>
-                  <fileset dir="${basedir}/target/classes">
-                    <include name="org/apache/activemq/store/jpa/model/*.class"/>
-                  </fileset>
-                </openjpac>
-                <copy todir="${basedir}/target/classes">
-                  <fileset dir="${basedir}/target/jpa-classes"/>
-                </copy>
-              </tasks>
-            </configuration>
-            <goals>
-              <goal>run</goal>
-            </goals>
-          </execution>
-        </executions>
       </plugin>
 
       <plugin>

Added: incubator/activemq/trunk/activemq-jpa-store/pom.xml
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/pom.xml?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/pom.xml (added)
+++ incubator/activemq/trunk/activemq-jpa-store/pom.xml Sat Nov 25 08:56:12 2006
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+   
+    http://www.apache.org/licenses/LICENSE-2.0
+   
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<project
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns="http://maven.apache.org/POM/4.0.0">
+  
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.activemq</groupId>
+    <artifactId>activemq-parent</artifactId>
+    <version>4.2-incubator-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>activemq-jpa-store</artifactId>
+  <packaging>jar</packaging>
+  <name>ActiveMQ :: JPA Message Store</name>
+
+  <dependencies>
+    <!-- activemq -->
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>activemq-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>activemq-core</artifactId>
+      <scope>compile</scope>
+      <type>test-jar</type>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa-persistence-jdbc</artifactId>
+    </dependency>
+
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <configuration>
+              <tasks>
+                <path id="cp">
+                  <path refid="maven.test.classpath"/>
+                  <path refid="maven.compile.classpath"/>
+                  <path refid="maven.dependency.classpath"/>
+                </path>
+                <taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
+                  <classpath refid="cp"/>
+                </taskdef>
+                <openjpac directory="${basedir}/target/jpa-classes">
+                  <classpath refid="cp"/>
+                  <fileset dir="${basedir}/target/classes">
+                    <include name="org/apache/activemq/store/jpa/model/*.class"/>
+                  </fileset>
+                </openjpac>
+                <copy todir="${basedir}/target/classes">
+                  <fileset dir="${basedir}/target/jpa-classes"/>
+                </copy>
+              </tasks>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>

Propchange: incubator/activemq/trunk/activemq-jpa-store/pom.xml
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAMessageStore.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAMessageStore.java?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAMessageStore.java (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAMessageStore.java Sat Nov 25 08:56:12 2006
@@ -0,0 +1,194 @@
+package org.apache.activemq.store.jpa;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.Message;
+import org.apache.activemq.command.MessageAck;
+import org.apache.activemq.command.MessageId;
+import org.apache.activemq.memory.UsageManager;
+import org.apache.activemq.store.MessageRecoveryListener;
+import org.apache.activemq.store.MessageStore;
+import org.apache.activemq.store.jpa.model.StoredMessage;
+import org.apache.activemq.util.ByteSequence;
+import org.apache.activemq.util.IOExceptionSupport;
+import org.apache.activemq.wireformat.WireFormat;
+
+public class JPAMessageStore implements MessageStore {
+
+	protected final JPAPersistenceAdapter adapter;
+	protected final WireFormat wireFormat;
+	protected final ActiveMQDestination destination;
+	protected final String destinationName;
+    protected AtomicLong lastMessageId = new AtomicLong(-1);
+
+	public JPAMessageStore(JPAPersistenceAdapter adapter, ActiveMQDestination destination) {
+		this.adapter = adapter;
+		this.destination = destination;
+		this.destinationName = destination.getQualifiedName();
+		this.wireFormat = this.adapter.getWireFormat();
+	}
+
+	public void addMessage(ConnectionContext context, Message message) throws IOException {
+		
+		EntityManager manager = adapter.beginEntityManager(context);
+		try {
+			
+			ByteSequence sequence = wireFormat.marshal(message);
+			sequence.compact();
+			
+			StoredMessage sm = new StoredMessage();
+			sm.setDestination(destinationName);
+			sm.setId(message.getMessageId().getBrokerSequenceId());
+			sm.setMessageId(message.getMessageId().toString());
+			sm.setExiration(message.getExpiration());
+			sm.setData(sequence.data);
+		
+			manager.persist(sm);
+			
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(context,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(context,manager);		
+	}
+
+	public void addMessageReference(ConnectionContext context,
+			MessageId messageId, long expirationTime, String messageRef)
+			throws IOException {
+		throw new IOException("Not implemented.");
+	}
+
+	public ActiveMQDestination getDestination() {
+		return destination;
+	}
+
+	public Message getMessage(MessageId identity) throws IOException {
+		Message rc;
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+			StoredMessage message=null;
+			if( identity.getBrokerSequenceId()!= 0 ) {
+				message = manager.find(StoredMessage.class, identity.getBrokerSequenceId());			
+			} else {
+				Query query = manager.createQuery("select m from StoredMessage m where m.messageId=?1");
+				query.setParameter(1, identity.toString());
+				message = (StoredMessage) query.getSingleResult();
+			}
+			
+			rc = (Message) wireFormat.unmarshal(new ByteSequence(message.getData()));
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+		return rc;
+	}
+
+	public int getMessageCount() throws IOException {
+		Integer rc;
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+			Query query = manager.createQuery("select count(m) from StoredMessage m");
+			rc = (Integer) query.getSingleResult();
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+		return rc;
+	}
+
+	public String getMessageReference(MessageId identity) throws IOException {
+		throw new IOException("Not implemented.");
+	}
+
+	public void recover(MessageRecoveryListener container) throws Exception {
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+			Query query = manager.createQuery("select m from StoredMessage m where m.destination=?1 order by m.id asc");
+			query.setParameter(1, destinationName);
+			for (StoredMessage m : (List<StoredMessage>)query.getResultList()) {
+				Message message = (Message) wireFormat.unmarshal(new ByteSequence(m.getData()));
+				container.recoverMessage(message);
+	        }
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+	}
+
+	public void recoverNextMessages(int maxReturned, MessageRecoveryListener listener) throws Exception {
+		
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+			
+			Query query = manager.createQuery("select m from StoredMessage m where m.destination=?1 and m.id>?2 order by m.id asc");
+			query.setParameter(1, destinationName);
+			query.setParameter(2, lastMessageId.get());
+			query.setMaxResults(maxReturned);
+			int count = 0;
+			for (StoredMessage m : (List<StoredMessage>)query.getResultList()) {
+				Message message = (Message) wireFormat.unmarshal(new ByteSequence(m.getData()));
+				listener.recoverMessage(message);
+				lastMessageId.set(m.getId());
+				count++;
+				if( count >= maxReturned ) { 
+					return;
+				}
+	        }
+
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+	}
+
+	public void removeAllMessages(ConnectionContext context) throws IOException {
+		EntityManager manager = adapter.beginEntityManager(context);
+		try {
+			Query query = manager.createQuery("delete from StoredMessage m where m.destination=?1");
+			query.setParameter(1, destinationName);
+			query.executeUpdate();
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(context,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(context,manager);
+	}
+
+	public void removeMessage(ConnectionContext context, MessageAck ack) throws IOException {
+		EntityManager manager = adapter.beginEntityManager(context);
+		try {
+			Query query = manager.createQuery("delete from StoredMessage m where m.id=?1");
+			query.setParameter(1, ack.getLastMessageId().getBrokerSequenceId());
+			query.executeUpdate();
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(context,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(context,manager);
+	}
+
+	public void resetBatching() {
+        lastMessageId.set(-1);
+	}
+
+	public void setUsageManager(UsageManager usageManager) {
+	}
+
+	public void start() throws Exception {
+	}
+
+	public void stop() throws Exception {
+	}
+
+}

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAPersistenceAdapter.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAPersistenceAdapter.java?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAPersistenceAdapter.java (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAPersistenceAdapter.java Sat Nov 25 08:56:12 2006
@@ -0,0 +1,253 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.store.jpa;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.ActiveMQQueue;
+import org.apache.activemq.command.ActiveMQTopic;
+import org.apache.activemq.memory.UsageManager;
+import org.apache.activemq.openwire.OpenWireFormatFactory;
+import org.apache.activemq.store.MessageStore;
+import org.apache.activemq.store.PersistenceAdapter;
+import org.apache.activemq.store.TopicMessageStore;
+import org.apache.activemq.store.TransactionStore;
+import org.apache.activemq.store.memory.MemoryTransactionStore;
+import org.apache.activemq.util.IOExceptionSupport;
+import org.apache.activemq.wireformat.WireFormat;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * An implementation of {@link PersistenceAdapter} that uses JPA to
+ * store it's messages.
+ * 
+ * @org.apache.xbean.XBean
+ * 
+ * @version $Revision: 1.17 $
+ */
+public class JPAPersistenceAdapter implements PersistenceAdapter {
+
+    private static final Log log = LogFactory.getLog(JPAPersistenceAdapter.class);
+    String entityManagerName = "activemq";
+	Properties entityManagerProperties = System.getProperties();
+	EntityManagerFactory entityManagerFactory;
+	private WireFormat wireFormat;
+	private MemoryTransactionStore transactionStore;
+	
+	public void beginTransaction(ConnectionContext context) throws IOException {
+		if( context.getLongTermStoreContext()!=null )
+			throw new IOException("Transation already started.");
+		
+		EntityManager manager = getEntityManagerFactory().createEntityManager();		
+		manager.getTransaction().begin();
+		context.setLongTermStoreContext(manager);
+	}
+
+	public void commitTransaction(ConnectionContext context) throws IOException {
+		EntityManager manager = (EntityManager) context.getLongTermStoreContext();
+		if( manager==null )
+			throw new IOException("Transation not started.");
+		context.setLongTermStoreContext(null);
+		manager.getTransaction().commit();
+		manager.close();
+	}
+	
+	public void rollbackTransaction(ConnectionContext context) throws IOException {
+		EntityManager manager = (EntityManager) context.getLongTermStoreContext();
+		if( manager==null )
+			throw new IOException("Transation not started.");
+		context.setLongTermStoreContext(null);
+		manager.getTransaction().rollback();
+		manager.close();
+	}
+	
+	public EntityManager beginEntityManager(ConnectionContext context) {
+		if( context==null || context.getLongTermStoreContext()==null ) {
+			EntityManager manager = getEntityManagerFactory().createEntityManager();		
+			manager.getTransaction().begin();
+			return manager;
+		} else {
+			return (EntityManager) context.getLongTermStoreContext();
+		}
+	}
+	
+	public void commitEntityManager(ConnectionContext context, EntityManager manager) {		
+		if( context==null || context.getLongTermStoreContext()==null ) {
+			manager.getTransaction().commit();
+			manager.close();
+		} 
+	}
+	
+	public void rollbackEntityManager(ConnectionContext context, EntityManager manager) {		
+		if( context==null || context.getLongTermStoreContext()==null ) {
+			manager.getTransaction().rollback();
+			manager.close();
+		} 
+	}
+
+	public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException {
+		MessageStore rc =  new JPAMessageStore(this, destination);
+        if (transactionStore != null) {
+            rc = transactionStore.proxy(rc);
+        }
+        return rc;
+	}
+
+	public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException {
+		TopicMessageStore rc = new JPATopicMessageStore(this, destination);
+        if (transactionStore != null) {
+            rc = transactionStore.proxy(rc);
+        }
+        return rc;
+	}
+
+	public TransactionStore createTransactionStore() throws IOException {
+        if (transactionStore == null) {
+            transactionStore = new MemoryTransactionStore();
+        }
+        return this.transactionStore;
+	}
+
+	public void deleteAllMessages() throws IOException {
+		EntityManager manager = beginEntityManager(null);
+		try {
+			Query query = manager.createQuery("delete from StoredMessage m");
+			query.executeUpdate();
+			query = manager.createQuery("delete from StoredSubscription ss");
+			query.executeUpdate();
+		} catch (Throwable e) {
+			rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		commitEntityManager(null,manager);		
+	}
+
+	public Set getDestinations() {
+		HashSet<ActiveMQDestination> rc = new HashSet<ActiveMQDestination>();
+		
+		EntityManager manager = beginEntityManager(null);
+		try {
+			Query query = manager.createQuery("select distinct m.destination from StoredMessage m");
+			for (String dest : (List<String>)query.getResultList()) {
+				rc.add(ActiveMQDestination.createDestination(dest,ActiveMQDestination.QUEUE_TYPE));
+	        }
+		} catch (RuntimeException e) {
+			rollbackEntityManager(null,manager);
+			throw e;
+		}
+		commitEntityManager(null,manager);		
+		return rc;
+	}
+
+	public long getLastMessageBrokerSequenceId() throws IOException {
+		long rc=0;
+		EntityManager manager = beginEntityManager(null);
+		try {
+			Query query = manager.createQuery("select max(m.id) from StoredMessage m");
+			Long t = (Long) query.getSingleResult();
+			if( t != null ) {
+				rc = t;
+			}
+		} catch (Throwable e) {
+			rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		commitEntityManager(null,manager);		
+		return rc;
+	}
+
+	public boolean isUseExternalMessageReferences() {
+		return false;
+	}
+
+	public void setUsageManager(UsageManager usageManager) {
+	}
+
+	public void setUseExternalMessageReferences(boolean enable) {
+		if( enable ) {
+			throw new IllegalArgumentException("This persistence adapter does not support externa message references");
+		}
+	}
+
+	public void start() throws Exception {
+	}
+
+	public void stop() throws Exception {
+		if( entityManagerFactory !=null ) {
+			entityManagerFactory.close();
+		}
+	}
+
+	public EntityManagerFactory getEntityManagerFactory() {
+		if( entityManagerFactory == null ) {
+			entityManagerFactory = createEntityManagerFactory();
+		}
+		return entityManagerFactory;
+	}
+	protected EntityManagerFactory createEntityManagerFactory() {
+		return Persistence.createEntityManagerFactory(getEntityManagerName(), getEntityManagerProperties());
+	}
+
+	public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
+		this.entityManagerFactory = entityManagerFactory;
+	}
+
+	public Properties getEntityManagerProperties() {
+		return entityManagerProperties;
+	}
+	public void setEntityManagerProperties(
+			Properties entityManagerProperties) {
+		this.entityManagerProperties = entityManagerProperties;
+	}
+
+	public String getEntityManagerName() {
+		return entityManagerName;
+	}
+	public void setEntityManagerName(String entityManager) {
+		this.entityManagerName = entityManager;
+	}
+
+	public WireFormat getWireFormat() {
+		if(wireFormat==null) {
+			wireFormat = createWireFormat();
+		}
+		return wireFormat;
+	}
+
+	private WireFormat createWireFormat() {
+		OpenWireFormatFactory wff = new OpenWireFormatFactory();
+		return wff.createWireFormat(); 
+	}
+
+	public void setWireFormat(WireFormat wireFormat) {
+		this.wireFormat = wireFormat;
+	}
+
+}

Propchange: incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPAPersistenceAdapter.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPATopicMessageStore.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPATopicMessageStore.java?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPATopicMessageStore.java (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/JPATopicMessageStore.java Sat Nov 25 08:56:12 2006
@@ -0,0 +1,233 @@
+package org.apache.activemq.store.jpa;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.Message;
+import org.apache.activemq.command.MessageId;
+import org.apache.activemq.command.SubscriptionInfo;
+import org.apache.activemq.store.MessageRecoveryListener;
+import org.apache.activemq.store.TopicMessageStore;
+import org.apache.activemq.store.jpa.model.StoredMessage;
+import org.apache.activemq.store.jpa.model.StoredSubscription;
+import org.apache.activemq.store.jpa.model.StoredSubscription.SubscriptionId;
+import org.apache.activemq.util.ByteSequence;
+import org.apache.activemq.util.IOExceptionSupport;
+
+public class JPATopicMessageStore extends JPAMessageStore implements TopicMessageStore {
+    private Map<SubscriptionId,AtomicLong> subscriberLastMessageMap=new ConcurrentHashMap<SubscriptionId,AtomicLong>();
+
+	public JPATopicMessageStore(JPAPersistenceAdapter adapter, ActiveMQDestination destination) {
+		super(adapter, destination);
+	}
+
+	public void acknowledge(ConnectionContext context, String clientId, String subscriptionName, MessageId messageId) throws IOException {
+		EntityManager manager = adapter.beginEntityManager(context);
+		try {
+			StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
+			ss.setLastAckedId(messageId.getBrokerSequenceId());
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(context,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(context,manager);
+	}
+
+	public void addSubsciption(String clientId, String subscriptionName, String selector, boolean retroactive) throws IOException {
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {			
+			StoredSubscription ss = new StoredSubscription();
+			ss.setClientId(clientId);
+			ss.setSubscriptionName(subscriptionName);
+			ss.setDestination(destinationName);
+			ss.setSelector(selector);
+			ss.setLastAckedId(-1);
+			
+			if( !retroactive ) {
+				Query query = manager.createQuery("select max(m.id) from StoredMessage m");
+				Long rc = (Long) query.getSingleResult();
+				if( rc != null ) {
+					ss.setLastAckedId(rc);
+				}
+			}
+			
+			manager.persist(ss);
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+	}
+
+	public void deleteSubscription(String clientId, String subscriptionName) throws IOException {
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {			
+			StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
+			manager.remove(ss);
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+	}
+
+	private StoredSubscription findStoredSubscription(EntityManager manager, String clientId, String subscriptionName) {
+		Query query = manager.createQuery(
+				"select ss from StoredSubscription ss " +
+				"where ss.clientId=?1 " +
+				"and ss.subscriptionName=?2 " +
+				"and ss.destination=?3");
+		query.setParameter(1, clientId);
+		query.setParameter(2, subscriptionName);
+		query.setParameter(3, destinationName);
+		List<StoredSubscription> resultList = query.getResultList();
+		if( resultList.isEmpty() )
+			return null;
+		return resultList.get(0); 
+	}
+
+	public SubscriptionInfo[] getAllSubscriptions() throws IOException {
+		SubscriptionInfo rc[];
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+			ArrayList<SubscriptionInfo> l = new ArrayList<SubscriptionInfo>();
+			
+			Query query = manager.createQuery("select ss from StoredSubscription ss where ss.destination=?1");
+			query.setParameter(1, destinationName);
+			for (StoredSubscription ss : (List<StoredSubscription>)query.getResultList()) {
+				SubscriptionInfo info = new SubscriptionInfo();
+				info.setClientId(ss.getClientId());
+				info.setDestination(destination);
+				info.setSelector(ss.getSelector());
+				info.setSubcriptionName(ss.getSubscriptionName());
+				l.add(info);
+	        }
+			
+			rc = new SubscriptionInfo[l.size()];
+			l.toArray(rc);
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);		
+		return rc;
+	}
+
+	public int getMessageCount(String clientId, String subscriptionName) throws IOException {
+		Integer rc;
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {	
+			Query query = manager.createQuery(
+					"select count(m) FROM StoredMessage m, StoredSubscription ss " +
+					"where ss.clientId=?1 " +
+					"and   ss.subscriptionName=?2 " +
+					"and   ss.destination=?3 " +
+					"and   m.desination=ss.destination and m.id > ss.lastAckedId");
+			query.setParameter(1, clientId);
+			query.setParameter(2, subscriptionName);
+			query.setParameter(2, destinationName);
+	        rc = (Integer) query.getSingleResult();	        
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+		return rc;
+	}
+
+	public SubscriptionInfo lookupSubscription(String clientId, String subscriptionName) throws IOException {
+		SubscriptionInfo rc=null;
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {			
+			StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
+			if( ss != null ) {
+				rc = new SubscriptionInfo();
+				rc.setClientId(ss.getClientId());
+				rc.setDestination(destination);
+				rc.setSelector(ss.getSelector());
+				rc.setSubcriptionName(ss.getSubscriptionName());
+			}
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+		return rc;
+	}
+
+	public void recoverNextMessages(String clientId, String subscriptionName, int maxReturned, MessageRecoveryListener listener) throws Exception {
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+			SubscriptionId id = new SubscriptionId();
+			id.setClientId(clientId);
+			id.setSubscriptionName(subscriptionName);
+			id.setDestination(destinationName);
+	
+			AtomicLong last=subscriberLastMessageMap.get(id);
+	        if(last==null){
+	    		StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
+	            last=new AtomicLong(ss.getLastAckedId());
+	            subscriberLastMessageMap.put(id,last);
+	        }
+	        final AtomicLong lastMessageId=last;
+			
+			Query query = manager.createQuery("select m from StoredMessage m where m.destination=?1 and m.id>?2 order by m.id asc");
+			query.setParameter(1, destinationName);
+			query.setParameter(2, lastMessageId.get());
+			query.setMaxResults(maxReturned);
+			int count = 0;
+			for (StoredMessage m : (List<StoredMessage>)query.getResultList()) {
+				Message message = (Message) wireFormat.unmarshal(new ByteSequence(m.getData()));
+				listener.recoverMessage(message);
+				lastMessageId.set(m.getId());
+				count++;
+				if( count >= maxReturned ) { 
+					return;
+				}
+	        }        
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+	}
+
+	public void recoverSubscription(String clientId, String subscriptionName, MessageRecoveryListener listener) throws Exception {
+		EntityManager manager = adapter.beginEntityManager(null);
+		try {
+	
+			StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
+			
+			Query query = manager.createQuery("select m from StoredMessage m where m.destination=?1 and m.id>?2 order by m.id asc");
+			query.setParameter(1, destinationName);
+			query.setParameter(2, ss.getLastAckedId());
+			for (StoredMessage m : (List<StoredMessage>)query.getResultList()) {
+				Message message = (Message) wireFormat.unmarshal(new ByteSequence(m.getData()));
+				listener.recoverMessage(message);
+	        }
+		} catch (Throwable e) {
+			adapter.rollbackEntityManager(null,manager);
+			throw IOExceptionSupport.create(e);
+		}
+		adapter.commitEntityManager(null,manager);
+	}
+
+	public void resetBatching(String clientId, String subscriptionName) {
+		SubscriptionId id = new SubscriptionId();
+		id.setClientId(clientId);
+		id.setSubscriptionName(subscriptionName);
+		id.setDestination(destinationName);
+
+        subscriberLastMessageMap.remove(id);
+	}
+
+}

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredMessage.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredMessage.java?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredMessage.java (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredMessage.java Sat Nov 25 08:56:12 2006
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.store.jpa.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/** 
+ */
+@Entity
+public class StoredMessage {
+	
+    @Id
+    private long id;
+	
+    @Basic
+    private String messageId;
+
+    @Basic
+    private String destination;
+
+    @Basic
+    private long exiration;
+
+    @Basic
+    private byte[] data;
+
+    public StoredMessage() {
+    }
+
+	public byte[] getData() {
+		return data;
+	}
+
+	public void setData(byte[] data) {
+		this.data = data;
+	}
+
+	public String getDestination() {
+		return destination;
+	}
+
+	public void setDestination(String destination) {
+		this.destination = destination;
+	}
+
+	public long getExiration() {
+		return exiration;
+	}
+
+	public void setExiration(long exiration) {
+		this.exiration = exiration;
+	}
+
+	public String getMessageId() {
+		return messageId;
+	}
+
+	public void setMessageId(String messageId) {
+		this.messageId = messageId;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long sequenceId) {
+		this.id = sequenceId;
+	}
+
+}

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredSubscription.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredSubscription.java?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredSubscription.java (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/java/org/apache/activemq/store/jpa/model/StoredSubscription.java Sat Nov 25 08:56:12 2006
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.store.jpa.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+/** 
+ */
+@Entity
+public class StoredSubscription {
+		
+	/**
+     * Application identity class for Magazine.
+     */
+    public static class SubscriptionId {
+
+	    public String destination;
+	    public String clientId;
+	    public String subscriptionName;
+
+        public boolean equals(Object other) {
+            if (other == this)
+                return true;
+            if (!(other instanceof SubscriptionId))
+                return false;
+    
+            SubscriptionId sid = (SubscriptionId) other;
+            return (destination == sid.destination || (destination != null && destination.equals(sid.destination)))
+                && (clientId == sid.clientId || (clientId != null && clientId.equals(sid.clientId)))
+                && (subscriptionName == sid.subscriptionName || (subscriptionName != null && subscriptionName.equals(sid.subscriptionName)));
+        }
+     
+        /**
+         * Hashcode must also depend on identity values.
+         */
+        public int hashCode() {
+            return ((destination == null) ? 0 : destination.hashCode())
+                ^ ((clientId == null) ? 0 : clientId.hashCode())
+                ^ ((subscriptionName == null) ? 0 : subscriptionName.hashCode())
+                ;
+        } 
+
+        public String toString() {
+            return destination + ":" + clientId + ":" + subscriptionName;
+        }
+
+		public String getClientId() {
+			return clientId;
+		}
+
+		public void setClientId(String clientId) {
+			this.clientId = clientId;
+		}
+
+		public String getDestination() {
+			return destination;
+		}
+
+		public void setDestination(String destination) {
+			this.destination = destination;
+		}
+
+		public String getSubscriptionName() {
+			return subscriptionName;
+		}
+
+		public void setSubscriptionName(String subscriptionName) {
+			this.subscriptionName = subscriptionName;
+		}
+    }
+
+    @Id
+    @GeneratedValue(strategy=GenerationType.AUTO) 
+    private long id;
+    
+    @Basic
+    private String destination;
+    @Basic
+    private String clientId;
+    @Basic
+    private String subscriptionName;
+    
+    @Basic
+    private long lastAckedId;
+    @Basic
+    private String selector;
+
+
+	public long getLastAckedId() {
+		return lastAckedId;
+	}
+
+	public void setLastAckedId(long lastAckedId) {
+		this.lastAckedId = lastAckedId;
+	}
+
+	public String getSelector() {
+		return selector;
+	}
+
+	public void setSelector(String selector) {
+		this.selector = selector;
+	}
+
+	public String getDestination() {
+		return destination;
+	}
+
+	public void setDestination(String destination) {
+		this.destination = destination;
+	}
+
+	public String getClientId() {
+		return clientId;
+	}
+
+	public void setClientId(String clientId) {
+		this.clientId = clientId;
+	}
+
+	public String getSubscriptionName() {
+		return subscriptionName;
+	}
+
+	public void setSubscriptionName(String subscriptionName) {
+		this.subscriptionName = subscriptionName;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+}

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/DISCLAIMER.txt
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/DISCLAIMER.txt?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/DISCLAIMER.txt (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/DISCLAIMER.txt Sat Nov 25 08:56:12 2006
@@ -0,0 +1,7 @@
+ActiveMQ is an effort undergoing incubation at the Apache Software Foundation
+(ASF), sponsored by the Geronimo PMC. Incubation is required of all newly
+accepted projects until a further review indicates that the infrastructure,
+communications, and decision making process have stabilized in a manner
+consistent with other successful ASF projects. While incubation status is not
+necessarily a reflection of the completeness or stability of the code, it does
+indicate that the project has yet to be fully endorsed by the ASF.
\ No newline at end of file

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/LICENSE.txt
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/LICENSE.txt?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/LICENSE.txt (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/LICENSE.txt Sat Nov 25 08:56:12 2006
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+

Propchange: incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/LICENSE.txt
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/NOTICE.txt
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/NOTICE.txt?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/NOTICE.txt (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/main/resources/META-INF/NOTICE.txt Sat Nov 25 08:56:12 2006
@@ -0,0 +1,12 @@
+=========================================================================
+==  NOTICE file corresponding to the section 4 d of                    ==
+==  the Apache License, Version 2.0,                                   ==
+==  in this case for the Apache ActiveMQ distribution.                 ==
+=========================================================================
+
+Apache ActiveMQ
+Copyright 2005-2006 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+

Added: incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/store/JPARecoveryBrokerTest.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/store/JPARecoveryBrokerTest.java?view=auto&rev=479145
==============================================================================
--- incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/store/JPARecoveryBrokerTest.java (added)
+++ incubator/activemq/trunk/activemq-jpa-store/src/test/java/org/apache/activemq/broker/store/JPARecoveryBrokerTest.java Sat Nov 25 08:56:12 2006
@@ -0,0 +1,71 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.broker.store;
+
+import java.util.Properties;
+
+import junit.framework.Test;
+
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.RecoveryBrokerTest;
+import org.apache.activemq.store.jpa.JPAPersistenceAdapter;
+
+/**
+ * Used to verify that recovery works correctly against 
+ * 
+ * @version $Revision$
+ */
+public class JPARecoveryBrokerTest extends RecoveryBrokerTest {
+
+    protected BrokerService createBroker() throws Exception {
+        BrokerService service = new BrokerService();
+        service.setDeleteAllMessagesOnStartup(true);
+        JPAPersistenceAdapter pa = new JPAPersistenceAdapter();
+        Properties props = new Properties();
+        props.setProperty("openjpa.ConnectionDriverName", "org.apache.derby.jdbc.EmbeddedDriver");
+        props.setProperty("openjpa.ConnectionURL", "jdbc:derby:activemq-data/derby;create=true");
+        props.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema");
+        props.setProperty("openjpa.Log", "DefaultLevel=WARN,SQL=TRACE");
+        pa.setEntityManagerProperties(props);
+        service.setPersistenceAdapter(pa);
+        return service;
+        
+    }
+    
+    protected BrokerService createRestartedBroker() throws Exception {
+        BrokerService service = new BrokerService();
+        JPAPersistenceAdapter pa = new JPAPersistenceAdapter();
+        Properties props = new Properties();
+        props.setProperty("openjpa.ConnectionDriverName", "org.apache.derby.jdbc.EmbeddedDriver");
+        props.setProperty("openjpa.ConnectionURL", "jdbc:derby:activemq-data/derby;create=true");
+        props.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema");
+        props.setProperty("openjpa.Log", "DefaultLevel=WARN,SQL=TRACE");
+        pa.setEntityManagerProperties(props);
+        service.setPersistenceAdapter(pa);
+        return service;
+    }
+    
+    public static Test suite() {
+        return suite(JPARecoveryBrokerTest.class);
+    }
+    
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+}

Modified: incubator/activemq/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/pom.xml?view=diff&rev=479145&r1=479144&r2=479145
==============================================================================
--- incubator/activemq/trunk/pom.xml (original)
+++ incubator/activemq/trunk/pom.xml Sat Nov 25 08:56:12 2006
@@ -139,6 +139,7 @@
     <module>activemq-openwire-generator</module>
     <module>activemq-xmpp</module>
     <module>assembly</module>
+    <module>activemq-jpa-store</module>
   </modules>
 
   <scm>



Mime
View raw message