You are viewing a plain text version of this content. The canonical link for it is here.
Posted to graffito-commits@incubator.apache.org by cl...@apache.org on 2006/06/14 19:08:49 UTC

svn commit: r414355 - in /incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring: JackrabbitSessionFactory.java JcrMappingCallback.java JcrMappingOperations.java JcrMappingTemplate.java MappingDescriptorFactoryBean.java

Author: clombart
Date: Wed Jun 14 12:08:49 2006
New Revision: 414355

URL: http://svn.apache.org/viewvc?rev=414355&view=rev
Log:
Review OCM/JCR  Spring support

Added:
    incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JackrabbitSessionFactory.java
    incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingCallback.java
    incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingOperations.java
    incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingTemplate.java
    incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/MappingDescriptorFactoryBean.java

Added: incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JackrabbitSessionFactory.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JackrabbitSessionFactory.java?rev=414355&view=auto
==============================================================================
--- incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JackrabbitSessionFactory.java (added)
+++ incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JackrabbitSessionFactory.java Wed Jun 14 12:08:49 2006
@@ -0,0 +1,71 @@
+/* ========================================================================
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================================
+ */
+package org.apache.portals.graffito.jcr.spring;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.portals.graffito.jcr.repository.RepositoryUtil;
+import org.springmodules.jcr.JcrSessionFactory;
+
+/**
+ *  JCR session factory specific to Jaclrabbit for Graffito. Until now, Jackrabbit cannot unregister a namespace. 
+ *  So, the JcrSessionFactory provided by the spring module is not usefull when namespace management are needed. 
+ *  This class extends the JcrSessionFactory in order to add the namespace graffito
+ *
+ * @author <a href="mailto:christophe.lombart@sword-technologies.com">Christophe Lombart</a>
+ */
+public class JackrabbitSessionFactory extends JcrSessionFactory 
+{
+
+	/**
+	 * Register the namespaces.
+	 * 
+	 * @param session
+	 * @throws RepositoryException
+	 */
+	protected void registerNamespaces() throws RepositoryException {
+
+		Session session = getSession();
+        try
+        {
+           String[] jcrNamespaces = session.getWorkspace().getNamespaceRegistry().getPrefixes();
+           boolean createGraffitoNamespace = true;
+           for (int i = 0; i < jcrNamespaces.length; i++)
+           {
+               if (jcrNamespaces[i].equals(RepositoryUtil.GRAFFITO_NAMESPACE_PREFIX))
+               {
+                   createGraffitoNamespace = false;
+                  
+               }
+           }
+            
+           if (createGraffitoNamespace)
+           {
+               session.getWorkspace().getNamespaceRegistry().registerNamespace(RepositoryUtil.GRAFFITO_NAMESPACE_PREFIX,RepositoryUtil.GRAFFITO_NAMESPACE);               
+           }
+           
+       }
+       catch (Exception e)
+       {
+           throw new RepositoryException(e.getMessage());
+       }
+       
+       super.registerNamespaces();
+	}
+
+}

Added: incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingCallback.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingCallback.java?rev=414355&view=auto
==============================================================================
--- incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingCallback.java (added)
+++ incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingCallback.java Wed Jun 14 12:08:49 2006
@@ -0,0 +1,35 @@
+/**
+ * Created on Oct 3, 2005
+ *
+ * $Id$
+ * $Revision$
+ */
+package org.apache.portals.graffito.jcr.spring;
+
+import org.apache.portals.graffito.jcr.exception.JcrMappingException;
+import org.apache.portals.graffito.jcr.persistence.PersistenceManager;
+
+/**
+ * Callback interface for Jcr mapping code. To be used with JcrMappingTemplate's execute method, 
+ * assumably often as anonymous classes within a method implementation. The typical 
+ * implementation will call PersistenceManager.get/insert/remove/update to perform some operations on 
+ * the repository.
+ * 
+ * @author Costin Leau
+ *
+ */
+public interface JcrMappingCallback {
+
+    /**
+     * Called by {@link JcrMappingTemplate#execute} within an active PersistenceManager
+     * {@link org.apache.graffito.jcr.mapper.persistence.PersistenceManager}. 
+     * It is not responsible for logging out of the <code>Session</code> or handling transactions.
+     *
+     * Allows for returning a result object created within the
+     * callback, i.e. a domain object or a collection of domain
+     * objects. A thrown {@link RuntimeException} is treated as an
+     * application exeception; it is propagated to the caller of the
+     * template.
+     */
+    public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException;
+}

Added: incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingOperations.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingOperations.java?rev=414355&view=auto
==============================================================================
--- incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingOperations.java (added)
+++ incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingOperations.java Wed Jun 14 12:08:49 2006
@@ -0,0 +1,55 @@
+package org.apache.portals.graffito.jcr.spring;
+
+import java.util.Collection;
+
+import org.apache.portals.graffito.jcr.query.Query;
+import org.springframework.dao.DataAccessException;
+
+/**
+ * Interface that specifies a basic set of JCR mapping operations. Not often used, but 
+ * a useful option to enhance testability, as it can easily be mocked or stubbed.
+ * 
+ * <p>
+ * Provides JcrMappingTemplate's data access methods that mirror various PersistenceManager
+ * methods. See the required javadocs for details on those methods.
+ * 
+ * @author Costin Leau
+ *
+ */
+public interface JcrMappingOperations {
+
+    /**
+     * Execute a JcrMappingCallback.
+     * 
+     * @param callback callback to execute
+     * @return the callback result
+     * @throws DataAccessException
+     */
+    public Object execute(JcrMappingCallback callback) throws DataAccessException;
+
+    /**
+     * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#insert(java.lang.String, java.lang.Object)
+     */
+    public void insert( final java.lang.Object object);
+
+    /**
+     * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#update(java.lang.String, java.lang.Object)
+     */
+    public void update( final java.lang.Object object);
+
+    /**
+     * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#remove(java.lang.String)
+     */
+    public void remove(final java.lang.String path);
+
+    /**
+     * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObject(java.lang.Class, java.lang.String) 
+     */
+    public Object getObject( final java.lang.String path);
+
+    /**
+     * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager#getObjects(org.apache.portals.graffito.jcr.query.Query)
+     */
+    public Collection getObjects(final Query query);
+
+}
\ No newline at end of file

Added: incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingTemplate.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingTemplate.java?rev=414355&view=auto
==============================================================================
--- incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingTemplate.java (added)
+++ incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/JcrMappingTemplate.java Wed Jun 14 12:08:49 2006
@@ -0,0 +1,267 @@
+/**
+ * Created on Oct 2, 2005
+ *
+ * $Id$
+ * $Revision$
+ */
+package org.apache.portals.graffito.jcr.spring;
+
+import java.io.InputStream;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.portals.graffito.jcr.exception.JcrMappingException;
+import org.apache.portals.graffito.jcr.mapper.Mapper;
+import org.apache.portals.graffito.jcr.persistence.PersistenceManager;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.BinaryTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.BooleanTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.ByteArrayTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.CalendarTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.DoubleTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.IntTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.LongTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.StringTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.TimestampTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.UtilDateTypeConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.impl.PersistenceManagerImpl;
+import org.apache.portals.graffito.jcr.query.Query;
+import org.apache.portals.graffito.jcr.query.QueryManager;
+import org.apache.portals.graffito.jcr.query.impl.QueryManagerImpl;
+import org.springframework.dao.DataAccessException;
+import org.springmodules.jcr.JcrCallback;
+import org.springmodules.jcr.JcrSystemException;
+import org.springmodules.jcr.JcrTemplate;
+import org.springmodules.jcr.SessionFactory;
+
+/**
+ * Template whichs adds mapping support for the Java Content Repository.
+ * <p/>
+ * For PersistenceManagers the template creates internally the set of default converters.
+ * 
+ * 
+ * @see org.apache.portals.graffito.jcr.persistence.PersistenceManager
+ * @author Costin Leau
+ * 
+ */
+public class JcrMappingTemplate extends JcrTemplate implements JcrMappingOperations {
+
+    private Mapper mapper;
+    
+
+    /**
+     * Default constructor for JcrTemplate
+     */
+    public JcrMappingTemplate() {
+        super();
+
+    }
+
+    /**
+     * @param sessionFactory
+     */
+    public JcrMappingTemplate(SessionFactory sessionFactory, Mapper mapper) {
+        setSessionFactory(sessionFactory);
+        setMapper(mapper);
+        
+        afterPropertiesSet();
+    }
+
+    /**
+     * Add rule for checking the mapper.
+     * 
+     * @see org.springmodules.jcr.JcrAccessor#afterPropertiesSet()
+     */
+    public void afterPropertiesSet() {
+        super.afterPropertiesSet();
+        if (mapper == null)
+            throw new IllegalArgumentException("mapper can NOT be null");
+    }
+
+    /**
+     * Method for creating a query manager. It's unclear where this entity is stateless or not.
+     * 
+     * @return
+     */
+    public  QueryManager createQueryManager() {
+    	    try 
+    	    {
+			Map atomicTypeConverters = this.createDefaultConverters(this.getSession());
+            return new QueryManagerImpl (mapper, atomicTypeConverters);
+		} 
+    	    catch (RepositoryException e) 
+    	    {
+			throw new JcrSystemException(e);
+		}
+    }
+
+    /**
+     * Creates a persistence manager. It's unclear if this object is stateless/thread-safe or not.
+     * However because it depends on session it has to be created per session and it's not per repository.
+     * 
+     * 
+     * @param session
+     * @return
+     * @throws JcrMappingException
+     */
+    protected PersistenceManager createPersistenceManager(Session session) throws RepositoryException, JcrMappingException {
+        return new PersistenceManagerImpl(mapper,  createQueryManager(), session);
+    }
+
+    /**
+     * Due to the way the actual jcr-mapping is made we have to create the converters for
+     * each session.
+     * 
+     * @param session
+     * @return
+     */
+    protected Map createDefaultConverters(Session session) throws RepositoryException {
+        Map map = new HashMap(14);
+
+        map.put(String.class, new StringTypeConverterImpl());
+        map.put(InputStream.class, new BinaryTypeConverterImpl());
+        map.put(long.class, new LongTypeConverterImpl());
+        map.put(Long.class, new LongTypeConverterImpl());
+        map.put(int.class, new IntTypeConverterImpl());
+        map.put(Integer.class, new IntTypeConverterImpl());
+        map.put(double.class, new DoubleTypeConverterImpl());
+        map.put(Double.class, new DoubleTypeConverterImpl());
+        map.put(boolean.class, new BooleanTypeConverterImpl());
+        map.put(Boolean.class, new BooleanTypeConverterImpl());
+        map.put(Calendar.class, new CalendarTypeConverterImpl());
+        map.put(Date.class, new UtilDateTypeConverterImpl());
+        map.put(byte[].class, new ByteArrayTypeConverterImpl());
+        map.put(Timestamp.class, new TimestampTypeConverterImpl());
+
+        return map;
+    }
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#execute(org.springmodules.jcr.mapping.JcrMappingCallback, boolean)
+     */
+    public Object execute(final JcrMappingCallback action, boolean exposeNativeSession) throws DataAccessException {
+        return execute(new JcrCallback() {
+            /**
+             * @see org.springmodules.jcr.JcrCallback#doInJcr(javax.jcr.Session)
+             */
+            public Object doInJcr(Session session) throws RepositoryException {
+                try {
+                    return action.doInJcrMapping(createPersistenceManager(session));
+                } catch (JcrMappingException e) {
+                    throw convertMappingAccessException(e);
+                }
+            }
+
+        }, exposeNativeSession);
+    }
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#execute(org.springmodules.jcr.mapping.JcrMappingCallback)
+     */
+    public Object execute(JcrMappingCallback callback) throws DataAccessException {
+        return execute(callback, isExposeNativeSession());
+    }
+
+    // ----------------
+    // Delegate methods
+    // ----------------
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#insert(java.lang.String, java.lang.Object)
+     */
+    public void insert(final java.lang.Object object) {
+        execute(new JcrMappingCallback() {
+            public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException {
+                manager.insert(object);
+                return null;
+            }
+        }, true);
+    }
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#update(java.lang.String, java.lang.Object)
+     */
+    public void update( final java.lang.Object object) {
+        execute(new JcrMappingCallback() {
+            public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException {
+                manager.update( object);
+                return null;
+            }
+        }, true);
+    }
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#remove(java.lang.String)
+     */
+    public void remove(final java.lang.String path) {
+        execute(new JcrMappingCallback() {
+            public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException {
+                manager.remove(path);
+                return null;
+            }
+        }, true);
+    }
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#getObject(java.lang.Class, java.lang.String)
+     */
+    public Object getObject(final java.lang.String path) {
+        return execute(new JcrMappingCallback() {
+            public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException {
+                return manager.getObject(path);
+            }
+        }, true);
+    }
+
+    /**
+     * @see org.springmodules.jcr.mapping.JcrMappingOperations#getObjects(org.apache.portals.graffito.jcr.query.Query)
+     */
+    public Collection getObjects(final Query query) {
+        return (Collection) execute(new JcrMappingCallback() {
+            public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException {
+                return manager.getObjects(query);
+            }
+        }, true);
+    }
+
+    /**
+     * Convert the given MappingException to an appropriate exception from
+     * the <code>org.springframework.dao</code> hierarchy.
+     * <p>
+     * Note that because we have no base specific exception we have to catch
+     * the generic Exception and translate it into JcrSystemException.
+     * <p>
+     * May be overridden in subclasses.
+     * 
+     * @param ex Exception that occured
+     * @return the corresponding DataAccessException instance
+     */
+    public DataAccessException convertMappingAccessException(Exception ex) {
+        // repository exception
+        if (ex instanceof RepositoryException)
+            return super.convertJcrAccessException((RepositoryException) ex);
+        return new JcrSystemException(ex);
+    }
+
+    /**
+     * @return Returns the mapper.
+     */
+    public Mapper getMapper() {
+        return mapper;
+    }
+
+    /**
+     * @param mapper The mapper to set.
+     */
+    public void setMapper(Mapper mapper) {
+        this.mapper = mapper;
+    }
+
+    
+}

Added: incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/MappingDescriptorFactoryBean.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/MappingDescriptorFactoryBean.java?rev=414355&view=auto
==============================================================================
--- incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/MappingDescriptorFactoryBean.java (added)
+++ incubator/graffito/trunk/jcr/spring/src/java/org/apache/portals/graffito/jcr/spring/MappingDescriptorFactoryBean.java Wed Jun 14 12:08:49 2006
@@ -0,0 +1,103 @@
+/**
+ * Created on Oct 2, 2005
+ *
+ * $Id$
+ * $Revision$
+ */
+package org.apache.portals.graffito.jcr.spring;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.portals.graffito.jcr.exception.JcrMappingException;
+import org.apache.portals.graffito.jcr.mapper.impl.DigesterDescriptorReader;
+import org.apache.portals.graffito.jcr.mapper.model.ClassDescriptor;
+import org.apache.portals.graffito.jcr.mapper.model.MappingDescriptor;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+
+/**
+ * Factory bean for loading mapping files. This factory beans can load several file descriptors
+ * and assembles them into an overall class descriptor. 
+ * 
+ * @author Costin Leau
+ *
+ */
+public class MappingDescriptorFactoryBean implements FactoryBean, InitializingBean {
+
+    private static final Log log = LogFactory.getLog(MappingDescriptorFactoryBean.class);
+
+    private MappingDescriptor mappingDescriptor;
+
+    private Resource[] mappings;
+
+    /**
+     * @see org.springframework.beans.factory.FactoryBean#getObject()
+     */
+    public Object getObject() throws Exception {
+        return mappingDescriptor;
+    }
+
+    /**
+     * @see org.springframework.beans.factory.FactoryBean#getObjectType()
+     */
+    public Class getObjectType() {
+        return (this.mappingDescriptor != null) ? this.mappingDescriptor.getClass() : ClassDescriptor.class;
+    }
+
+    /**
+     * @see org.springframework.beans.factory.FactoryBean#isSingleton()
+     */
+    public boolean isSingleton() {
+        return true;
+    }
+
+    /**
+     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+     */
+    public void afterPropertiesSet() throws Exception {
+        if (mappings == null || mappings.length == 0)
+            throw new IllegalArgumentException("at least one mapping file is needed");
+
+        createMappingDescriptor();
+    }
+
+    /**
+     * Subclasses can extend this method to provide custom behavior when creating 
+     * the mapping descriptor
+     */
+    protected void createMappingDescriptor() throws IOException, JcrMappingException {
+        // load the descriptors step by step and concatenate everything in an over-all
+        // descriptor
+    	   DigesterDescriptorReader reader = new DigesterDescriptorReader();
+        mappingDescriptor = reader.loadClassDescriptors(mappings[0].getInputStream());
+        boolean debug = log.isDebugEnabled();
+
+        for (int i = 1; i < mappings.length; i++) {
+            if (mappings[i] != null) {
+                MappingDescriptor descriptor = reader.loadClassDescriptors(mappings[i].getInputStream());
+                for (Iterator iter = descriptor.getClassDescriptorsByClassName().values().iterator(); iter.hasNext();) {
+                    mappingDescriptor.addClassDescriptor((ClassDescriptor) iter.next());
+                }
+            }
+        }
+    }
+
+    /**
+     * @return Returns the descriptors.
+     */
+    public Resource[] getMappings() {
+        return mappings;
+    }
+
+    /**
+     * @param descriptors The descriptors to set.
+     */
+    public void setMappings(Resource[] descriptors) {
+        this.mappings = descriptors;
+    }
+
+}