/** * Created on Oct 2, 2005 * * $Id$ * $Revision$ */ package org.springmodules.jcr.mapping; 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.mapper.model.MappingDescriptor; import org.apache.portals.graffito.jcr.persistence.PersistenceManager; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.BinaryTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.BooleanTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.ByteArrayTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.CalendarTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.DoubleTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.IntTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.LongTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.StringTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.TimestampTypeConverter; import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.UtilDateTypeConverter; 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; import org.springmodules.jcr.mapping.support.MapperSupport; /** * 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(); } /** * @param sessionFactory */ public JcrMappingTemplate(SessionFactory sessionFactory, MappingDescriptor descriptor) { setSessionFactory(sessionFactory); setMapper(descriptor); 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 */ protected QueryManager createQueryManager() { return new QueryManagerImpl(mapper); } /** * 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, createDefaultConverters(session), 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 StringTypeConverter(session.getValueFactory())); map.put(InputStream.class, new BinaryTypeConverter(session.getValueFactory())); map.put(long.class, new LongTypeConverter(session.getValueFactory())); map.put(Long.class, new LongTypeConverter(session.getValueFactory())); map.put(int.class, new IntTypeConverter(session.getValueFactory())); map.put(Integer.class, new IntTypeConverter(session.getValueFactory())); map.put(double.class, new DoubleTypeConverter(session.getValueFactory())); map.put(Double.class, new DoubleTypeConverter(session.getValueFactory())); map.put(boolean.class, new BooleanTypeConverter(session.getValueFactory())); map.put(Boolean.class, new BooleanTypeConverter(session.getValueFactory())); map.put(Calendar.class, new CalendarTypeConverter(session.getValueFactory())); map.put(Date.class, new UtilDateTypeConverter(session.getValueFactory())); map.put(byte[].class, new ByteArrayTypeConverter(session.getValueFactory())); map.put(Timestamp.class, new TimestampTypeConverter(session.getValueFactory())); 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.String path, final java.lang.Object object) { execute(new JcrMappingCallback() { public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException { manager.insert(path, object); return null; } }, true); } /** * @see org.springmodules.jcr.mapping.JcrMappingOperations#update(java.lang.String, java.lang.Object) */ public void update(final java.lang.String path, final java.lang.Object object) { execute(new JcrMappingCallback() { public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException { manager.update(path, 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.Class pojoClass, final java.lang.String path) { return execute(new JcrMappingCallback() { public Object doInJcrMapping(PersistenceManager manager) throws JcrMappingException { return manager.getObject(pojoClass, 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; } /** * This method should be used when the client has the mapping descriptions but not * the mapper. * * @param descriptor The mapping descriptor to set. */ public void setMapper(MappingDescriptor descriptor) { this.mapper = new MapperSupport(descriptor); } }