activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r633639 [3/7] - in /activemq/sandbox/activemq-router: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/activemq/ src/main/java/org/apache/activemq/broker/ src/main/java/org/apache/active...
Date Tue, 04 Mar 2008 21:01:57 GMT
Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/ReferenceIndex.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/ReferenceIndex.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/ReferenceIndex.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/ReferenceIndex.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,37 @@
+/**
+ * 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.router.index.api;
+
+import java.util.List;
+
+/**
+ * 
+ * @author chirino
+ */
+public interface ReferenceIndex extends Index {
+
+    /**
+     * Adds a reference record to this store.
+     * 
+     * @param id
+     * @throws Exception
+     */
+    public void addReference(IndexEntry id) throws Exception;
+
+    public List<IndexEntry> remove(IndexEntry first, IndexEntry last, int max) throws Exception;
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/package.html
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/package.html?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/package.html (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/api/package.html Tue Mar  4 13:01:41 2008
@@ -0,0 +1,26 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+   
+    http://www.apache.org/licenses/LICENSE-2.0
+   
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<html>
+<head>
+</head>
+<body>
+
+Defines the interfaces that indexes should implement.  Indexes are used by DataStores
+like the journal to index the data contained in it's data stores. 
+
+</body>
+</html>

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndex.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndex.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndex.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndex.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,325 @@
+/**
+ * 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.router.index.jpa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.router.index.api.DataIndex;
+import org.apache.activemq.broker.router.index.api.IndexEntry;
+import org.apache.activemq.broker.router.index.api.ReferenceIndex;
+import org.apache.activemq.broker.router.index.jpa.JpaDataIndexManager.EntityManagerAction;
+import org.apache.activemq.broker.router.index.jpa.model.IndexRecord;
+import org.apache.activemq.broker.router.index.jpa.model.Record;
+import org.apache.activemq.broker.router.index.jpa.model.StoreMetadata;
+import org.apache.activemq.kaha.impl.async.Location;
+
+/**
+ * 
+ * @author chirino
+ */
+public class JpaDataIndex extends JpaIndex implements DataIndex {
+
+    private final JpaIndexManager<ReferenceIndex> indexManager = new JpaIndexManager<ReferenceIndex>() {
+        @Override
+        protected ReferenceIndex createStore(String name) throws Exception {
+            StoreMetadata referenceMetatdata = manager.createStoreMetadata(storeMetadata.getId(), name);
+            JpaReferenceIndex rc = new JpaReferenceIndex(JpaDataIndex.this, referenceMetatdata);
+            return rc;
+        }
+
+        @Override
+        protected void destroyStore(ReferenceIndex store) throws Exception {
+            final JpaReferenceIndex jpaReferenceIndex = (JpaReferenceIndex) store;
+            executeTransacted(new EntityManagerAction<Object>() {
+                public Object execute(EntityManager em) throws Exception {
+                    jpaReferenceIndex.remove(em);
+                    return null;
+                }
+            });
+        }
+
+        @Override
+        protected HashMap<String, ReferenceIndex> createExistingStores() throws Exception {
+            HashMap<String, ReferenceIndex> rc = new HashMap<String, ReferenceIndex>();
+            List<StoreMetadata> stores = manager.listStoreMetadata(storeMetadata.getId());
+            for (StoreMetadata storeMetadata : stores) {
+                rc.put(storeMetadata.getName(), new JpaReferenceIndex(JpaDataIndex.this, storeMetadata));
+            }
+            return rc;
+        }
+
+    };
+
+    private final AtomicBoolean lastIndexLoaded = new AtomicBoolean();
+    private final AtomicReference<IndexRecord> lastAddedIndexRecord = new AtomicReference<IndexRecord>();
+
+    public JpaDataIndex(JpaDataIndexManager parent, StoreMetadata storeMetadata) {
+        super(parent, storeMetadata);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Delegate methods to IndexManager
+    // /////////////////////////////////////////////////////////////////
+    public ReferenceIndex addStore(String name) throws Exception {
+        return indexManager.addStore(name);
+    }
+
+    public ReferenceIndex getStore(String name) throws Exception {
+        return indexManager.getStore(name);
+    }
+
+    public List<ReferenceIndex> getStores() throws Exception {
+        return indexManager.getStores();
+    }
+
+    public void removeStore(ReferenceIndex store) throws Exception {
+        indexManager.removeStore(store);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Interface to DataIndex
+    // /////////////////////////////////////////////////////////////////
+
+    public IndexEntry addMessage(long id, Location location) throws Exception {
+        final IndexRecord rc = new IndexRecord();
+        rc.setRowId(getNextRowId());
+        rc.setId(id);
+        rc.setLocation(location);
+        rc.setStore(storeMetadata.getId());
+        rc.setIndex(this);
+        return executeTransacted(new EntityManagerAction<IndexEntry>() {
+            public IndexEntry execute(EntityManager em) {
+                em.persist(rc);
+                lastAddedIndexRecord.set(rc);
+                return rc;
+            }
+        });
+    }
+
+    private long getNextRowId() {
+        return manager.getLastIndexRecordRowId().incrementAndGet();
+    }
+
+    public IndexEntry redoAddMessage(final long id, final Location location) throws Exception {
+
+        IndexRecord rc = executeTransacted(new EntityManagerAction<IndexRecord>() {
+            @SuppressWarnings("unchecked")
+            public IndexRecord execute(EntityManager em) {
+
+                Query query = em.createQuery("SELECT r FROM IndexRecord r WHERE r.store=?1 AND r.id=?2");
+                query.setParameter(1, storeMetadata.getId());
+                query.setParameter(2, id);
+                List<IndexRecord> result = query.getResultList();
+                if (!result.isEmpty()) {
+                    return result.get(0);
+                } else {
+                    IndexRecord rc = new IndexRecord();
+                    rc.setRowId(getNextRowId());
+                    rc.setId(id);
+                    rc.setLocation(location);
+                    rc.setStore(storeMetadata.getId());
+                    rc.setIndex(JpaDataIndex.this);
+
+                    em.persist(rc);
+                    lastAddedIndexRecord.set(rc);
+                    return rc;
+                }
+            }
+        });
+        return rc;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean remove(final long id) throws Exception {
+        return executeTransacted(new EntityManagerAction<Boolean>() {
+            public Boolean execute(EntityManager em) {
+
+                // Delete the references..
+
+                // Delete the record..
+                Query query = em.createQuery("SELECT r FROM IndexRecord r WHERE r.id=?1 AND r.store=?2");
+                query.setParameter(1, id);
+                query.setParameter(2, storeMetadata.getId());
+                List<IndexRecord> rs = query.getResultList();
+                for (IndexRecord r : rs) {
+                    Query q2 = em.createQuery("DELETE FROM ReferenceRecord r WHERE r.record.rowId=?1");
+                    q2.setParameter(1, r.getRowId());
+                    q2.executeUpdate();
+                    em.remove(r);
+                    return true;
+                }
+                return false;
+            }
+        });
+    }
+
+    public void redoRemove(final long id) throws Exception {
+        executeTransacted(new EntityManagerAction<Object>() {
+            public Object execute(EntityManager em) {
+
+                Query query = em.createQuery("DELETE FROM IndexRecord r WHERE r.id=?1 AND r.store=?2");
+                query.setParameter(1, id);
+                query.setParameter(2, storeMetadata.getId());
+                query.executeUpdate();
+
+                return null;
+            }
+        });
+
+    }
+
+    public void removeUnreferencedRecords(IndexEntry maxId) throws Exception {
+        throw new Exception("TODO: implement this method.");
+    }
+
+    public void setAutoRemove(boolean enable) {
+    }
+
+    public IndexRecord getLastAddedIndexRecord() throws Exception {
+        IndexRecord rc = lastAddedIndexRecord.get();
+        if (rc == null && !lastIndexLoaded.get()) {
+            lastIndexLoaded.set(true);
+            rc = executeUnTransacted(new EntityManagerAction<IndexRecord>() {
+
+                @SuppressWarnings("unchecked")
+                public IndexRecord execute(EntityManager em) {
+                    Query query = em.createQuery("SELECT r FROM IndexRecord r WHERE r.store=?1 ORDER BY r.rowId DESC");
+                    query.setParameter(1, storeMetadata.getId());
+                    query.setMaxResults(1);
+                    List<IndexRecord> rc = query.getResultList();
+                    if (rc.isEmpty()) {
+                        return null;
+                    }
+                    return rc.get(0);
+                }
+            });
+        }
+        return rc;
+    }
+
+    public IndexEntry getLastAddedId() throws Exception {
+        IndexRecord rc = getLastAddedIndexRecord();
+        if (rc == null) {
+            return null;
+        }
+        return rc;
+    }
+
+    public long size() throws Exception {
+        return executeUnTransacted(new EntityManagerAction<Long>() {
+            public Long execute(EntityManager em) {
+                Query query = em.createQuery("SELECT count(r) FROM IndexRecord r WHERE r.store=?1");
+                query.setParameter(1, storeMetadata.getId());
+                return (Long) query.getSingleResult();
+            }
+        });
+    }
+
+    public boolean contains(final long id) throws Exception {
+        return executeUnTransacted(new EntityManagerAction<Boolean>() {
+            @SuppressWarnings("unchecked")
+            public Boolean execute(EntityManager em) {
+                Query query = em.createQuery("SELECT count(r) FROM IndexRecord r WHERE r.store=?1 AND r.id=?2");
+                query.setParameter(1, storeMetadata.getId());
+                query.setParameter(2, id);
+                return ((Long) query.getSingleResult()).longValue() > 0;
+            }
+        });
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<IndexEntry> load(IndexEntry firstIE, IndexEntry lastIE, final int max) throws Exception {
+
+        final IndexRecord first = (IndexRecord) firstIE;
+        final IndexRecord last = (IndexRecord) lastIE;
+
+        return executeUnTransacted(new EntityManagerAction<List<IndexEntry>>() {
+            public List<IndexEntry> execute(EntityManager em) {
+                ArrayList<IndexEntry> rc = new ArrayList<IndexEntry>(max);
+                Query query;
+
+                query = createSelectRecordsBetween(em, "SELECT r FROM IndexRecord r WHERE ", storeMetadata.getId(), first, last);
+                query.setMaxResults(max);
+
+                List<IndexRecord> rs = query.getResultList();
+                for (IndexRecord r : rs) {
+                    if (rc.size() >= max) {
+                        break;
+                    }
+                    r.setIndex(JpaDataIndex.this);
+                    rc.add(r);
+                }
+                return rc;
+            }
+
+        });
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Implementation Methods
+    // /////////////////////////////////////////////////////////////////
+    @Override
+    public void remove(EntityManager em) throws Exception {
+        // Get rid of the reference stores.
+        List<ReferenceIndex> stores = getStores();
+        for (ReferenceIndex referenceIndex : stores) {
+            ((JpaReferenceIndex) referenceIndex).remove(em);
+        }
+
+        // Get rid of the data..
+        Query query = em.createQuery("DELETE FROM IndexRecord r WHERE r.store=?1");
+        query.setParameter(1, storeMetadata.getId());
+        query.executeUpdate();
+
+        // This gets rid of the metadata..
+        super.remove(em);
+    }
+
+    static public Query createSelectRecordsBetween(EntityManager em, String select, long store, Record first, Record last) {
+        Query query;
+        String q = select + " r.store=?1";
+        int c = 2;
+        if (first != null) {
+            q += " AND ?" + c + " < r.rowId";
+            c++;
+        }
+        if (last != null) {
+            q += " AND r.rowId <= ?" + c;
+        }
+        q += " ORDER BY r.rowId";
+
+        query = em.createQuery(q);
+        query.setParameter(1, store);
+        c = 2;
+        if (first != null) {
+            query.setParameter(c, first.getRowId());
+            c++;
+        }
+        if (last != null) {
+            query.setParameter(c, last.getRowId());
+        }
+        return query;
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndexManager.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndexManager.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndexManager.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaDataIndexManager.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,280 @@
+/**
+ * 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.router.index.jpa;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.router.index.api.DataIndex;
+import org.apache.activemq.broker.router.index.api.DataIndexManager;
+import org.apache.activemq.broker.router.index.jpa.model.IndexRecord;
+import org.apache.activemq.broker.router.index.jpa.model.StoreMetadata;
+import org.apache.activemq.kaha.impl.async.Location;
+
+/**
+ * 
+ * @author chirino
+ */
+public class JpaDataIndexManager implements DataIndexManager {
+
+    private EntityManagerFactory entityManagerFactory;
+    private String entityManagerName = "activemq";
+    private Properties entityManagerProperties = System.getProperties();
+
+    private final AtomicLong lastIndexRecordRowId = new AtomicLong();
+    private final AtomicLong lastReferenceRecordRowId = new AtomicLong();
+
+    private final JpaIndexManager<DataIndex> indexManager = new JpaIndexManager<DataIndex>() {
+        @Override
+        protected DataIndex createStore(String name) throws Exception {
+            StoreMetadata indexData = createStoreMetadata(name);
+            JpaDataIndex rc = new JpaDataIndex(JpaDataIndexManager.this, indexData);
+            return rc;
+        }
+
+        @Override
+        protected void destroyStore(DataIndex store) throws Exception {
+            final JpaDataIndex jpaDataIndex = (JpaDataIndex) store;
+            executeTransacted(new EntityManagerAction<Object>() {
+                public Object execute(EntityManager em) throws Exception {
+                    jpaDataIndex.remove(em);
+                    return null;
+                }
+            });
+        }
+
+        @Override
+        protected HashMap<String, DataIndex> createExistingStores() throws Exception {
+            HashMap<String, DataIndex> rc = new HashMap<String, DataIndex>();
+            List<StoreMetadata> stores = listStoreMetadata();
+            for (StoreMetadata storeMetadata : stores) {
+                rc.put(storeMetadata.getName(), new JpaDataIndex(JpaDataIndexManager.this, storeMetadata));
+            }
+            return rc;
+        }
+    };
+
+    // /////////////////////////////////////////////////////////////////
+    // Delegate methods to indexManager
+    // /////////////////////////////////////////////////////////////////
+
+    public DataIndex addStore(String name) throws Exception {
+        return indexManager.addStore(name);
+    }
+
+    public DataIndex getStore(String name) throws Exception {
+        return indexManager.getStore(name);
+    }
+
+    public List<DataIndex> getStores() throws Exception {
+        return indexManager.getStores();
+    }
+
+    public void removeStore(DataIndex store) throws Exception {
+        indexManager.removeStore(store);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // DataIndexManager interface
+    // /////////////////////////////////////////////////////////////////
+    public void clear() {
+    }
+
+    public void sync() throws Exception {
+    }
+
+    public void start() throws Exception {
+
+        lastIndexRecordRowId.set(executeUnTransacted(new EntityManagerAction<Long>() {
+            public Long execute(EntityManager em) {
+                Query query = em.createQuery("SELECT max(r.rowId) FROM IndexRecord r");
+                Long rc = (Long) query.getSingleResult();
+                if (rc == null) {
+                    rc = new Long(0);
+                }
+                return rc;
+            }
+        }));
+
+        lastReferenceRecordRowId.set(executeUnTransacted(new EntityManagerAction<Long>() {
+            public Long execute(EntityManager em) {
+                Query query = em.createQuery("SELECT max(r.rowId) FROM ReferenceRecord r");
+                Long rc = (Long) query.getSingleResult();
+                if (rc == null) {
+                    rc = new Long(0);
+                }
+                return rc;
+            }
+        }));
+
+    }
+
+    public void stop() throws Exception {
+        // TODO Auto-generated method stub
+
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Field Accessors
+    // /////////////////////////////////////////////////////////////////
+    public String getEntityManagerName() {
+        return entityManagerName;
+    }
+
+    public void setEntityManagerName(String entityManagerName) {
+        this.entityManagerName = entityManagerName;
+    }
+
+    public Properties getEntityManagerProperties() {
+        return entityManagerProperties;
+    }
+
+    public void setEntityManagerProperties(Properties entityManagerProperties) {
+        this.entityManagerProperties = entityManagerProperties;
+    }
+
+    public EntityManagerFactory getEntityManagerFactory() {
+        if (entityManagerFactory == null) {
+            entityManagerFactory = createEntityManagerFactory();
+        }
+        return entityManagerFactory;
+    }
+
+    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
+        this.entityManagerFactory = entityManagerFactory;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Implementation Methods
+    // /////////////////////////////////////////////////////////////////
+
+    protected EntityManagerFactory createEntityManagerFactory() {
+        return Persistence.createEntityManagerFactory(getEntityManagerName(), getEntityManagerProperties());
+    }
+
+    protected StoreMetadata createStoreMetadata(String name) throws Exception {
+        return createStoreMetadata(null, name);
+    }
+
+    public interface EntityManagerAction<T> {
+        T execute(EntityManager em) throws Exception;
+    }
+
+    public <T> T executeTransacted(EntityManagerAction<T> closure) throws Exception {
+        T rc;
+        EntityManager em = getEntityManagerFactory().createEntityManager();
+        try {
+            em.getTransaction().begin();
+            rc = closure.execute(em);
+            em.getTransaction().commit();
+        } finally {
+            if (em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            em.close();
+        }
+        return rc;
+    }
+
+    public <T> T executeUnTransacted(EntityManagerAction<T> closure) throws Exception {
+        T rc;
+        EntityManager em = getEntityManagerFactory().createEntityManager();
+        try {
+            rc = closure.execute(em);
+        } finally {
+            em.close();
+        }
+        return rc;
+    }
+
+    public StoreMetadata createStoreMetadata(Long parent, String name) throws Exception {
+        final StoreMetadata rc = new StoreMetadata();
+        rc.setName(name);
+        rc.setParent(parent);
+
+        return executeTransacted(new EntityManagerAction<StoreMetadata>() {
+            public StoreMetadata execute(EntityManager em) {
+                em.persist(rc);
+                return rc;
+            }
+        });
+    }
+
+    public List<StoreMetadata> listStoreMetadata() throws Exception {
+        return listStoreMetadata(null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<StoreMetadata> listStoreMetadata(final Long parent) throws Exception {
+        return executeUnTransacted(new EntityManagerAction<List<StoreMetadata>>() {
+            public List<StoreMetadata> execute(EntityManager em) {
+                Query query;
+                if (parent == null) {
+                    query = em.createQuery("SELECT m FROM StoreMetadata m WHERE m.parent IS NULL");
+                } else {
+                    query = em.createQuery("SELECT m FROM StoreMetadata m WHERE m.parent=?1");
+                    query.setParameter(1, parent);
+                }
+                return query.getResultList();
+            }
+        });
+    }
+
+    public AtomicLong getLastIndexRecordRowId() {
+        return lastIndexRecordRowId;
+    }
+
+    public AtomicLong getLastReferenceRecordRowId() {
+        return lastReferenceRecordRowId;
+    }
+
+    public Location getLastAddLocation() throws Exception {
+        return executeUnTransacted(new EntityManagerAction<Location>() {
+            @SuppressWarnings("unchecked")
+            public Location execute(EntityManager em) {
+                Query query = em.createQuery("SELECT r FROM IndexRecord r ORDER BY r.rowId DESC");
+                query.setMaxResults(1);
+                List<IndexRecord> rc = query.getResultList();
+                if (rc.isEmpty()) {
+                    return null;
+                }
+                return rc.get(0).getLocation();
+            }
+        });
+    }
+
+    public Set<Integer> getDataFileIdsInUse() throws Exception {
+        return executeUnTransacted(new EntityManagerAction<Set<Integer>>() {
+            @SuppressWarnings("unchecked")
+            public Set<Integer> execute(EntityManager em) {
+                Query query = em.createQuery("SELECT DISTINCT r.dataFileId FROM IndexRecord r");
+                List<Integer> rs = query.getResultList();
+                return new HashSet<Integer>(rs);
+            }
+        });
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndex.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndex.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndex.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndex.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,124 @@
+/**
+ * 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.router.index.jpa;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.router.index.api.Index;
+import org.apache.activemq.broker.router.index.jpa.JpaDataIndexManager.EntityManagerAction;
+import org.apache.activemq.broker.router.index.jpa.model.StoreMetadata;
+
+/**
+ * 
+ * @author chirino
+ */
+abstract public class JpaIndex implements Index {
+
+    private static final String ISO_8859_1 = "ISO-8859-1";
+    protected final JpaDataIndexManager manager;
+    protected StoreMetadata storeMetadata;
+
+    // /////////////////////////////////////////////////////////////////
+    // Index Accessors
+    // /////////////////////////////////////////////////////////////////
+
+    public JpaIndex(JpaDataIndexManager manager, StoreMetadata storeMetadata) {
+        this.manager = manager;
+        this.storeMetadata = storeMetadata;
+    }
+
+    public String getName() {
+        return storeMetadata.getName();
+    }
+
+    public void setProperties(Map<String, String> properties) throws Exception {
+        final String value = toString(properties);
+        storeMetadata = executeTransacted(new EntityManagerAction<StoreMetadata>() {
+            public StoreMetadata execute(EntityManager em) {
+                StoreMetadata rc = em.find(StoreMetadata.class, storeMetadata.getId());
+                rc.setProperties(value);
+                return rc;
+            }
+        });
+    }
+
+    public Map<String, String> getProperties() throws Exception {
+        return toMap(storeMetadata.getProperties());
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Field Accessors
+    // /////////////////////////////////////////////////////////////////
+    public StoreMetadata getStoreMetadata() {
+        return storeMetadata;
+    }
+
+    public JpaDataIndexManager getJpaDataIndexManager() {
+        return manager;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Implementation Methods
+    // /////////////////////////////////////////////////////////////////
+    public <T> T executeTransacted(EntityManagerAction<T> closure) throws Exception {
+        return manager.executeTransacted(closure);
+    }
+
+    public <T> T executeUnTransacted(EntityManagerAction<T> closure) throws Exception {
+        return manager.executeUnTransacted(closure);
+    }
+
+    public void remove(EntityManager em) throws Exception {
+        Query query = em.createQuery("DELETE FROM StoreMetadata m WHERE m.id=?1");
+        query.setParameter(1, storeMetadata.getId());
+        query.executeUpdate();
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, String> toMap(String properties) throws IOException {
+        if (properties == null)
+            return null;
+        HashMap<String, String> rc = new HashMap<String, String>();
+        ByteArrayInputStream bais = new ByteArrayInputStream(properties.getBytes(ISO_8859_1));
+        Properties p = new Properties();
+        p.load(bais);
+        rc.putAll((Map) p);
+        return rc;
+    }
+
+    private String toString(Map<String, String> properties) throws IOException {
+        if (properties == null) {
+            return null;
+        }
+
+        Properties p = new Properties();
+        p.putAll(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        p.store(baos, "");
+        baos.close();
+        return baos.toString(ISO_8859_1);
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndexManager.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndexManager.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndexManager.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaIndexManager.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,76 @@
+/**
+ * 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.router.index.jpa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.activemq.broker.router.index.api.Index;
+import org.apache.activemq.broker.router.index.api.IndexManager;
+
+/**
+ * 
+ * @author chirino
+ */
+abstract public class JpaIndexManager<T extends Index> implements IndexManager<T> {
+
+    private HashMap<String, T> stores;
+
+    synchronized public T addStore(String name) throws Exception {
+        if (stores == null) {
+            stores = createExistingStores();
+        }
+        T rc = stores.get(name);
+        if (rc == null) {
+            rc = createStore(name);
+            stores.put(name, rc);
+        }
+        return rc;
+    }
+
+    synchronized public T getStore(String name) throws Exception {
+        if (stores == null) {
+            stores = createExistingStores();
+        }
+        return stores.get(name);
+    }
+
+    synchronized public List<T> getStores() throws Exception {
+        if (stores == null) {
+            stores = createExistingStores();
+        }
+        ArrayList<T> rc = new ArrayList<T>();
+        rc.addAll(stores.values());
+        return rc;
+    }
+
+    synchronized public void removeStore(T store) throws Exception {
+        if (stores == null) {
+            stores = createExistingStores();
+        }
+        stores.remove(store.getName());
+        destroyStore(store);
+    }
+
+    abstract protected HashMap<String, T> createExistingStores() throws Exception;
+
+    abstract protected T createStore(String name) throws Exception;
+
+    abstract protected void destroyStore(T store) throws Exception;
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaReferenceIndex.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaReferenceIndex.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaReferenceIndex.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/JpaReferenceIndex.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,220 @@
+/**
+ * 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.router.index.jpa;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.activemq.broker.router.index.api.IndexEntry;
+import org.apache.activemq.broker.router.index.api.ReferenceIndex;
+import org.apache.activemq.broker.router.index.jpa.JpaDataIndexManager.EntityManagerAction;
+import org.apache.activemq.broker.router.index.jpa.model.IndexRecord;
+import org.apache.activemq.broker.router.index.jpa.model.Record;
+import org.apache.activemq.broker.router.index.jpa.model.ReferenceRecord;
+import org.apache.activemq.broker.router.index.jpa.model.StoreMetadata;
+
+/**
+ * 
+ * @author chirino
+ */
+public class JpaReferenceIndex extends JpaIndex implements ReferenceIndex {
+
+    private JpaDataIndex dataIndex;
+
+    public JpaReferenceIndex(JpaDataIndex dataIndex, StoreMetadata storeMetadata) {
+        super(dataIndex.getJpaDataIndexManager(), storeMetadata);
+        this.dataIndex = dataIndex;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Interface to ReferenceIndex
+    // /////////////////////////////////////////////////////////////////
+
+    public void addReference(IndexEntry ie) throws Exception {
+        final IndexRecord ir = (IndexRecord) ie;
+        final ReferenceRecord rr = new ReferenceRecord();
+        rr.setRowId(getNextRowId());
+        rr.setStore(storeMetadata.getId());
+        executeTransacted(new EntityManagerAction<Object>() {
+            public Object execute(EntityManager em) {
+                rr.setRecord(em.find(IndexRecord.class, ir.getRowId()));
+                em.persist(rr);
+                return null;
+            }
+        });
+    }
+
+    private long getNextRowId() {
+        return this.manager.getLastReferenceRecordRowId().incrementAndGet();
+    }
+
+    public IndexEntry getLastAddedId() throws Exception {
+        return executeUnTransacted(new EntityManagerAction<IndexEntry>() {
+            @SuppressWarnings("unchecked")
+            public IndexEntry execute(EntityManager em) {
+                Query query = em.createQuery("SELECT r FROM ReferenceRecord r WHERE r.store=?1 ORDER BY r.rowId DESC");
+                query.setParameter(1, storeMetadata.getId());
+                List<ReferenceRecord> rc = query.getResultList();
+                if (rc.isEmpty()) {
+                    return null;
+                }
+                ReferenceRecord rr = rc.get(0);
+                rr.setIndex(dataIndex);
+                return rr;
+            }
+        });
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<IndexEntry> load(IndexEntry firstIE, IndexEntry lastIE, final int max) throws Exception {
+
+        final ReferenceRecord first = (ReferenceRecord) firstIE;
+        final ReferenceRecord last = (ReferenceRecord) lastIE;
+
+        return executeUnTransacted(new EntityManagerAction<List<IndexEntry>>() {
+
+            public List<IndexEntry> execute(EntityManager em) {
+
+                ArrayList<IndexEntry> rc = new ArrayList<IndexEntry>(max);
+
+                Query query = createSelectRecordsBetween(em, "SELECT r FROM ReferenceRecord r WHERE ", storeMetadata.getId(), first, last);
+                query.setMaxResults(max);
+
+                List<ReferenceRecord> rs = query.getResultList();
+                for (ReferenceRecord rr : rs) {
+                    if (rc.size() >= max) {
+                        break;
+                    }
+
+                    rr.setIndex(dataIndex);
+                    rc.add(rr);
+                }
+                return rc;
+
+            }
+        });
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<IndexEntry> remove(IndexEntry firstIE, IndexEntry lastIE, final int max) throws Exception {
+        final ArrayList<IndexEntry> rc = new ArrayList<IndexEntry>();
+        while (rc.size() < max) {
+            final List<IndexEntry> l = load(firstIE, lastIE, max);
+            int skipped = executeTransacted(new EntityManagerAction<Integer>() {
+                public Integer execute(EntityManager em) {
+                    int skipped = 0;
+                    for (IndexEntry ie : l) {
+                        ReferenceRecord rr = (ReferenceRecord) ie;
+                        if (rc.size() >= max) {
+                            return skipped;
+                        }
+
+                        Query query = em.createQuery("DELETE FROM ReferenceRecord m WHERE m.rowId=?1");
+                        query.setParameter(1, rr.getRowId());
+                        if (query.executeUpdate() != 1) {
+                            skipped++;
+                        }
+                    }
+                    return skipped;
+                }
+            });
+
+            if (rc.size() >= max || skipped == 0) {
+                return rc;
+            }
+        }
+
+        return rc;
+    }
+
+    public void redoRemove(final long id) throws Exception {
+        executeTransacted(new EntityManagerAction<Object>() {
+            public Object execute(EntityManager em) {
+
+                Query query = em.createQuery("DELETE FROM ReferenceRecord m WHERE m.record.id=?1 AND m.store=?2");
+                query.setParameter(1, id);
+                query.setParameter(2, storeMetadata.getId());
+                query.executeUpdate();
+
+                return null;
+            }
+        });
+    }
+
+    public boolean remove(final long id) throws Exception {
+        return executeTransacted(new EntityManagerAction<Boolean>() {
+            public Boolean execute(EntityManager em) {
+
+                Query query = em.createQuery("DELETE FROM ReferenceRecord m WHERE m.record.id=?1 AND m.store=?2");
+                query.setParameter(1, id);
+                query.setParameter(2, storeMetadata.getId());
+                return query.executeUpdate() > 0;
+
+            }
+        });
+    }
+
+    public long size() throws Exception {
+        return executeTransacted(new EntityManagerAction<Long>() {
+            public Long execute(EntityManager em) {
+                Query query = em.createQuery("SELECT count(r) FROM ReferenceRecord r WHERE r.store=?1");
+                query.setParameter(1, storeMetadata.getId());
+                return (Long) query.getSingleResult();
+            }
+        });
+    }
+
+    @Override
+    public void remove(EntityManager em) throws Exception {
+        Query query = em.createQuery("DELETE FROM ReferenceRecord r WHERE r.store=?1");
+        query.setParameter(1, storeMetadata.getId());
+        query.executeUpdate();
+
+        super.remove(em);
+    }
+
+    static public Query createSelectRecordsBetween(EntityManager em, String select, long store, Record first, Record last) {
+        Query query;
+        String q = select + " r.store=?1";
+        int c = 2;
+        if (first != null) {
+            q += " AND ?" + c + " < r.rowId";
+            c++;
+        }
+        if (last != null) {
+            q += " AND r.rowId <= ?" + c;
+        }
+        q += " ORDER BY r.rowId";
+
+        query = em.createQuery(q);
+        query.setParameter(1, store);
+        c = 2;
+        if (first != null) {
+            query.setParameter(c, first.getRowId());
+            c++;
+        }
+        if (last != null) {
+            query.setParameter(c, last.getRowId());
+        }
+        return query;
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/IndexRecord.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/IndexRecord.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/IndexRecord.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/IndexRecord.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.broker.router.index.jpa.model;
+
+import java.util.Collection;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.apache.activemq.broker.router.index.api.DataIndex;
+import org.apache.activemq.kaha.impl.async.Location;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+/**
+ * 
+ * @author chirino
+ */
+@Entity()
+@Table(name = "INDEX_RECORDS")
+public class IndexRecord implements Record {
+
+    @Id
+    private long rowId;
+
+    @Index(enabled = true, unique = false)
+    @Basic(optional = false)
+    private long store;
+    @Index(enabled = true, unique = false)
+    @Basic(optional = false)
+    private long id;
+
+    @Basic(optional = false)
+    private int dataFileId;
+    @Basic(optional = false)
+    private int offset;
+
+    @OneToMany(mappedBy = "record", cascade = {})
+    private Collection<ReferenceRecord> references;
+
+    transient private DataIndex index;
+    transient private Location location;
+
+    public IndexRecord() {
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public long getStore() {
+        return store;
+    }
+
+    public void setStore(long store) {
+        this.store = store;
+    }
+
+    public int getOffset() {
+        return offset;
+    }
+
+    public void setOffset(int offset) {
+        this.offset = offset;
+    }
+
+    public Location getLocation() {
+        if (location == null) {
+            location = new Location();
+            location.setDataFileId(dataFileId);
+            location.setOffset(offset);
+        }
+        return location;
+    }
+
+    public void setLocation(Location location) {
+        this.location = location;
+        this.offset = location.getOffset();
+        this.dataFileId = location.getDataFileId();
+    }
+
+    public void setIndex(DataIndex index) {
+        this.index = index;
+    }
+
+    public DataIndex getIndex() {
+        return index;
+    }
+
+    public int getDataFileId() {
+        return dataFileId;
+    }
+
+    public void setDataFileId(int dataFileId) {
+        this.dataFileId = dataFileId;
+    }
+
+    public long getRowId() {
+        return rowId;
+    }
+
+    public void setRowId(long rowId) {
+        this.rowId = rowId;
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/Record.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/Record.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/Record.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/Record.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,29 @@
+/**
+ * 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.router.index.jpa.model;
+
+import org.apache.activemq.broker.router.index.api.IndexEntry;
+
+/**
+ * 
+ * @author chirino
+ */
+public interface Record extends IndexEntry {
+
+    public long getRowId();
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/ReferenceRecord.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/ReferenceRecord.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/ReferenceRecord.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/ReferenceRecord.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.broker.router.index.jpa.model;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import org.apache.activemq.broker.router.index.api.DataIndex;
+import org.apache.activemq.kaha.impl.async.Location;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+/**
+ * 
+ * @author chirino
+ */
+@Entity()
+@Table(name = "REFERENCE_RECORDS")
+public class ReferenceRecord implements Record {
+
+    @Id
+    private long rowId;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = false, cascade = {})
+    private IndexRecord record;
+
+    private long store;
+    @Index(enabled = true, unique = false)
+    transient private DataIndex index;
+    transient private long id;
+    transient private Location location;
+
+    public long getRowId() {
+        return rowId;
+    }
+
+    public void setRowId(long rowId) {
+        this.rowId = rowId;
+    }
+
+    public void setIndex(DataIndex index) {
+        this.index = index;
+        if (record != null) {
+            id = record.getId();
+            location = record.getLocation();
+        }
+    }
+
+    public DataIndex getIndex() {
+        return index;
+    }
+
+    public IndexRecord getRecord() {
+        return record;
+    }
+
+    public void setRecord(IndexRecord record) {
+        this.record = record;
+    }
+
+    public long getStore() {
+        return store;
+    }
+
+    public void setStore(long store) {
+        this.store = store;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public Location getLocation() {
+        return location;
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/StoreMetadata.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/StoreMetadata.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/StoreMetadata.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/StoreMetadata.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,101 @@
+/**
+ * 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.router.index.jpa.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.jdbc.Index;
+
+/**
+ * 
+ * @author chirino
+ */
+@Entity()
+// @SequenceGenerator(name="metadata-seq", sequenceName="METADATA_SEQ")
+@Table(name = "STORE_METADATA")
+public class StoreMetadata {
+
+    @Id
+    @GeneratedValue
+    // @GeneratedValue(strategy=GenerationType.SEQUENCE,
+    // generator="metadata-seq")
+    private long id;
+
+    @Basic(optional = false)
+    @Index(enabled = true, unique = false)
+    private String name;
+
+    @Basic(optional = true)
+    private Long parent;
+
+    @Basic(optional = true)
+    @Lob
+    private String properties;
+
+    // @Basic(optional = false)
+    // @Index(enabled = true, unique = false)
+    // private String destination;
+    //
+    // @Basic
+    // private long exiration;
+    //
+    // @Basic
+    // @Lob
+    // private byte[] data;
+
+    public StoreMetadata() {
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Long getParent() {
+        return parent;
+    }
+
+    public void setParent(Long parent) {
+        this.parent = parent;
+    }
+
+    public void setProperties(String properties) {
+        this.properties = properties;
+
+    }
+
+    public String getProperties() {
+        return properties;
+    }
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/package.html
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/package.html?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/package.html (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/model/package.html Tue Mar  4 13:01:41 2008
@@ -0,0 +1,25 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+The JPA entities used by the JPA Index implementation.
+
+</body>
+</html>

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/package.html
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/package.html?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/package.html (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/index/jpa/package.html Tue Mar  4 13:01:41 2008
@@ -0,0 +1,25 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+A JPA implementation of the org.apache.activemq.broker.router.index.api package.
+
+</body>
+</html>

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/CacheEntry.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/CacheEntry.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/CacheEntry.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/CacheEntry.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,63 @@
+/**
+ * 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.router.store.api;
+
+import org.apache.activemq.command.Message;
+
+/**
+ * A cache entry is used to reference count the number of user interested in a
+ * message. A data store's cache will keep entries that in use in memory and
+ * move those that are not in use out of memory.
+ * 
+ * @author chirino
+ */
+public interface CacheEntry {
+
+    /**
+     * The key to the message in the DataStore.
+     * 
+     * @return
+     */
+    public long getId();
+
+    /**
+     * Gives you the message. Should only be called while the cache entry is
+     * 'loaded'
+     * 
+     * @return
+     */
+    public Message getMessage();
+
+    /**
+     * Lets the cache know that you will be using this entry. This method can be
+     * called multiple times. For the entry to not be considered in use, it
+     * should call unload() the same number of times.
+     */
+    public void load();
+
+    /**
+     * Lets the cache know that you will NOT be using this entry.
+     */
+    public void unload();
+
+    public void incrementRedeliveryCounter();
+
+    public DataStore getStore();
+
+    public boolean lock();
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStore.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStore.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStore.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStore.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,112 @@
+/**
+ * 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.router.store.api;
+
+import org.apache.activemq.broker.router.api.Destination;
+import org.apache.activemq.broker.router.store.api.DataStoreManager.TransactionAction;
+import org.apache.activemq.command.Message;
+import org.apache.activemq.command.TransactionId;
+
+/**
+ * The DataStore interface is what is used to store messages in the system. It
+ * also allows you to create child ReferenceStore objects which are ideal for
+ * storing client subscriptions.
+ * 
+ * @author chirino
+ */
+public interface DataStore extends Store, StoreManager<ReferenceStore> {
+
+    /**
+     * Adds a record to the store.
+     * 
+     * @param id
+     * 
+     * @param id
+     * @param record
+     * @param tx
+     * @param onCompleted
+     * @throws Exception
+     */
+    public CacheEntry addMessage(long id, Message record, Runnable onCompleted) throws Exception;
+
+    public interface AddMessageTransactionAction extends TransactionAction {
+        Message getMessage();
+
+        CacheEntry complete() throws Exception;
+    }
+
+    /**
+     * When messages are transacted, adding data needs to be done in 2 parts.
+     * First we need to store the record, and if the transaction commits then we
+     * need to add it to the container. This method does the first part.
+     * 
+     * @param record
+     * @param tx
+     * @param onCompleted
+     * @return a locator object that is used later to complete the transactions.
+     * @throws Exception
+     */
+    public AddMessageTransactionAction addTransactedMessage(long id, Message record, TransactionId tx, Runnable onCompleted) throws Exception;
+
+    /**
+     * Removes any records from the store that do not have any references from
+     * child reference stores. Used to delete items that do not exist in
+     * subscriptions.
+     * 
+     * Since message are first added to the data store and then references are
+     * created, it would be possible to delete a record that has no references
+     * but would have been referenced. Therefore you should specify a maxId
+     * which is that highest record that will be deleted.
+     * 
+     * @param until
+     * @throws Exception
+     */
+    public void removeUnreferencedRecords(CacheEntry until) throws Exception;
+
+    public interface RemoveMesageTransactionAction extends TransactionAction {
+        long getId();
+
+        void complete() throws Exception;
+    }
+
+    /**
+     * Removes the 'id' record from the store. In a transaction 1st phase.
+     * 
+     * @param id
+     *            The identifier of the record.
+     * @param tx
+     *            The transaction that this operation will participate in. May
+     *            be null if part of a trasaction.
+     * @param onCompleted
+     *            if not null then the Runnable should be called once we can
+     *            guarantee this action will not be lost.
+     * @throws Exception
+     */
+    public RemoveMesageTransactionAction removeTransacted(long id, TransactionId tx, Runnable onCompleted) throws Exception;
+
+    public Destination getDestination();
+
+    public void setDestination(Destination destination);
+
+    /**
+     * Can the store auto remove messages that have no references and that are
+     * not loaded.
+     * 
+     * @param enable
+     */
+    public void setAutoRemove(boolean enable);
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStoreManager.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStoreManager.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStoreManager.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/DataStoreManager.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.broker.router.store.api;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.activemq.Service;
+import org.apache.activemq.command.TransactionId;
+import org.apache.activemq.command.TransactionInfo;
+
+/**
+ * This if the root object of a persistence System in ActiveMQ. It has a life
+ * cycle and allows you to create DataStore objects for messaging destinations.
+ * The DataStores hold messages in a sequenced list.
+ * 
+ * It also provides the interface storing the state of the transaction operating
+ * against the broker.
+ * 
+ * @author chirino
+ * 
+ */
+public interface DataStoreManager extends StoreManager<DataStore>, Service {
+
+    public interface TransactionAction {
+        TransactionId getTransactionId();
+
+        DataStore getDataStore();
+    }
+
+    /**
+     * Store that a transaction control operation occurred.
+     * 
+     * @param txOperation
+     * @throws Exception
+     */
+    public void record(TransactionInfo txOperation, Runnable onComplete) throws Exception;
+
+    /**
+     * 
+     * @return
+     */
+    public Map<TransactionId, List<TransactionAction>> recoverPendingTransactions() throws Exception;
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/ReferenceStore.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/ReferenceStore.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/ReferenceStore.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/ReferenceStore.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,63 @@
+/**
+ * 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.router.store.api;
+
+import java.util.List;
+
+import org.apache.activemq.broker.router.store.api.DataStoreManager.TransactionAction;
+import org.apache.activemq.command.TransactionId;
+
+/**
+ * 
+ * @author chirino
+ */
+public interface ReferenceStore extends Store {
+
+    /**
+     * Adds a reference record to this store.
+     * 
+     * @param id
+     * @throws Exception
+     */
+    public void addReference(CacheEntry id) throws Exception;
+
+    public interface RemoveReferenceTransactionAction extends TransactionAction {
+        ReferenceStore getReferenceStore();
+
+        long getId();
+
+        void complete() throws Exception;
+    }
+
+    /**
+     * Removes the 'id' record from the store. In a transaction 1st phase.
+     * 
+     * @param id
+     *            The identifier of the record.
+     * @param tx
+     *            The transaction that this operation will participate in. May
+     *            be null if part of a trasaction.
+     * @param onCompleted
+     *            if not null then the Runnable should be called once we can
+     *            guarantee this action will not be lost.
+     * @throws Exception
+     */
+    public RemoveReferenceTransactionAction removeReferenceTransacted(long id, TransactionId tx, Runnable onCompleted) throws Exception;
+
+    public List<CacheEntry> remove(CacheEntry first, CacheEntry last, int max) throws Exception;
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/Store.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/Store.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/Store.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/Store.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,113 @@
+/**
+ * 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.router.store.api;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A store allows you store, load, and delete sequenced data in persistent
+ * storage. There are two variations of this interface. (1) DataStore allows you
+ * to store any data and (2) ReferenceStore allows you to store references to
+ * entries in the DataStore.
+ * 
+ * @author chirino
+ */
+public interface Store {
+
+    /**
+     * The name of the store.
+     * 
+     * @return
+     */
+    public String getName();
+
+    /**
+     * Allows you to associate some properties with the store.
+     * 
+     * Potential Uses:
+     * <li> If the store is holding message data this could get used persist
+     * destination configuration/settings.
+     * <li> If this is a ReferenceStore for a durable subscription, then it
+     * could get configured with subscription information, like the selector,
+     * client id, and subscription name.
+     * 
+     * @param metadata
+     * @throws Exception
+     */
+    public void setProperties(Map<String, String> properties) throws Exception;
+
+    /**
+     * The properties associated with this store.
+     * 
+     * @return and empty map if nothing was previously associated.
+     * @throws Exception
+     */
+    public Map<String, String> getProperties() throws Exception;
+
+    /**
+     * The number of records in the store.
+     * 
+     * @return
+     * @throws Exception
+     */
+    public long size() throws Exception;
+
+    /**
+     * This is used to know what was the last id that was added to store. This
+     * is used by users of the DataStore to initialize the record id sequence.
+     * Also used by users of the ReferenceStore to know where 'recovery' should
+     * continue at.
+     * 
+     * @return The record id of the last record added to the store or null if no
+     *         record had previously been added.
+     * @throws Exception
+     */
+    public CacheEntry getLastAddedEntry() throws Exception;
+
+    /**
+     * Removes the 'id' record from the store.
+     * 
+     * @param id
+     *            The identifier of the record.
+     * @param onCompleted
+     *            if not null then the Runnable should be called once we can
+     *            guarantee this action will not be lost.
+     * @throws Exception
+     */
+    public void remove(long id, Runnable onCompleted) throws Exception;
+
+    /**
+     * Loads data items from the Store. The returned list will be at most 'max'
+     * record big but may be smaller.
+     * 
+     * The records returned will be records with id's greater than the 'first'
+     * id and and less than or equal to the 'last' id specified. The records
+     * will be assending order in the list.
+     * 
+     * If 'first' is null then start with the smallest record id in the store.
+     * If 'last" is null then stop at the largest record id in the store.
+     * 
+     * @param first
+     * @param last
+     * @param max
+     * @return
+     * @throws Exception
+     */
+    public List<CacheEntry> load(CacheEntry first, CacheEntry last, int max) throws Exception;
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/StoreManager.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/StoreManager.java?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/StoreManager.java (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/StoreManager.java Tue Mar  4 13:01:41 2008
@@ -0,0 +1,36 @@
+/**
+ * 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.router.store.api;
+
+import java.util.List;
+
+/**
+ * The StoreManager allows you to add/find/delete Stores in the system.
+ * 
+ * @author chirino
+ */
+public interface StoreManager<T extends Store> {
+
+    public T addStore(String name) throws Exception;
+
+    public List<T> getStores() throws Exception;
+
+    public T getStore(String name) throws Exception;
+
+    public void removeStore(T store) throws Exception;
+
+}

Added: activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/package.html
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/package.html?rev=633639&view=auto
==============================================================================
--- activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/package.html (added)
+++ activemq/sandbox/activemq-router/src/main/java/org/apache/activemq/broker/router/store/api/package.html Tue Mar  4 13:01:41 2008
@@ -0,0 +1,27 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+Defines the interfaces to the Store API that is used by the Router to hold in transit messages.  There are 
+persistent and non-persistent store implementations.  The stores API is designed so that the Store is responsible
+for caching messages in memory.
+
+</body>
+</html>



Mime
View raw message