Added the ability to use the Spring 3.0 ApplicationEvent mechanism for event handling internally within the mapping framework.
This commit is contained in:
@@ -16,15 +16,38 @@
|
||||
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.mapping.model.*;
|
||||
import org.springframework.data.mapping.event.MappingContextEvent;
|
||||
import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.mapping.model.MappingConfigurationBuilder;
|
||||
import org.springframework.data.mapping.model.MappingConfigurationException;
|
||||
import org.springframework.data.mapping.model.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,26 +55,16 @@ import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.FieldCallback;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
public class BasicMappingContext implements MappingContext, InitializingBean, ApplicationContextAware {
|
||||
|
||||
protected Logger log = LoggerFactory.getLogger(getClass());
|
||||
protected ApplicationContext applicationContext;
|
||||
protected MappingConfigurationBuilder builder;
|
||||
protected ConcurrentMap<TypeInformation, PersistentEntity<?>> persistentEntities = new ConcurrentHashMap<TypeInformation, PersistentEntity<?>>();
|
||||
protected ConcurrentMap<PersistentEntity<?>, List<Validator>> validators = new ConcurrentHashMap<PersistentEntity<?>, List<Validator>>();
|
||||
protected ConcurrentSkipListSet<Listener> listeners = new ConcurrentSkipListSet<Listener>();
|
||||
protected GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
|
||||
public BasicMappingContext() {
|
||||
@@ -67,6 +80,11 @@ public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PersistentEntity<?>> getPersistentEntities() {
|
||||
return persistentEntities.values();
|
||||
@@ -79,24 +97,24 @@ public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
public <T> PersistentEntity<T> getPersistentEntity(Class<T> type) {
|
||||
return getPersistentEntity(new ClassTypeInformation(type));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public <T> PersistentEntity<T> getPersistentEntity(TypeInformation type) {
|
||||
return (PersistentEntity<T>) persistentEntities.get(type);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> PersistentEntity<T> addPersistentEntity(TypeInformation typeInformation) {
|
||||
|
||||
|
||||
PersistentEntity<?> persistentEntity = persistentEntities.get(typeInformation);
|
||||
|
||||
|
||||
if (persistentEntity != null) {
|
||||
return (PersistentEntity<T>) persistentEntity;
|
||||
}
|
||||
|
||||
|
||||
Class<T> type = (Class<T>) typeInformation.getType();
|
||||
|
||||
|
||||
try {
|
||||
final PersistentEntity<T> entity = builder.createPersistentEntity(typeInformation, this);
|
||||
BeanInfo info = Introspector.getBeanInfo(type);
|
||||
@@ -125,7 +143,7 @@ public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
if (property.isIdProperty()) {
|
||||
entity.setIdProperty(property);
|
||||
}
|
||||
|
||||
|
||||
if (property.isComplexType() && !property.isTransient()) {
|
||||
addPersistentEntity(property.getTypeInformation());
|
||||
}
|
||||
@@ -139,16 +157,9 @@ public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
entity.setPreferredConstructor(builder.getPreferredConstructor(type));
|
||||
|
||||
// Inform listeners
|
||||
List<Listener> listenersToRemove = new ArrayList<Listener>();
|
||||
for (Listener listener : listeners) {
|
||||
if (!listener.persistentEntityAdded(entity)) {
|
||||
listenersToRemove.add(listener);
|
||||
}
|
||||
}
|
||||
for (Listener listener : listenersToRemove) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
applicationContext.publishEvent(new MappingContextEvent(entity));
|
||||
|
||||
// Cache
|
||||
persistentEntities.put(entity.getPropertyInformation(), entity);
|
||||
|
||||
return entity;
|
||||
@@ -157,7 +168,7 @@ public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
} catch (IntrospectionException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -220,11 +231,6 @@ public class BasicMappingContext implements MappingContext, InitializingBean {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContextListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(builder, "No mapping configuration provider configured.");
|
||||
|
||||
@@ -16,14 +16,17 @@
|
||||
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import org.springframework.data.mapping.model.*;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.mapping.model.MappingContext;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.PreferredConstructor;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@@ -37,8 +40,9 @@ public class BasicPersistentEntity<T> implements PersistentEntity<T> {
|
||||
protected final TypeInformation information;
|
||||
|
||||
protected MappingContext mappingContext;
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public BasicPersistentEntity(MappingContext mappingContext, TypeInformation information) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.type = (Class<T>) information.getType();
|
||||
@@ -98,7 +102,7 @@ public class BasicPersistentEntity<T> implements PersistentEntity<T> {
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TypeInformation getPropertyInformation() {
|
||||
return information;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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.springframework.data.mapping.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MappingContextEvent extends ApplicationEvent {
|
||||
|
||||
public MappingContextEvent(PersistentEntity source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentEntity getSource() {
|
||||
return (PersistentEntity) super.getSource();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,9 @@
|
||||
*/
|
||||
package org.springframework.data.mapping.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -21,9 +24,6 @@ import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>This interface defines the overall context including all known
|
||||
* PersistentEntity instances and methods to obtain instances on demand</p>
|
||||
@@ -47,7 +47,7 @@ public interface MappingContext extends InitializingBean {
|
||||
* @return A list of PersistentEntity instances
|
||||
*/
|
||||
Collection<PersistentEntity<?>> getPersistentEntities();
|
||||
|
||||
|
||||
<T> PersistentEntity<T> getPersistentEntity(Class<T> type);
|
||||
|
||||
<T> PersistentEntity<T> getPersistentEntity(TypeInformation type);
|
||||
@@ -109,18 +109,4 @@ public interface MappingContext extends InitializingBean {
|
||||
*/
|
||||
boolean isPersistentEntity(Object value);
|
||||
|
||||
void addContextListener(Listener listener);
|
||||
|
||||
/**
|
||||
* Listener interface to deal with newly-added persistent entities.
|
||||
*/
|
||||
public interface Listener {
|
||||
/**
|
||||
* Handle this new entity, return true or false, depending on whether this listener should continue listening.
|
||||
*
|
||||
* @param entity
|
||||
* @return 'true' to leave listener attached, 'false' to remove this listener
|
||||
*/
|
||||
boolean persistentEntityAdded(PersistentEntity<?> entity);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user