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;
+ }
+
+}