Code cleanup and commenting
diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
index ab434b1..cdf9133 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2011 Oracle. All rights reserved.

+ * Copyright (c) 2011, 2012 Oracle. All rights reserved.

  * This program and the accompanying materials are made available under the 

  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 

  * which accompanies this distribution. 

@@ -9,7 +9,6 @@
  *

  * Contributors:

  * 		dclarke/tware - initial 

- *      tware

  ******************************************************************************/

 package org.eclipse.persistence.jpa.rs;

 

@@ -54,41 +53,74 @@
 import org.eclipse.persistence.jpa.JpaHelper;

 import org.eclipse.persistence.jpa.PersistenceProvider;

 import org.eclipse.persistence.jpa.dynamic.JPADynamicHelper;

+import org.eclipse.persistence.jpa.rs.eventlistener.ChangeListener;

 import org.eclipse.persistence.jpa.rs.eventlistener.DatabaseEventListenerFactory;

 import org.eclipse.persistence.jpa.rs.eventlistener.DescriptorBasedDatabaseEventListener;

-import org.eclipse.persistence.jpa.rs.util.DatabaseListener;

 import org.eclipse.persistence.jpa.rs.util.DynamicXMLMetadataSource;

+import org.eclipse.persistence.jpa.rs.util.LinkAdapter;

 import org.eclipse.persistence.platform.database.events.DatabaseEventListener;

 import org.eclipse.persistence.queries.DatabaseQuery;

 import org.eclipse.persistence.sessions.Session;

 import org.eclipse.persistence.sessions.server.Server;

 import org.eclipse.persistence.sessions.server.ServerSession;

 

-import org.eclipse.persistence.jpa.rs.util.ChangeListener;

 import org.eclipse.persistence.jpa.rs.PersistenceFactory;

 

 /**

- * A wrapper around the JPA and JAXB artifacts used to persist an application

+ * A wrapper around the JPA and JAXB artifacts used to persist an application.

+ * 

+ * A PersistenceContext provides the capability of using the same persistence unit in JPA to

+ * to interact with a Database or other JPA-capable data source and in JAXB to interact with either 

+ * XML or JSON.

+ * 

+ * A PersistenceContext can wrap either an existing persistence unit (EntityManagerFactory), or it can be used to bootstrap a 

+ * fully dynamic persistence unit.

  * 

  * @author douglas.clarke, tom.ware

  */

 public class PersistenceContext {

     

-    private static final String PACKAGE_ROOT = "jpars.app.";

-    private static final String MODEL_PACKAGE = ".model";   

+    /** A factory class that will provide listeners for events provided by the database

+     *  Setting this provides a hook to allow applications that are capable of receiving

+     *  events from the database to do so.

+     */

     public static DatabaseEventListenerFactory EVENT_LISTENER_FACTORY = null;

     

+    /** This internal property is used to save a change listener on the session for later retreival.**/

+    public static final String CHANGE_NOTIFICATION_LISTENER = "jpars.change-notification-listener";

+

+

+    /**

+     * Static setter for the EVENT_LISTENER_FACTORY

+     * Part of the mechanism for plugging in code that can react to database events

+     * @param eventListenerFactory

+     */

+    public static void setEventListenerFactory(

+            DatabaseEventListenerFactory eventListenerFactory) {

+        EVENT_LISTENER_FACTORY = eventListenerFactory;

+    }

+    

+    /**

+     * The name of the persistence context is used to look it up. By default it will be the

+     * persistence unit name of the JPA persistence unit.

+     */

     private String name = null;

     

+    /** The EntityManagerFactory used to interact using JPA **/

     private EntityManagerFactory emf;

     

+    /** The JAXBConext used to produce JSON or XML **/

     private JAXBContext context = null;

     

+    /** The URI of the Persistence context.  This is used to build Links in JSON and XML **/

     private URI baseURI = null;

     

+    /** 

+     * An application provided listener that can be used if the application has a framework

+     * to listen to database events.

+     */

     private DescriptorBasedDatabaseEventListener databaseEventListener = null;

 

-

     public PersistenceContext(Archive archive, Map<String, Object> properties, ClassLoader classLoader){

         super();

         List<SEPersistenceUnitInfo> persistenceUnits = PersistenceUnitProcessor.getPersistenceUnits(archive, classLoader);

@@ -99,7 +131,7 @@
         if (!persistenceUnitInfo.getProperties().containsKey(PersistenceUnitProperties.JDBC_DRIVER) && !properties.containsKey(PersistenceUnitProperties.JDBC_DRIVER)) {

             properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, "jdbc/jpa-rs");

         }

-        EntityManagerFactoryImpl emf = createDynamicEMF(persistenceUnitInfo, properties);

+        EntityManagerFactoryImpl emf = createEntityManagerFactory(persistenceUnitInfo, properties);

         this.emf = emf;

        

         try{

@@ -123,49 +155,18 @@
             throw new RuntimeException("JAXB Creation Exception", e);

         }

     }

-    

-    protected EntityManagerFactoryImpl createDynamicEMF(PersistenceUnitInfo info, Map<String, ?> properties){

-        PersistenceProvider provider = new PersistenceProvider();

-        EntityManagerFactory emf = provider.createContainerEntityManagerFactory(info, properties);

-        return (EntityManagerFactoryImpl)emf;

-    }

-    

+ 

     /**

+     * This method is used to help construct a JAXBContext from an existing EntityManagerFactory.

+     * 

+     * For each package in the EntityManagerFactory, a MetadataSource that is capable of building a JAXBContext

+     * that creates the same mappings in JAXB is created.  These MetadataSources are used to constuct the JAXContext

+     * that is used for JSON and XML translation

+     * @param metadataSources

+     * @param persistenceUnitName

      * @param session

-     * @return

      */

-    protected JAXBContext createDynamicJAXBContext(String persistenceUnitName, Server session) throws JAXBException, IOException {

-        JAXBContext jaxbContext = (JAXBContext) session.getProperty(JAXBContext.class.getName());

-        if (jaxbContext != null) {

-            return jaxbContext;

-        }

-        String packageName = PACKAGE_ROOT + persistenceUnitName + MODEL_PACKAGE;

-

-        Map<String, Object> properties = createJAXBProperties(persistenceUnitName, session, packageName);      

-

-        ClassLoader cl = session.getPlatform().getConversionManager().getLoader();

-        jaxbContext = DynamicJAXBContextFactory.createContextFromOXM(cl, properties);

-        

-        session.setProperty(JAXBContext.class.getName(), jaxbContext);

-

-        return jaxbContext;

-    }

-    

-    public Map<String, Object> createJAXBProperties(String persistenceUnitName, Server session, String dynamicPackageName) throws IOException{

-        String oxmLocation = (String) emf.getProperties().get("eclipselink.jpa-rs.oxm");

-        

-        Map<String, Object> properties = new HashMap<String, Object>(1);

-        List<Object> metadataLocations = new ArrayList<Object>();

-

-        addDynamicXMLMetadataSources(metadataLocations, persistenceUnitName, session);

-        if (oxmLocation != null){

-            metadataLocations.add(new org.eclipse.persistence.jaxb.metadata.XMLMetadataSource((new URL(oxmLocation)).openStream()));

-        }

-        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataLocations);

-        return properties;

-    }

-    

-    public void addDynamicXMLMetadataSources(List<Object> metadataSources, String persistenceUnitName, Server session){

+    protected void addDynamicXMLMetadataSources(List<Object> metadataSources, String persistenceUnitName, Server session){

         Set<String> packages = new HashSet<String>();

         Iterator<Class> i = session.getDescriptors().keySet().iterator();

         while (i.hasNext()){

@@ -184,29 +185,25 @@
         }

     }

     

-    public String getName() {

-        return name;

+    /**

+     * Add a listener that can react to DatabaseChange notifications

+     */

+    public void addListener(ChangeListener listener) {

+        DescriptorBasedDatabaseEventListener changeListener = (DescriptorBasedDatabaseEventListener) JpaHelper.getDatabaseSession(getEmf()).getProperty(CHANGE_NOTIFICATION_LISTENER);

+        if (changeListener == null) {

+            throw new RuntimeException("Change Listener not registered properly");

+        }

+        changeListener.addChangeListener(listener);

     }

-

-    public EntityManagerFactory getEmf() {

-        return emf;

-    }

-

-    public JAXBContext getJAXBContext() {

-        return context;

-    }

-

-    public URI getBaseURI() {

-        return baseURI;

-    }

-

-    public void setBaseURI(URI baseURI) {

-        this.baseURI = baseURI;

-    }

-

+    

+    /**

+     * A part of the facade over the JPA API

+     * Persist an entity in JPA and commit

+     * @param tenantId

+     * @param entity

+     */

     public void create(String tenantId, Object entity) {

         EntityManager em = getEmf().createEntityManager();

-

         try {

             em.getTransaction().begin();

             em.persist(entity);

@@ -215,8 +212,194 @@
             em.close();

         }

     }

+    

+    /**

+     * Create a JAXBConext based on the EntityManagerFactory for this PersistenceContext

+     * @param session

+     * @return

+     */

+    protected JAXBContext createDynamicJAXBContext(String persistenceUnitName, Server session) throws JAXBException, IOException {

+        JAXBContext jaxbContext = (JAXBContext) session.getProperty(JAXBContext.class.getName());

+        if (jaxbContext != null) {

+            return jaxbContext;

+        }

 

-    public Object merge(String type, String tenantId, Object entity) {

+        Map<String, Object> properties = createJAXBProperties(persistenceUnitName, session);      

+

+        ClassLoader cl = session.getPlatform().getConversionManager().getLoader();

+        jaxbContext = DynamicJAXBContextFactory.createContextFromOXM(cl, properties);

+        

+        session.setProperty(JAXBContext.class.getName(), jaxbContext);

+

+        return jaxbContext;

+    }

+    

+    /**

+     * A part of the facade over the JPA API

+     * Create an EntityManagerFactory using the given PersistenceUnitInfo and properties

+     * @param info

+     * @param properties

+     * @return

+     */

+    protected EntityManagerFactoryImpl createEntityManagerFactory(PersistenceUnitInfo info, Map<String, ?> properties){

+        PersistenceProvider provider = new PersistenceProvider();

+        EntityManagerFactory emf = provider.createContainerEntityManagerFactory(info, properties);

+        return (EntityManagerFactoryImpl)emf;

+    }

+    

+    /**

+     * A part of the facade over the JPA API

+     * Create an EntityManager from the EntityManagerFactory wrapped by this persistence context

+     * @param tenantId

+     * @return

+     */

+    protected EntityManager createEntityManager(String tenantId) {

+        return getEmf().createEntityManager();

+    }

+    

+    /**

+     * Build the set of properties used to create the JAXBContext based on the EntityManagerFactory that

+     * this PersistenceContext wraps

+     * @param persistenceUnitName

+     * @param session

+     * @return

+     * @throws IOException

+     */

+    protected Map<String, Object> createJAXBProperties(String persistenceUnitName, Server session) throws IOException{

+        String oxmLocation = (String) emf.getProperties().get("eclipselink.jpa-rs.oxm");

+        

+        Map<String, Object> properties = new HashMap<String, Object>(1);

+        List<Object> metadataLocations = new ArrayList<Object>();

+

+        addDynamicXMLMetadataSources(metadataLocations, persistenceUnitName, session);

+        if (oxmLocation != null){

+            metadataLocations.add(new org.eclipse.persistence.jaxb.metadata.XMLMetadataSource((new URL(oxmLocation)).openStream()));

+        }

+        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataLocations);

+        return properties;

+    }

+    

+    /**

+     *  A part of the facade over the JPA API

+     *  Delete the given entity in JPA and commit the changes

+     */

+    public void delete(String tenantId, String type, Object id) {

+        EntityManager em = getEmf().createEntityManager();

+

+        try {

+            em.getTransaction().begin();

+            Object entity = em.find(getClass(type), id);

+            em.remove(entity);

+            em.getTransaction().commit();

+        } finally {

+            em.close();

+        }

+    }

+    

+    /**

+     * A part of the facade over the JPA API

+     * Find an entity with the given name and id in JPA

+     * @param entityName

+     * @param id

+     * @return

+     */

+    public Object find(String entityName, Object id) {

+        return find(null, entityName, id);

+    }

+

+    /**

+     * A part of the facade over the JPA API

+     * Find an entity with the given name and id in JPA

+     * @param tenantId

+     * @param entityName

+     * @param id

+     * @return

+     */

+    public Object find(String tenantId, String entityName, Object id) {

+        return find(tenantId, entityName, id, null);

+    }

+    

+    /**

+     * A part of the facade over the JPA API

+     * Find an entity with the given name and id in JPA

+     * @param tenantId

+     * @param entityName

+     * @param id

+     * @param properties - query hints used on the find

+     * @return

+     */

+    public Object find(String tenantId, String entityName, Object id, Map<String, Object> properties) {

+        EntityManager em = getEmf().createEntityManager();

+

+        try {

+            return em.find(getClass(entityName), id, properties);

+        } finally {

+            em.close();

+        }

+    }

+

+    public URI getBaseURI() {

+        return baseURI;

+    }

+    

+    /**

+     * Look-up the given entity name in the EntityManagerFactory and return the class

+     * is describes

+     * @param entityName

+     * @return

+     */

+    public Class<?> getClass(String entityName) {

+        ClassDescriptor descriptor = getDescriptor(entityName);

+        if (descriptor == null){

+            return null;

+        }

+        return descriptor.getJavaClass();

+    }

+    

+    /**

+     * Lookup the descriptor for the given entity name.

+     * This method will look first in the EntityManagerFactory wrapped by this persistence context

+     * and return that descriptor.  If one does not exist, it search the JAXBContext and return

+     * a descriptor from there.

+     * @param entityName

+     * @return

+     */

+    public ClassDescriptor getDescriptor(String entityName){

+        Server session = JpaHelper.getServerSession(getEmf());

+        ClassDescriptor descriptor = session.getDescriptorForAlias(entityName);

+        if (descriptor == null){

+            for (Object ajaxBSession:((JAXBContext)getJAXBContext()).getXMLContext().getSessions() ){

+                descriptor = ((Session)ajaxBSession).getClassDescriptorForAlias(entityName);

+                if (descriptor != null){

+                    break;

+                }

+            }

+        }

+        return descriptor;

+    }

+    

+    public EntityManagerFactory getEmf() {

+        return emf;

+    }

+

+    public JAXBContext getJAXBContext() {

+        return context;

+    }

+    

+    public String getName() {

+        return name;

+    }

+    

+    /**

+     * A part of the facade over the JPA API

+     * Call jpa merge on the given object and commit

+     * If the passed object is a list, we will iterate through the

+     * list and merge each member

+     * @param tenantId

+     * @param entity

+     * @return

+     */

+    public Object merge(String tenantId, Object entity) {

         EntityManager em = getEmf().createEntityManager();

         Object mergedEntity = null;

         try {

@@ -236,23 +419,22 @@
             em.close();

         }

     }

-

-    public boolean isList(String type){

-        Server session = JpaHelper.getServerSession(getEmf());

-        ClassDescriptor descriptor = session.getDescriptorForAlias(type);

-        if (descriptor == null && getDescriptor(type) != null){

-            return true;

-        }

-        return false;

-    }

     

     /**

-     * TODO

+     * A convenience method to create a new dynamic entity of the given type

+     * @param type

+     * @return

      */

     public DynamicEntity newEntity(String type) {

         return newEntity(null, type);

     }

-

+    

+    /**

+     * A convenience method to create a new dynamic entity of the given type

+     * @param tenantId

+     * @param type

+     * @return

+     */

     public DynamicEntity newEntity(String tenantId, String type) {

         JPADynamicHelper helper = new JPADynamicHelper(getEmf());

         DynamicEntity entity = null;

@@ -270,91 +452,27 @@
         }

         return entity;

     }

-

-    /**

-     * TODO

-     */

-    public void save(String tenantId, Object entity) {

-        EntityManager em = getEmf().createEntityManager();

-

-        try {

-            em.getTransaction().begin();

-            em.merge(entity);

-            em.getTransaction().commit();

-        } finally {

-            em.close();

-        }

-    }

-

-    /**

-     * TODO

-     */

-    public void delete(String tenantId, String type, Object id) {

-        EntityManager em = getEmf().createEntityManager();

-

-        try {

-            em.getTransaction().begin();

-            Object entity = em.find(getClass(type), id);

-            em.remove(entity);

-            em.getTransaction().commit();

-        } finally {

-            em.close();

-        }

-    }

-

-    /**

-     * Stop the current application instance

-     */

-    protected void stop() {

-        emf.close();

-        this.emf = null;

-        this.context = null;

-    }

-

-    public Object find(String entityName, Object id) {

-        return find(null, entityName, id);

-    }

-

-    public Object find(String tenantId, String entityName, Object id) {

-        return find(tenantId, entityName, id, null);

-    }

     

-    public Object find(String tenantId, String entityName, Object id, Map<String, Object> properties) {

-        EntityManager em = getEmf().createEntityManager();

-

-        try {

-            return em.find(getClass(entityName), id, properties);

-        } finally {

-            em.close();

-        }

-    }

-

-    public String toString() {

-        return "Application(" + getName() + ")::" + System.identityHashCode(this);

-    }

-

-    public ClassDescriptor getDescriptor(String entityName){

-        Server session = JpaHelper.getServerSession(getEmf());

-        ClassDescriptor descriptor = session.getDescriptorForAlias(entityName);

-        if (descriptor == null){

-            for (Object ajaxBSession:((JAXBContext)getJAXBContext()).getXMLContext().getSessions() ){

-                descriptor = ((Session)ajaxBSession).getClassDescriptorForAlias(entityName);

-                if (descriptor != null){

-                    break;

-                }

-            }

-        }

-        return descriptor;

-    }

-    

-    public Class<?> getClass(String entityName) {

-        return getDescriptor(entityName).getJavaClass();

-    }

-

+    /**

+     * A part of the facade over the JPA API

+     * Run a query with the given name in JPA and return the result

+     * @param name

+     * @param parameters

+     * @return

+     */

     public Object query(String name, Map<?, ?> parameters) {

         return query(name, parameters, null, false);

     }

     

+    /**

+     * A part of the facade over the JPA API

+     * Run a query with the given name in JPA and return the result

+     * @param name

+     * @param parameters

+     * @param hints

+     * @param returnSingleResult

+     * @return

+     */

     @SuppressWarnings("rawtypes")

     public Object query(String name, Map<?, ?> parameters, Map<String, ?> hints, boolean returnSingleResult) {

         EntityManager em = getEmf().createEntityManager();

@@ -395,43 +513,36 @@
         return null;

     }

     

-    public Object unmarshalEntity(String entityName, String tenantId, String acceptedMedia, InputStream in) throws JAXBException {

-        Unmarshaller unmarshaller = getJAXBContext().createUnmarshaller();

-        if (acceptedMedia == null || acceptedMedia.indexOf(MediaType.APPLICATION_JSON) < 0) {

-            unmarshaller.setProperty(MEDIA_TYPE, MediaType.APPLICATION_JSON);

-            // TODO - handle type

-        } else {

-            unmarshaller.setProperty(MEDIA_TYPE, MediaType.APPLICATION_XML);

-        }

-        JAXBElement<?> element = unmarshaller.unmarshal(new StreamSource(in), getClass(entityName));

-		return element.getValue();

-    }

-

-    protected EntityManager createEntityManager(String tenantId) {

-        return getEmf().createEntityManager();

-    }

-    

     /**

-     * TODO

-     */

-    public void addListener(ChangeListener listener) {

-        DatabaseListener changeListener = (DatabaseListener) JpaHelper.getDatabaseSession(getEmf()).getProperty(PersistenceFactory.CHANGE_NOTIFICATION_LISTENER);

-        if (changeListener == null) {

-            throw new RuntimeException("Change Listener not registered properly");

-        }

-        changeListener.addChangeListener(listener);

-    }

-

-    /**

-     * TODO

+     * Remove a given change listener.  Used in interacting with an application-provided mechanism for listenig

+     * to database events.

+     * @param listener

      */

     public void remove(ChangeListener listener) {

-        DatabaseListener changeListener = (DatabaseListener) JpaHelper.getDatabaseSession(getEmf()).getProperty(PersistenceFactory.CHANGE_NOTIFICATION_LISTENER);

+        DescriptorBasedDatabaseEventListener changeListener = (DescriptorBasedDatabaseEventListener) JpaHelper.getDatabaseSession(getEmf()).getProperty(CHANGE_NOTIFICATION_LISTENER);

         if (changeListener != null) {

             changeListener.removeChangeListener(listener);

         }

     }

     

+    public void setBaseURI(URI baseURI) {

+        this.baseURI = baseURI;

+    }

+    

+    /**

+     * Stop the current application instance

+     */

+    protected void stop() {

+        emf.close();

+        this.emf = null;

+        this.context = null;

+    }

+    

+    /**

+     * Trigger the mechanism to allow persistence context to react to database change events.

+     * @param descriptorAlias

+     * @return

+     */

     public DatabaseEventListener subscribeToEventNotification(String descriptorAlias) {

         ServerSession session = (ServerSession) JpaHelper.getServerSession(emf);

         ClassDescriptor descriptor = session.getDescriptorForAlias(descriptorAlias);

@@ -441,26 +552,39 @@
         return subscribeToEventNotification(emf, descriptor);

     }

     

+    /**

+     * Trigger the mechanism to allow persistence context to react to database change events.

+     * @param emf

+     * @param descriptor

+     * @return

+     */

     public DatabaseEventListener subscribeToEventNotification(EntityManagerFactory emf, ClassDescriptor descriptor) {

         ServerSession session = (ServerSession) JpaHelper.getServerSession(emf);

         if (databaseEventListener == null){

             if (EVENT_LISTENER_FACTORY != null){

                 databaseEventListener = EVENT_LISTENER_FACTORY.createDatabaseEventListener();

                 session.setDatabaseEventListener(databaseEventListener);

-                session.setProperty(PersistenceFactory.CHANGE_NOTIFICATION_LISTENER, databaseEventListener);

+                session.setProperty(CHANGE_NOTIFICATION_LISTENER, databaseEventListener);

             } else {

                 throw new RuntimeException("Could not subscribe to change notification for " + descriptor.getAlias());

             }

         }

-       System.out.println("--- Subscribe set Listener " + databaseEventListener + " descriptor " + descriptor.getAlias());

-       databaseEventListener.initialize(descriptor, session);

-       databaseEventListener.register(session, descriptor);

+        databaseEventListener.initialize(descriptor, session);

+        databaseEventListener.register(session, descriptor);

         return databaseEventListener;

     }

 

-    public static void setEventListenerFactory(

-            DatabaseEventListenerFactory eventListenerFactory) {

-        EVENT_LISTENER_FACTORY = eventListenerFactory;

+    public String toString() {

+        return "Application(" + getName() + ")::" + System.identityHashCode(this);

+    }

+    

+    public Object unmarshalEntity(String type, String tenantId, MediaType acceptedMedia, InputStream in) throws JAXBException {

+        Unmarshaller unmarshaller = getJAXBContext().createUnmarshaller();

+        unmarshaller.setProperty(JAXBContext.JSON_INCLUDE_ROOT, Boolean.FALSE);

+        unmarshaller.setProperty(MEDIA_TYPE, acceptedMedia.toString());

+        unmarshaller.setAdapter(new LinkAdapter(getBaseURI().toString(), this));

+        JAXBElement<?> element = unmarshaller.unmarshal(new StreamSource(in), getClass(type));

+        return element.getValue();

     }

 

 }

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceFactory.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceFactory.java
index 4b570a7..db29f18 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceFactory.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2011 Oracle. All rights reserved.

+ * Copyright (c) 2011, 2012 Oracle. All rights reserved.

  * This program and the accompanying materials are made available under the 

  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 

  * which accompanies this distribution. 

@@ -8,7 +8,7 @@
  * http://www.eclipse.org/org/documents/edl-v10.php.

  *

  * Contributors:

- * 		dclarke - TODO

+ * 		dclarke/tware - initial implementation

  ******************************************************************************/

 package org.eclipse.persistence.jpa.rs;

 

@@ -29,7 +29,6 @@
 import org.eclipse.persistence.dynamic.DynamicClassLoader;

 import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;

 import org.eclipse.persistence.jpa.Archive;

-import org.eclipse.persistence.jpa.rs.eventlistener.DatabaseEventListenerFactory;

 import org.eclipse.persistence.jpa.rs.metadata.Application;

 import org.eclipse.persistence.jpa.rs.metadata.MetadataStore;

 import org.eclipse.persistence.jpa.rs.util.InMemoryArchive;

@@ -42,56 +41,72 @@
  * @author douglas.clarke, tom.ware

  */

 @Singleton

-public class PersistenceFactory {

-

-    public static final String CHANGE_NOTIFICATION_LISTENER = "jpars.change-notification-listener";

+public class PersistenceFactory {    

     

+    /** Holds all the PersistenceContexts available to this factory by name **/

 	private Map<String, PersistenceContext> persistenceContexts = new HashMap<String, PersistenceContext>();

     

+	/** used to keep information about bootstrapped PersistenceContexts in a persistent store **/

     private MetadataStore metadataStore;

-    

-    private DatabaseEventListenerFactory eventListenerFactory;

 	

     public PersistenceFactory(){

     }

-

-    public void initialize(){

-        initialize(new HashMap<String, Object>());

-    }

     

-    public void initialize(Map<String, Object> properties){

-        if (metadataStore != null && !metadataStore.isInitialized()){

-            List<Application> applications = metadataStore.retreiveMetadata();

-            for (Application application: applications){

-                try{

-                    URL persistenceXMLURL = new URL( application.getPersistenceXMLURL());

-                    bootstrapPersistenceContext(application.getName(), persistenceXMLURL, properties, false);

-                } catch (Exception e){

-                    // TODO proper logging

-                    System.out.println("Exception bootstrapping PersistenceFactory for application "  + application.getName());

-                    e.printStackTrace();

-                }

-            }

-        }

-    }

-    

+    /**

+     * Create a PersistenceContext based on a persistence xml provided in full text as a String

+     * @param name

+     * @param persistenceXML

+     * @param originalProperties

+     * @param replace

+     * @return

+     */

     public PersistenceContext bootstrapPersistenceContext(String name, String persistenceXML, Map<String, ?> originalProperties, boolean replace){

         ByteArrayInputStream stream = new ByteArrayInputStream(persistenceXML.getBytes());

         InMemoryArchive archive = new InMemoryArchive(stream);

         return bootstrapPersistenceContext(name, archive, null, originalProperties, replace);

     }

     

+    /**

+     * Create a PersistenceContext based on a persistence xml provided through a URL

+     * @param name

+     * @param persistenceXMLURL

+     * @param originalProperties

+     * @param replace

+     * @return

+     * @throws IOException

+     */

     public PersistenceContext bootstrapPersistenceContext(String name, URL persistenceXMLURL, Map<String, ?> originalProperties, boolean replace) throws IOException{

         InMemoryArchive archive = new InMemoryArchive(persistenceXMLURL.openStream());

         return bootstrapPersistenceContext(name, archive, persistenceXMLURL.toString(), originalProperties, replace);

     }

     

+    /**

+     * Create a persistence Context based on a persistence xml provided as a Stream

+     * @param name

+     * @param persistenceXMLStream

+     * @param originalProperties

+     * @param replace

+     * @return

+     */

     public PersistenceContext bootstrapPersistenceContext(String name, InputStream persistenceXMLStream, Map<String, ?> originalProperties, boolean replace){

         InMemoryArchive archive = new InMemoryArchive(persistenceXMLStream);

         return bootstrapPersistenceContext(name, archive, null, originalProperties, replace);

     }

-    

-    

+ 

+    /**

+     * This is the main PersistenceContext bootstrapping method.  It takes an Archive as its source of a persistence.xml

+     * file and bootstraps a persistence context based on that archive.

+     * 

+     * If the persistence.xml location is provided, that location will be stored in the metadata source so that it

+     * can be retrieved at bootstrap time.

+     * 

+     * @param name

+     * @param archive

+     * @param persistenceXMLLocation

+     * @param originalProperties

+     * @param replace

+     * @return

+     */

     public PersistenceContext bootstrapPersistenceContext(String name, Archive archive, String persistenceXMLLocation, Map<String, ?> originalProperties, boolean replace){

         initialize();

         PersistenceContext persistenceContext = getPersistenceContext(name);

@@ -112,6 +127,14 @@
         return persistenceContext;

     }

     

+    /**

+     * Bootstrap a PersistenceContext based on an pre-existing EntityManagerFactory

+     * @param name

+     * @param emf

+     * @param baseURI

+     * @param replace

+     * @return

+     */

     public PersistenceContext bootstrapPersistenceContext(String name, EntityManagerFactory emf, URI baseURI, boolean replace){

         initialize();

         PersistenceContext persistenceContext = null;

@@ -126,16 +149,10 @@
         return persistenceContext;

     }

  

-    

-    public synchronized PersistenceContext getPersistenceContext(String name){

-        initialize();

-        return persistenceContexts.get(name);

-    }

-    

-    public Set<String> getPersistenceContextNames(){

-        return persistenceContexts.keySet();

-    }

-    

+    /**

+     * Close the PersistenceContext of a given name and clean it out of our list of PersistenceContexts

+     * @param name

+     */

     public void closePersistenceContext(String name){

         PersistenceContext context = persistenceContexts.get(name);

         if (context != null){

@@ -144,6 +161,9 @@
         }

     }

     

+    /**

+     * Stop the factory.  Remove all the PersistenceContexts.

+     */

     public void close(){

         for (String key: persistenceContexts.keySet()){

             persistenceContexts.get(key).stop();

@@ -153,13 +173,18 @@
         }

     }

 

+    /**

+     * Provide an initial set of properties for bootstrapping PersistenceContexts.

+     * @param dcl

+     * @param originalProperties

+     * @return

+     */

     protected static Map<String, Object> createProperties(DynamicClassLoader dcl, Map<String, ?> originalProperties) {

         Map<String, Object> properties = new HashMap<String, Object>();

 

         properties.put(PersistenceUnitProperties.CLASSLOADER, dcl);

         properties.put(PersistenceUnitProperties.WEAVING, "static");

         properties.put("eclipselink.ddl-generation", "create-tables");

-        // properties.put("eclipselink.ddl-generation.output-mode", "database");

         properties.put(PersistenceUnitProperties.LOGGING_LEVEL, "FINEST");

 

         // For now we'll copy the connection info from admin PU

@@ -171,6 +196,56 @@
         return properties;

     }

     

+    public synchronized PersistenceContext getPersistenceContext(String name){

+        initialize();

+        return persistenceContexts.get(name);

+    }

+    

+    public Set<String> getPersistenceContextNames(){

+        return persistenceContexts.keySet();

+    }

+

+    public MetadataStore getMetadataStore() {

+        return metadataStore;

+    }

+    

+    /**

+     * Initialize the factory by checking any existing metadata store for persistence units.

+     */

+    public void initialize(){

+        initialize(new HashMap<String, Object>());

+    }

+    

+    /**

+     * Initialize the factory by checking any existing metadata store for persistence units.

+     * @param properties

+     */

+    public void initialize(Map<String, Object> properties){

+        if (metadataStore != null && !metadataStore.isInitialized()){

+            List<Application> applications = metadataStore.retreiveMetadata();

+            for (Application application: applications){

+                try{

+                    URL persistenceXMLURL = new URL( application.getPersistenceXMLURL());

+                    bootstrapPersistenceContext(application.getName(), persistenceXMLURL, properties, false);

+                } catch (Exception e){

+                    // TODO proper logging

+                    System.out.println("Exception bootstrapping PersistenceFactory for application "  + application.getName());

+                    e.printStackTrace();

+                }

+            }

+        }

+    }

+

+    public void setMetadataStore(MetadataStore metadataStore) {

+        this.metadataStore = metadataStore;

+    }

+    

+    /**

+     * Ask the metadata store to store a given persistence unit.

+     * Currently only persistence units that are defined by a location string (usually a URL) can be saved.

+     * @param applicationName

+     * @param persistenceXMLURL

+     */

     public void storeApplicationMetadata(String applicationName, String persistenceXMLURL){

         if (metadataStore != null){

             metadataStore.persistMetadata(applicationName, persistenceXMLURL);

@@ -179,23 +254,5 @@
             System.out.println("Unable to store metadata.  No MetadataStore has been configured.");

         }

     }

-

-    public MetadataStore getMetadataStore() {

-        return metadataStore;

-    }

-

-    public void setMetadataStore(MetadataStore metadataStore) {

-        this.metadataStore = metadataStore;

-    }

-    

-

-    public DatabaseEventListenerFactory getEventListenerFactory() {

-        return eventListenerFactory;

-    }

-

-    public void setEventListenerFactory(

-            DatabaseEventListenerFactory eventListenerFactory) {

-        this.eventListenerFactory = eventListenerFactory;

-    }

     

 }

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java
index b2e95f7..683bcd5 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java
@@ -12,7 +12,6 @@
  ******************************************************************************/

 package org.eclipse.persistence.jpa.rs;

 

-import static org.eclipse.persistence.jaxb.JAXBContext.MEDIA_TYPE;

 import static org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller.mediaType;

 

 import java.io.InputStream;

@@ -49,21 +48,15 @@
 import javax.ws.rs.core.Response.Status;

 import javax.ws.rs.core.StreamingOutput;

 import javax.ws.rs.core.UriInfo;

-import javax.xml.bind.JAXBElement;

 import javax.xml.bind.JAXBException;

-import javax.xml.bind.Unmarshaller;

-import javax.xml.transform.stream.StreamSource;

 

 import org.eclipse.persistence.config.PersistenceUnitProperties;

 import org.eclipse.persistence.descriptors.ClassDescriptor;

 import org.eclipse.persistence.dynamic.DynamicClassLoader;

-import org.eclipse.persistence.dynamic.DynamicEntity;

 import org.eclipse.persistence.internal.queries.MapContainerPolicy;

-import org.eclipse.persistence.jaxb.JAXBContext;

 import org.eclipse.persistence.jpa.JpaHelper;

 import org.eclipse.persistence.jpa.rs.metadata.DatabaseMetadataStore;

 import org.eclipse.persistence.jpa.rs.util.IdHelper;

-import org.eclipse.persistence.jpa.rs.util.LinkAdapter;

 import org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller;

 import org.eclipse.persistence.mappings.CollectionMapping;

 import org.eclipse.persistence.mappings.DatabaseMapping;

@@ -206,6 +199,21 @@
         rb.status(Status.OK);

         return rb.build();

     }

+

+    @PUT

+    @Path("{context}/subscribe/{name}")

+    public Response subscribe(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context UriInfo ui) {

+        ResponseBuilder rb = new ResponseBuilderImpl();

+        System.out.println("Subscribe " + name);

+        PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

+        if (app == null){

+            rb.status(Status.NOT_FOUND);

+        }

+        app.subscribeToEventNotification(name);

+

+        rb.status(Status.OK);

+        return rb.build();

+    }

     

     @GET

     @Path("{context}/entity/{type}")

@@ -228,7 +236,12 @@
     @Path("{context}/entity/{type}")

     public Response create(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) {

         PersistenceContext app = get(persistenceUnit, uriInfo.getBaseUri());

-        Object entity = unmarshalEntity(app, type, getTenantId(hh), mediaType(hh.getAcceptableMediaTypes()), in);

+        Object entity = null;

+        try {

+            entity = app.unmarshalEntity(type, getTenantId(hh), mediaType(hh.getAcceptableMediaTypes()), in);

+        } catch (JAXBException e){

+            throw new WebApplicationException(e);

+        }

         app.create(getTenantId(hh), entity);

 

         ResponseBuilder rb = new ResponseBuilderImpl();

@@ -243,15 +256,26 @@
         PersistenceContext app = get(persistenceUnit, uriInfo.getBaseUri());

         String tenantId = getTenantId(hh);

         MediaType contentType = mediaType(hh.getRequestHeader(HttpHeaders.CONTENT_TYPE)); 

-        Object entity = unmarshalEntity(app, type, tenantId, contentType, in);

-        entity = app.merge(type, tenantId, entity);

+        Object entity = null;

+        try {

+            entity = app.unmarshalEntity(type, tenantId, contentType, in);

+        } catch (JAXBException e){

+            throw new WebApplicationException(e);

+        }

+        entity = app.merge(tenantId, entity);

         return new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes());

     }

 

     @GET

+    @Path("{context}/query")

+    public StreamingOutput adhocQuery(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo ui) {

+        throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);

+    }

+    

+    @GET

     @Path("{context}/query/{name}")

     public StreamingOutput namedQuery(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

-long millis = System.currentTimeMillis();

+        long millis = System.currentTimeMillis();

         System.out.println("Start Named Query " + name);

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

         Object result = app.query(name, Service.getParameterMap(ui), Service.getHintMap(ui), false);

@@ -269,21 +293,6 @@
         Object result = app.query(name, Service.getParameterMap(ui), Service.getHintMap(ui), true);

         return new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes());

     }

-

-    @PUT

-    @Path("{context}/subscribe/{name}")

-    public Response subscribe(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context UriInfo ui) {

-        ResponseBuilder rb = new ResponseBuilderImpl();

-        System.out.println("Subscribe " + name);

-        PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

-        if (app == null){

-            rb.status(Status.NOT_FOUND);

-        }

-        app.subscribeToEventNotification(name);

-

-        rb.status(Status.OK);

-        return rb.build();

-    }

     

     protected void appendDescriptor(StringBuffer buffer, ClassDescriptor descriptor){

         buffer.append("{\"name\": ");

@@ -325,35 +334,9 @@
         buffer.append("}");

     }

     

-    /**

-     * This method has been temporarily added to allow processing of either query or matrix parameters

-     * When the final protocol is worked out, it should be removed or altered.

-     * 

-     * Here we check for query parameters and if they don't exist, we get the matrix parameters.

-     * @param info

-     * @return

-     */

-    private static Map<String, Object> getParameterMap(UriInfo info){

-        Map<String, Object> parameters = new HashMap<String, Object>();

-        PathSegment pathSegment = info.getPathSegments().get(info.getPathSegments().size() - 1); 

-        for(Entry<String, List<String>> entry : pathSegment.getMatrixParameters().entrySet()) { 

-            parameters.put(entry.getKey(), entry.getValue().get(0)); 

-        }

-        return parameters;

-    }

-    

-    private static Map<String, Object> getHintMap(UriInfo info){

-        Map<String, Object> hints = new HashMap<String, Object>();

-         for(String key :  info.getQueryParameters().keySet()) { 

-            hints.put(key, info.getQueryParameters().getFirst(key));  

-        }

-        return hints;

-    }

-    

-    @GET

-    @Path("{context}/query")

-    public StreamingOutput adhocQuery(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo ui) {

-        throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);

+    @PreDestroy

+    public void close() {

+        factory.close();

     }

 

     private PersistenceContext get(String persistenceUnit, URI defaultURI) {

@@ -376,6 +359,31 @@
         }

         return app;

     }

+    

+    private static Map<String, Object> getHintMap(UriInfo info){

+        Map<String, Object> hints = new HashMap<String, Object>();

+         for(String key :  info.getQueryParameters().keySet()) { 

+            hints.put(key, info.getQueryParameters().getFirst(key));  

+        }

+        return hints;

+    }

+    

+    /**

+     * This method has been temporarily added to allow processing of either query or matrix parameters

+     * When the final protocol is worked out, it should be removed or altered.

+     * 

+     * Here we check for query parameters and if they don't exist, we get the matrix parameters.

+     * @param info

+     * @return

+     */

+    private static Map<String, Object> getParameterMap(UriInfo info){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        PathSegment pathSegment = info.getPathSegments().get(info.getPathSegments().size() - 1); 

+        for(Entry<String, List<String>> entry : pathSegment.getMatrixParameters().entrySet()) { 

+            parameters.put(entry.getKey(), entry.getValue().get(0)); 

+        }

+        return parameters;

+    }

 

     private String getTenantId(HttpHeaders hh) {

         List<String> tenantIdValues = hh.getRequestHeader("tenant-id");

@@ -387,21 +395,6 @@
         }

         return tenantIdValues.get(0);

     }

-

-    private Object unmarshalEntity(PersistenceContext app, String type, String tenantId, MediaType acceptedMedia, InputStream in) {

-        Unmarshaller unmarshaller;

-        try {

-            unmarshaller = app.getJAXBContext().createUnmarshaller();

-            unmarshaller.setProperty(JAXBContext.JSON_INCLUDE_ROOT, Boolean.FALSE);

-            unmarshaller.setProperty(MEDIA_TYPE, acceptedMedia.toString());

-            unmarshaller.setAdapter(new LinkAdapter(app.getBaseURI().toString(), app));

-            JAXBElement<?> element = unmarshaller.unmarshal(new StreamSource(in), app.getClass(type));

-            return element.getValue();

-        } catch (JAXBException e) {

-            throw new WebApplicationException(Status.BAD_REQUEST);

-        }

-    }

-

     

     private String getURL(HttpHeaders hh){

         List<String> persistenceXmlURLs = hh.getRequestHeader("persistenceXmlURL");

@@ -414,9 +407,4 @@
         return persistenceXmlURLs.get(0);

     }

 

-    @PreDestroy

-    public void close() {

-        factory.close();

-    }

-

 }
\ No newline at end of file
diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ChangeListener.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/ChangeListener.java
similarity index 78%
rename from JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ChangeListener.java
rename to JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/ChangeListener.java
index 17e7d62..93ae4f8 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/ChangeListener.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/ChangeListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2011 Oracle. All rights reserved.

+ * Copyright (c) 2011, 2012 Oracle. All rights reserved.

  * This program and the accompanying materials are made available under the 

  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 

  * which accompanies this distribution. 

@@ -10,8 +10,14 @@
  * Contributors:

  *      dclarke/tware - initial 

  ******************************************************************************/

-package org.eclipse.persistence.jpa.rs.util;

+package org.eclipse.persistence.jpa.rs.eventlistener;

 

+/**

+ * A ChangeListener is used to extend a PersistenceContext to react to database sent change 

+ * events.

+ * @author tware

+ *

+ */

 public interface ChangeListener {

 

     void objectUpdated(String entityName, String transactionId, String rowId); 

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DatabaseEventListenerFactory.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DatabaseEventListenerFactory.java
index 297f000..1809380 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DatabaseEventListenerFactory.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DatabaseEventListenerFactory.java
@@ -1,5 +1,22 @@
+/****************************************************************************

+ * Copyright (c) 2012 Oracle. All rights reserved.

+ * This program and the accompanying materials are made available under the 

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 

+ * which accompanies this distribution. 

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at 

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *      tware - initial implementation

+ ******************************************************************************/

 package org.eclipse.persistence.jpa.rs.eventlistener;

 

+/**

+ * Provides a mechanism for plugging in database event listener creation.

+ * @author tware

+ *

+ */

 public interface DatabaseEventListenerFactory {

     

     public DescriptorBasedDatabaseEventListener createDatabaseEventListener();

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DescriptorBasedDatabaseEventListener.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DescriptorBasedDatabaseEventListener.java
index 5a987b4..6df4df4 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DescriptorBasedDatabaseEventListener.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/eventlistener/DescriptorBasedDatabaseEventListener.java
@@ -1,10 +1,41 @@
+/****************************************************************************

+ * Copyright (c) 2012 Oracle. All rights reserved.

+ * This program and the accompanying materials are made available under the 

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 

+ * which accompanies this distribution. 

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at 

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *      tware - initial implementation

+ ******************************************************************************/

 package org.eclipse.persistence.jpa.rs.eventlistener;

 

 import org.eclipse.persistence.descriptors.ClassDescriptor;

 import org.eclipse.persistence.platform.database.events.DatabaseEventListener;

 import org.eclipse.persistence.sessions.Session;

 

+/**

+ * Extends EclipseLink's database event listening capabilities by allowing a listener to subscribe to

+ * to change notifications from the database

+ * 

+ * This listener also expands the interface to support subscription on a descriptor basis rather than 

+ * the wholesale subscription provided by its superclass.

+ * 

+ * @author tware

+ *

+ */

 public interface DescriptorBasedDatabaseEventListener extends DatabaseEventListener {

 

+    /**

+     * Register for change notifications on a particular descriptor

+     * @param session

+     * @param descriptor

+     */

     public void register(Session session, ClassDescriptor descriptor);

+    

+    public void addChangeListener(ChangeListener listener);

+    

+    public void removeChangeListener(ChangeListener listener);

 }

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/Application.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/Application.java
index cff9d7d..c5f333d 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/Application.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/Application.java
@@ -12,9 +12,16 @@
  ******************************************************************************/

 package org.eclipse.persistence.jpa.rs.metadata;

 

+/**

+ * Used to persist information about the location of an application

+ * @author tware

+ *

+ */

+

 import javax.persistence.Entity;

 import javax.persistence.Id;

 

+

 @Entity

 public class Application {

 

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/DatabaseMetadataStore.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/DatabaseMetadataStore.java
index a9b1484..577d2d6 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/DatabaseMetadataStore.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/DatabaseMetadataStore.java
@@ -22,6 +22,11 @@
 

 import org.eclipse.persistence.config.PersistenceUnitProperties;

 

+/**

+ * A metadata store that stores information about existing applications in a database

+ * @author tware

+ *

+ */

 public class DatabaseMetadataStore implements MetadataStore {

     

     protected EntityManagerFactory factory = null;

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/MetadataStore.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/MetadataStore.java
index 5d4e729..250e0e9 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/MetadataStore.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/metadata/MetadataStore.java
@@ -15,6 +15,11 @@
 import java.util.List;

 import java.util.Map;

 

+/**

+ * Implementers are capable of storing information about a PersistenceContext in some kind of a persistent store

+ * @author tware

+ *

+ */

 public interface MetadataStore {

 

     public void persistMetadata(String name, String url);

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/DatabaseListener.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/DatabaseListener.java
deleted file mode 100644
index 90fa854..0000000
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/DatabaseListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.eclipse.persistence.jpa.rs.util;

-

-import org.eclipse.persistence.platform.database.events.DatabaseEventListener;

-

-public interface DatabaseListener extends DatabaseEventListener {

-

-    public void addChangeListener(ChangeListener listener);

-    

-    public void removeChangeListener(ChangeListener listener);

-    

-}

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java
index 1cca0c5..9c89edb 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/LinkAdapter.java
@@ -30,6 +30,18 @@
 import org.eclipse.persistence.mappings.DatabaseMapping;

 import org.eclipse.persistence.queries.FetchGroup;

 

+/**

+ * Used with JAXB to convert from a URL representing an relationship to an object

+ * It provides functionality at marshall and unmarshall time

+ * 

+ * At marshall time, the target of a relationship will be marshalled as a URL that could be

+ * used to find the object through a REST service

+ * 

+ * At unmarsall time, the URL will be deconstructed and used to find the object in JPA.

+ * 

+ * @author tware

+ *

+ */

 public class LinkAdapter extends XmlAdapter<String, Object> {

 

     private String baseURI = null;

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java
index 7ea879b..5ef7963 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/StreamingOutputMarshaller.java
@@ -62,8 +62,8 @@
     }

 

     public void write(OutputStream output) throws IOException, WebApplicationException {

-long millis = System.currentTimeMillis();

-        System.out.println("SteamingOutputMarshaller About to write ");

+        long millis = System.currentTimeMillis();

+        System.out.println("StreamingOutputMarshaller About to write ");

         if (this.context != null && this.context.getJAXBContext() != null && this.result != null && !this.mediaType.equals(MediaType.WILDCARD_TYPE)) {

             try {

                 Marshaller marshaller = createMarshaller(context, mediaType);

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/XMLDatabaseMetadataSource.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/XMLDatabaseMetadataSource.java
deleted file mode 100644
index 57022db..0000000
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/util/XMLDatabaseMetadataSource.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*******************************************************************************

- * Copyright (c) 2011 Oracle. All rights reserved.

- * This program and the accompanying materials are made available under the 

- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 

- * which accompanies this distribution. 

- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

- * and the Eclipse Distribution License is available at 

- * http://www.eclipse.org/org/documents/edl-v10.php.

- *

- * Contributors:

- * 		dclarke/tware - initial 

- ******************************************************************************/

-package org.eclipse.persistence.jpa.rs.util;

-

-import java.io.CharArrayReader;

-import java.io.Reader;

-import java.util.Map;

-

-import org.eclipse.persistence.jpa.metadata.XMLMetadataSource;

-import org.eclipse.persistence.logging.SessionLog;

-

-public class XMLDatabaseMetadataSource extends XMLMetadataSource {

-    

-    public Reader getEntityMappingsReader(Map<String, Object> properties, ClassLoader classLoader, SessionLog log) {

-       

-        CharArrayReader reader = new CharArrayReader(null);

-        return reader;

-    }

-    

-}