Added mapping support to commons core. Will be used by other spring-data projects for multi-store mapping.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,3 +2,7 @@ target
|
||||
.springBeans
|
||||
.ant-targets-build.xml
|
||||
src/ant/.ant-targets-upload-dist.xml
|
||||
.DS_Store
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
@@ -1,79 +1,83 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-parent</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-commons-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data Commons Core</name>
|
||||
<dependencies>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-parent</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-commons-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data Commons Core</name>
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>1.6</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>1.6</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author J. Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.FIELD})
|
||||
public @interface Id {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.CONSTRUCTOR)
|
||||
public @interface PersistenceConstructor {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author J. Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {
|
||||
ElementType.TYPE,
|
||||
ElementType.ANNOTATION_TYPE,
|
||||
ElementType.FIELD,
|
||||
ElementType.PARAMETER
|
||||
})
|
||||
public @interface Persistent {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ElementType.ANNOTATION_TYPE,
|
||||
ElementType.FIELD
|
||||
})
|
||||
public @interface Reference {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author J. Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Transient {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public interface AssociationHandler {
|
||||
void doWithAssociation(Association association);
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.data.annotation.*;
|
||||
import org.springframework.data.mapping.model.*;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class BasicMappingConfigurationBuilder implements MappingConfigurationBuilder {
|
||||
|
||||
protected static ConcurrentMap<Class<?>, BeanInfo> beanInfo = new ConcurrentHashMap<Class<?>, BeanInfo>();
|
||||
protected Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected MappingContext mappingContext;
|
||||
|
||||
public BasicMappingConfigurationBuilder(MappingContext mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean isPersistentEntity(Class<T> type) {
|
||||
if (type.isAnnotationPresent(Persistent.class)) {
|
||||
return true;
|
||||
} else {
|
||||
for (Annotation annotation : type.getDeclaredAnnotations()) {
|
||||
if (annotation.annotationType().isAnnotationPresent(Persistent.class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(Id.class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public <T> PersistentEntity<T> createPersistentEntity(Class<T> type) throws MappingConfigurationException {
|
||||
return new BasicPersistentEntity<T>(mappingContext, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistentProperty(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException {
|
||||
if ("class".equals(field.getName()) || isTransient(field)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public PersistentProperty<?> createPersistentProperty(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException {
|
||||
return new BasicPersistentProperty(field.getName(), field.getType(), field, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> PersistentProperty<?> getIdProperty(Class<T> type) throws MappingConfigurationException {
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (isIdField(field)) {
|
||||
return createPersistentProperty(field, null);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public <T> PreferredConstructor<T> getPreferredConstructor(Class<T> type) throws MappingConfigurationException {
|
||||
// Find the right constructor
|
||||
PreferredConstructor<T> preferredConstructor = null;
|
||||
|
||||
for (Constructor<?> constructor : type.getConstructors()) {
|
||||
if (constructor.getParameterTypes().length != 0) {
|
||||
// Non-no-arg constructor
|
||||
if (null == preferredConstructor || constructor.isAnnotationPresent(PersistenceConstructor.class)) {
|
||||
preferredConstructor = new PreferredConstructor<T>((Constructor<T>) constructor);
|
||||
|
||||
String[] paramNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(constructor);
|
||||
Type[] paramTypes = constructor.getGenericParameterTypes();
|
||||
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
Class<?> targetType = Object.class;
|
||||
if (paramTypes[i] instanceof ParameterizedType) {
|
||||
ParameterizedType ptype = (ParameterizedType) paramTypes[i];
|
||||
Type[] types = ptype.getActualTypeArguments();
|
||||
if (types.length == 1) {
|
||||
if (types[0] instanceof TypeVariable) {
|
||||
// Placeholder type
|
||||
targetType = Object.class;
|
||||
} else {
|
||||
targetType = (Class<?>) types[0];
|
||||
}
|
||||
} else {
|
||||
targetType = (Class<?>) ptype.getRawType();
|
||||
}
|
||||
} else {
|
||||
if (paramTypes[i] instanceof TypeVariable) {
|
||||
Type[] bounds = ((TypeVariable) paramTypes[i]).getBounds();
|
||||
if (bounds.length > 0) {
|
||||
targetType = (Class<?>) bounds[0];
|
||||
}
|
||||
} else if (paramTypes[i] instanceof Class<?>) {
|
||||
targetType = (Class<?>) paramTypes[i];
|
||||
}
|
||||
}
|
||||
preferredConstructor.addParameter(paramNames[i], targetType, targetType.getDeclaredAnnotations());
|
||||
}
|
||||
|
||||
if (constructor.isAnnotationPresent(PersistenceConstructor.class)) {
|
||||
// We're done
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return preferredConstructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssociation(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException {
|
||||
if (!isTransient(field)) {
|
||||
if (field.isAnnotationPresent(Reference.class)) {
|
||||
return true;
|
||||
}
|
||||
for (Annotation annotation : field.getDeclaredAnnotations()) {
|
||||
if (annotation.annotationType().isAnnotationPresent(Reference.class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association createAssociation(PersistentProperty<?> property) {
|
||||
// Only support uni-directional associations in the Basic configuration
|
||||
Association association = new Association(property, null);
|
||||
property.setAssociation(association);
|
||||
|
||||
return association;
|
||||
}
|
||||
|
||||
protected BeanInfo getBeanInfo(Class<?> type) {
|
||||
BeanInfo info = beanInfo.get(type);
|
||||
if (null == info) {
|
||||
try {
|
||||
info = Introspector.getBeanInfo(type);
|
||||
} catch (IntrospectionException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
beanInfo.put(type, info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
protected boolean isTransient(Field field) {
|
||||
if (Modifier.isTransient(field.getModifiers())
|
||||
|| null != field.getAnnotation(Transient.class)
|
||||
|| null != field.getAnnotation(Value.class)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isIdField(Field field) {
|
||||
if (field.isAnnotationPresent(Id.class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (field.getType() == String.class || field.getType() == BigInteger.class) {
|
||||
if ("id".equals(field.getName()) || "_id".equals(field.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
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.util.Assert;
|
||||
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 {
|
||||
|
||||
protected Logger log = LoggerFactory.getLogger(getClass());
|
||||
protected MappingConfigurationBuilder builder;
|
||||
protected ConcurrentMap<String, PersistentEntity<?>> persistentEntities = new ConcurrentHashMap<String, 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() {
|
||||
builder = new BasicMappingConfigurationBuilder(this);
|
||||
}
|
||||
|
||||
public BasicMappingContext(MappingConfigurationBuilder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public BasicMappingContext(MappingConfigurationBuilder builder, GenericConversionService conversionService) {
|
||||
this.builder = builder;
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PersistentEntity<?>> getPersistentEntities() {
|
||||
return persistentEntities.values();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public <T> PersistentEntity<T> getPersistentEntity(Class<T> type) {
|
||||
return (PersistentEntity<T>) persistentEntities.get(type.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentEntity<?> getPersistentEntity(String name) {
|
||||
return persistentEntities.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> PersistentEntity<T> addPersistentEntity(Class<T> type) {
|
||||
if (null == persistentEntities.get(type.getName())) {
|
||||
try {
|
||||
PersistentEntity<T> entity = builder.createPersistentEntity(type);
|
||||
BeanInfo info = Introspector.getBeanInfo(type);
|
||||
|
||||
Map<String, PropertyDescriptor> descriptors = new HashMap<String, PropertyDescriptor>();
|
||||
for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) {
|
||||
descriptors.put(descriptor.getName(), descriptor);
|
||||
}
|
||||
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
PropertyDescriptor descriptor = descriptors.get(field.getName());
|
||||
if (builder.isPersistentProperty(field, descriptor)) {
|
||||
PersistentProperty<?> property = builder.createPersistentProperty(field, descriptor);
|
||||
property.setOwner(entity);
|
||||
entity.addPersistentProperty(property);
|
||||
if (builder.isAssociation(field, descriptor)) {
|
||||
Association association = builder.createAssociation(property);
|
||||
entity.addAssociation(association);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entity.setIdProperty(builder.getIdProperty(type));
|
||||
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);
|
||||
}
|
||||
|
||||
persistentEntities.put(type.getName(), entity);
|
||||
|
||||
return entity;
|
||||
} catch (MappingConfigurationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (IntrospectionException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityValidator(PersistentEntity<?> entity, Validator validator) {
|
||||
List<Validator> v = validators.get(entity);
|
||||
if (null == v) {
|
||||
v = new ArrayList<Validator>();
|
||||
validators.put(entity, v);
|
||||
}
|
||||
v.add(validator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, T> void addTypeConverter(Converter<S, T> converter) {
|
||||
conversionService.addConverter(converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConverterRegistry getConverterRegistry() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Validator> getEntityValidators(PersistentEntity<?> entity) {
|
||||
return validators.get(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingConfigurationBuilder getMappingConfigurationBuilder() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMappingConfigurationBuilder(MappingConfigurationBuilder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public boolean isPersistentEntity(Object value) {
|
||||
if (null != value) {
|
||||
Class clazz;
|
||||
if (value instanceof Class) {
|
||||
clazz = ((Class) value);
|
||||
} else {
|
||||
clazz = value.getClass();
|
||||
}
|
||||
return builder.isPersistentEntity(clazz);
|
||||
}
|
||||
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.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.mapping.model.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class BasicPersistentEntity<T> implements PersistentEntity {
|
||||
|
||||
protected final Class<T> type;
|
||||
protected PreferredConstructor<T> preferredConstructor;
|
||||
protected PersistentProperty<?> idProperty;
|
||||
protected Map<String, PersistentProperty<?>> persistentProperties = new HashMap<String, PersistentProperty<?>>();
|
||||
protected Map<String, Association> associations = new HashMap<String, Association>();
|
||||
|
||||
protected MappingContext mappingContext;
|
||||
|
||||
public BasicPersistentEntity(MappingContext mappingContext, Class<T> type) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferredConstructor getPreferredConstructor() {
|
||||
return preferredConstructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreferredConstructor(PreferredConstructor constructor) {
|
||||
this.preferredConstructor = constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return type.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentProperty<?> getIdProperty() {
|
||||
return idProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdProperty(PersistentProperty property) {
|
||||
idProperty = property;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PersistentProperty<?>> getPersistentProperties() {
|
||||
return persistentProperties.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPersistentProperty(PersistentProperty property) {
|
||||
persistentProperties.put(property.getName(), property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Association> getAssociations() {
|
||||
return associations.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAssociation(Association association) {
|
||||
associations.put(association.getInverse().getName(), association);
|
||||
}
|
||||
|
||||
public PersistentProperty getPersistentProperty(String name) {
|
||||
return persistentProperties.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getPersistentPropertyNames() {
|
||||
return persistentProperties.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingContext getMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWithProperties(PropertyHandler handler) {
|
||||
for (PersistentProperty<?> property : persistentProperties.values()) {
|
||||
if (!property.isTransient() && !property.isAssociation()) {
|
||||
handler.doWithPersistentProperty(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWithAssociations(AssociationHandler handler) {
|
||||
for (Association association : associations.values()) {
|
||||
handler.doWithAssociation(association);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class BasicPersistentProperty<T> implements PersistentProperty {
|
||||
|
||||
protected final String name;
|
||||
protected final Class<T> type;
|
||||
protected final PropertyDescriptor propertyDescriptor;
|
||||
protected final Field field;
|
||||
protected Association association;
|
||||
protected Value value;
|
||||
protected boolean isTransient = false;
|
||||
protected PersistentEntity<?> owner;
|
||||
|
||||
public BasicPersistentProperty(String name,
|
||||
Class<T> type,
|
||||
Field field,
|
||||
PropertyDescriptor propertyDescriptor) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.propertyDescriptor = propertyDescriptor;
|
||||
this.field = field;
|
||||
this.isTransient = Modifier.isTransient(field.getModifiers()) || field.isAnnotationPresent(Transient.class);
|
||||
if (field.isAnnotationPresent(Value.class)) {
|
||||
this.value = field.getAnnotation(Value.class);
|
||||
// Fields with @Value annotations are considered the same as transient fields
|
||||
this.isTransient = true;
|
||||
}
|
||||
if (field.isAnnotationPresent(Autowired.class)) {
|
||||
this.isTransient = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwner(Object owner) {
|
||||
if (null != owner && owner.getClass().isAssignableFrom(PersistentEntity.class)) {
|
||||
this.owner = (PersistentEntity<?>) owner;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor getPropertyDescriptor() {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValueAnnotation() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransient() {
|
||||
return isTransient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
return null != association;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association getAssociation() {
|
||||
return association;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAssociation(Association association) {
|
||||
this.association = association;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollection() {
|
||||
return type.isAssignableFrom(Collection.class) || type.isAssignableFrom(List.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplexType() {
|
||||
return !MappingBeanHelper.getSimpleTypes().contains(field.getType().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getComponentType() {
|
||||
if (isCollection()) {
|
||||
Type genericType = field.getGenericType();
|
||||
if (genericType instanceof ParameterizedType) {
|
||||
Type[] genericTypes = ((ParameterizedType) genericType).getActualTypeArguments();
|
||||
for (Type t : genericTypes) {
|
||||
if (t instanceof Class) {
|
||||
return (Class<?>) t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return type.getComponentType();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.PreferredConstructor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public abstract class MappingBeanHelper {
|
||||
|
||||
protected static GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
protected static SpelExpressionParser parser = new SpelExpressionParser();
|
||||
protected static Set<String> simpleTypes = new ConcurrentSkipListSet<String>() {{
|
||||
add(boolean.class.getName());
|
||||
add(long.class.getName());
|
||||
add(short.class.getName());
|
||||
add(int.class.getName());
|
||||
add(byte.class.getName());
|
||||
add(float.class.getName());
|
||||
add(double.class.getName());
|
||||
add(char.class.getName());
|
||||
add(Boolean.class.getName());
|
||||
add(Long.class.getName());
|
||||
add(Short.class.getName());
|
||||
add(Integer.class.getName());
|
||||
add(Byte.class.getName());
|
||||
add(Float.class.getName());
|
||||
add(Double.class.getName());
|
||||
add(Character.class.getName());
|
||||
add(String.class.getName());
|
||||
add(java.util.Date.class.getName());
|
||||
add(Locale.class.getName());
|
||||
add(Class.class.getName());
|
||||
}};
|
||||
|
||||
public static GenericConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
public static void setConversionService(GenericConversionService conversionService) {
|
||||
MappingBeanHelper.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public static Set<String> getSimpleTypes() {
|
||||
return simpleTypes;
|
||||
}
|
||||
|
||||
public static <T> T constructInstance(PersistentEntity<T> entity,
|
||||
PreferredConstructor.ParameterValueProvider provider) {
|
||||
return constructInstance(entity, provider, new StandardEvaluationContext());
|
||||
}
|
||||
|
||||
public static <T> T constructInstance(PersistentEntity<T> entity,
|
||||
PreferredConstructor.ParameterValueProvider provider,
|
||||
EvaluationContext spelCtx) {
|
||||
|
||||
PreferredConstructor<T> constructor = entity.getPreferredConstructor();
|
||||
if (null == constructor) {
|
||||
try {
|
||||
return entity.getType().newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> params = new LinkedList<Object>();
|
||||
if (null != provider && constructor.getParameters().size() > 0) {
|
||||
for (PreferredConstructor.Parameter parameter : constructor.getParameters()) {
|
||||
Value v = parameter.getValue();
|
||||
Object obj;
|
||||
if (null != v) {
|
||||
Expression x = parser.parseExpression(v.value());
|
||||
obj = x.getValue(spelCtx);
|
||||
} else {
|
||||
obj = provider.getParameterValue(parameter);
|
||||
}
|
||||
params.add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
T obj = null;
|
||||
try {
|
||||
obj = constructor.getConstructor().newInstance(params.toArray());
|
||||
} catch (InstantiationException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static void setProperty(Object on,
|
||||
PersistentProperty<?> property,
|
||||
Object value)
|
||||
throws IllegalAccessException, InvocationTargetException {
|
||||
setProperty(on, property, value, false);
|
||||
}
|
||||
|
||||
public static void setProperty(Object on,
|
||||
PersistentProperty<?> property,
|
||||
Object value,
|
||||
boolean fieldAccessOnly)
|
||||
throws IllegalAccessException, InvocationTargetException {
|
||||
|
||||
Field field = property.getField();
|
||||
if (fieldAccessOnly || (null == property.getPropertyDescriptor() || null == property.getPropertyDescriptor().getWriteMethod())) {
|
||||
field.setAccessible(true);
|
||||
if (null != value && value.getClass().isAssignableFrom(field.getType())) {
|
||||
field.set(on, value);
|
||||
} else {
|
||||
field.set(on, conversionService.convert(value, field.getType()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Method setter = property.getPropertyDescriptor().getWriteMethod();
|
||||
Class<?>[] paramTypes = setter.getParameterTypes();
|
||||
if (null != value && paramTypes.length > 0 && !value.getClass().isAssignableFrom(paramTypes[0])) {
|
||||
setter.invoke(on, conversionService.convert(value, paramTypes[0]));
|
||||
} else {
|
||||
setter.invoke(on, value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static <T> T getProperty(Object from,
|
||||
PersistentProperty<?> property,
|
||||
Class<T> type,
|
||||
boolean fieldAccessOnly)
|
||||
throws IllegalAccessException, InvocationTargetException {
|
||||
|
||||
Field field = property.getField();
|
||||
if (fieldAccessOnly || (null == property.getPropertyDescriptor() || null == property.getPropertyDescriptor().getReadMethod())) {
|
||||
field.setAccessible(true);
|
||||
Object obj = field.get(from);
|
||||
if (null != obj && !obj.getClass().isAssignableFrom(type)) {
|
||||
return conversionService.convert(obj, type);
|
||||
} else {
|
||||
return (T) obj;
|
||||
}
|
||||
}
|
||||
|
||||
Object obj = property.getPropertyDescriptor().getReadMethod().invoke(from);
|
||||
if (null != obj && !obj.getClass().isAssignableFrom(type)) {
|
||||
return conversionService.convert(obj, type);
|
||||
} else {
|
||||
return (T) obj;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public interface PropertyHandler {
|
||||
void doWithPersistentProperty(PersistentProperty<?> persistentProperty);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class Association {
|
||||
|
||||
protected PersistentProperty<?> inverse;
|
||||
protected PersistentProperty<?> obverse;
|
||||
|
||||
public Association(PersistentProperty<?> inverse, PersistentProperty<?> obverse) {
|
||||
this.inverse = inverse;
|
||||
this.obverse = obverse;
|
||||
}
|
||||
|
||||
public PersistentProperty<?> getInverse() {
|
||||
return inverse;
|
||||
}
|
||||
|
||||
public void setInverse(PersistentProperty<?> inverse) {
|
||||
this.inverse = inverse;
|
||||
}
|
||||
|
||||
public PersistentProperty<?> getObverse() {
|
||||
return obverse;
|
||||
}
|
||||
|
||||
public void setObverse(PersistentProperty<?> obverse) {
|
||||
this.obverse = obverse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Copyright (C) 2010 SpringSource
|
||||
*
|
||||
* 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.model;
|
||||
|
||||
/**
|
||||
* Thrown when an error occurs reading the mapping between object and datastore
|
||||
*
|
||||
* @author Graeme Rocher
|
||||
* @since 1.0
|
||||
*/
|
||||
public class IllegalMappingException extends RuntimeException {
|
||||
|
||||
public IllegalMappingException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
|
||||
public IllegalMappingException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public interface MappingConfigurationBuilder {
|
||||
|
||||
<T> boolean isPersistentEntity(Class<T> clazz);
|
||||
|
||||
<T> PersistentEntity<T> createPersistentEntity(Class<T> clazz) throws MappingConfigurationException;
|
||||
|
||||
boolean isPersistentProperty(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException;
|
||||
|
||||
PersistentProperty<?> createPersistentProperty(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException;
|
||||
|
||||
<T> PersistentProperty<?> getIdProperty(Class<T> clazz) throws MappingConfigurationException;
|
||||
|
||||
<T> PreferredConstructor<?> getPreferredConstructor(Class<T> clazz) throws MappingConfigurationException;
|
||||
|
||||
boolean isAssociation(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException;
|
||||
|
||||
Association createAssociation(PersistentProperty<?> property);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MappingConfigurationException extends Throwable {
|
||||
public MappingConfigurationException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public MappingConfigurationException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/* Copyright 2004-2005 the original author or authors.
|
||||
*
|
||||
* 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.model;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
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>
|
||||
* <p/>
|
||||
* <p>This interface is used internally to establish associations
|
||||
* between entities and also at runtime to obtain entities by name</p>
|
||||
* <p/>
|
||||
* <p>The generic type parameters T & R are used to specify the
|
||||
* mapped form of a class (example Table) and property (example Column) respectively.</p>
|
||||
* <p/>
|
||||
*
|
||||
* @author Graeme Rocher
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface MappingContext extends InitializingBean {
|
||||
|
||||
|
||||
/**
|
||||
* Obtains a list of PersistentEntity instances
|
||||
*
|
||||
* @return A list of PersistentEntity instances
|
||||
*/
|
||||
Collection<PersistentEntity<?>> getPersistentEntities();
|
||||
|
||||
/**
|
||||
* Obtains a PersistentEntity by name
|
||||
*
|
||||
* @param name The name of the entity
|
||||
* @return The entity or null
|
||||
*/
|
||||
PersistentEntity<?> getPersistentEntity(String name);
|
||||
|
||||
<T> PersistentEntity<T> getPersistentEntity(Class<T> type);
|
||||
|
||||
/**
|
||||
* Adds a PersistentEntity instance
|
||||
*
|
||||
* @param type The Java class representing the entity
|
||||
* @return The PersistentEntity instance
|
||||
*/
|
||||
<T> PersistentEntity<T> addPersistentEntity(Class<T> type);
|
||||
|
||||
/**
|
||||
* Adds a validator to be used by the entity for validation
|
||||
*
|
||||
* @param entity The PersistentEntity
|
||||
* @param validator The validator
|
||||
*/
|
||||
void addEntityValidator(PersistentEntity<?> entity, Validator validator);
|
||||
|
||||
/**
|
||||
* Add a converter used to convert property values to and from the datastore
|
||||
*
|
||||
* @param converter The converter to add
|
||||
*/
|
||||
<S, T> void addTypeConverter(Converter<S, T> converter);
|
||||
|
||||
/**
|
||||
* Obtains the ConversionService instance to use for type conversion
|
||||
*
|
||||
* @return The conversion service instance
|
||||
*/
|
||||
ConversionService getConversionService();
|
||||
|
||||
/**
|
||||
* Obtains the converter registry
|
||||
*
|
||||
* @return The converter registry used for type conversion
|
||||
*/
|
||||
ConverterRegistry getConverterRegistry();
|
||||
|
||||
/**
|
||||
* Obtains a validator for the given entity
|
||||
*
|
||||
* @param entity The entity
|
||||
* @return A validator or null if none exists for the given entity
|
||||
*/
|
||||
List<Validator> getEntityValidators(PersistentEntity<?> entity);
|
||||
|
||||
MappingConfigurationBuilder getMappingConfigurationBuilder();
|
||||
|
||||
void setMappingConfigurationBuilder(MappingConfigurationBuilder builder);
|
||||
|
||||
/**
|
||||
* Returns whether the specified value is a persistent entity
|
||||
*
|
||||
* @param value The value to check
|
||||
* @return True if it is
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MappingException extends RuntimeException {
|
||||
public MappingException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public MappingException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: jbrisbin
|
||||
* Date: 2/25/11
|
||||
* Time: 9:07 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class MappingInstantiationException extends RuntimeException {
|
||||
public MappingInstantiationException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.springframework.data.mapping.model;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a persistent entity
|
||||
*
|
||||
* @author Graeme Rocher
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface PersistentEntity<T> extends InitializingBean {
|
||||
|
||||
/**
|
||||
* The entity name including any package prefix
|
||||
*
|
||||
* @return The entity name
|
||||
*/
|
||||
String getName();
|
||||
|
||||
PreferredConstructor<T> getPreferredConstructor();
|
||||
|
||||
void setPreferredConstructor(PreferredConstructor constructor);
|
||||
|
||||
/**
|
||||
* Returns the identity of the instance
|
||||
*
|
||||
* @return The identity
|
||||
*/
|
||||
PersistentProperty<?> getIdProperty();
|
||||
|
||||
void setIdProperty(PersistentProperty<?> property);
|
||||
|
||||
/**
|
||||
* A list of properties to be persisted
|
||||
*
|
||||
* @return A list of PersistentProperty instances
|
||||
*/
|
||||
Collection<PersistentProperty<?>> getPersistentProperties();
|
||||
|
||||
void addPersistentProperty(PersistentProperty<?> property);
|
||||
|
||||
/**
|
||||
* A list of the associations for this entity. This is typically a subset of the list returned by {@link #getPersistentProperties()}
|
||||
*
|
||||
* @return A list of associations
|
||||
*/
|
||||
Collection<Association> getAssociations();
|
||||
|
||||
void addAssociation(Association association);
|
||||
|
||||
/**
|
||||
* Obtains a PersistentProperty instance by name
|
||||
*
|
||||
* @param name The name of the property
|
||||
* @return The PersistentProperty or null if it doesn't exist
|
||||
*/
|
||||
PersistentProperty<?> getPersistentProperty(String name);
|
||||
|
||||
/**
|
||||
* @return The underlying Java class for this entity
|
||||
*/
|
||||
Class<T> getType();
|
||||
|
||||
/**
|
||||
* A list of property names
|
||||
*
|
||||
* @return A List of strings
|
||||
*/
|
||||
Collection<String> getPersistentPropertyNames();
|
||||
|
||||
/**
|
||||
* Obtains the MappingContext where this PersistentEntity is defined
|
||||
*
|
||||
* @return The MappingContext instance
|
||||
*/
|
||||
MappingContext getMappingContext();
|
||||
|
||||
void doWithProperties(PropertyHandler handler);
|
||||
|
||||
void doWithAssociations(AssociationHandler handler);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.springframework.data.mapping.model;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Graeme Rocher
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface PersistentProperty<T> {
|
||||
|
||||
Object getOwner();
|
||||
|
||||
void setOwner(Object owner);
|
||||
|
||||
/**
|
||||
* The name of the property
|
||||
*
|
||||
* @return The property name
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* The type of the property
|
||||
*
|
||||
* @return The property type
|
||||
*/
|
||||
Class<T> getType();
|
||||
|
||||
PropertyDescriptor getPropertyDescriptor();
|
||||
|
||||
Field getField();
|
||||
|
||||
Value getValueAnnotation();
|
||||
|
||||
boolean isTransient();
|
||||
|
||||
boolean isAssociation();
|
||||
|
||||
Association getAssociation();
|
||||
|
||||
void setAssociation(Association association);
|
||||
|
||||
boolean isCollection();
|
||||
|
||||
boolean isComplexType();
|
||||
|
||||
Class<?> getComponentType();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PreferredConstructor<T> {
|
||||
|
||||
protected Constructor<T> constructor;
|
||||
protected List<Parameter> parameters = new LinkedList<Parameter>();
|
||||
|
||||
public PreferredConstructor(Constructor<T> constructor) {
|
||||
this.constructor = constructor;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public Constructor<T> getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
public List<Parameter> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void addParameter(String name, Class<?> type, Annotation[] annotations) {
|
||||
parameters.add(new Parameter(name, type, annotations));
|
||||
}
|
||||
|
||||
public static class Parameter {
|
||||
protected final String name;
|
||||
protected final Class<?> type;
|
||||
protected final Annotation[] annotations;
|
||||
protected Value value;
|
||||
|
||||
public Parameter(String name, Class<?> type, Annotation[] annotations) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.annotations = annotations;
|
||||
for (Annotation anno : annotations) {
|
||||
if (anno.annotationType() == Value.class) {
|
||||
this.value = (Value) anno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Annotation[] getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface ParameterValueProvider {
|
||||
Object getParameterValue(Parameter parameter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Persistent
|
||||
public class Child extends PersonWithId {
|
||||
|
||||
public Child(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ElementType.TYPE,
|
||||
ElementType.FIELD
|
||||
})
|
||||
@Persistent
|
||||
public @interface Document {
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:mapping.xml")
|
||||
public class MappingMetadataTests {
|
||||
|
||||
BasicMappingContext ctx;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
ctx = new BasicMappingContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesRecognizePersistentEntities() {
|
||||
boolean persistentEntity = ctx.isPersistentEntity(PersonNoId.class);
|
||||
assertFalse(persistentEntity);
|
||||
|
||||
persistentEntity = ctx.isPersistentEntity(PersonPersistent.class);
|
||||
assertTrue(persistentEntity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPojoWithId() {
|
||||
PersistentEntity<PersonWithId> person = ctx.addPersistentEntity(PersonWithId.class);
|
||||
assertNotNull(person.getIdProperty());
|
||||
assertEquals(String.class, person.getIdProperty().getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPojoWithoutId() {
|
||||
PersistentEntity<PersonNoId> person = ctx.addPersistentEntity(PersonNoId.class);
|
||||
assertNull(person.getIdProperty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssociations() {
|
||||
PersistentEntity<PersonWithChildren> person = ctx.addPersistentEntity(PersonWithChildren.class);
|
||||
assertNotNull(person.getAssociations());
|
||||
|
||||
for (Association association : person.getAssociations()) {
|
||||
assertEquals(Child.class, association.getInverse().getComponentType());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesRecognizeDocumentEntities() {
|
||||
// PersistentEntity<PersonDocument> person = ctx.addPersistentEntity(PersonDocument.class);
|
||||
boolean persistentEntity = ctx.isPersistentEntity(PersonDocument.class);
|
||||
assertTrue(persistentEntity);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public abstract class Person {
|
||||
|
||||
private Integer ssn;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
protected Person(Integer ssn, String firstName, String lastName) {
|
||||
this.ssn = ssn;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Integer getSsn() {
|
||||
return ssn;
|
||||
}
|
||||
|
||||
public void setSsn(Integer ssn) {
|
||||
this.ssn = ssn;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document
|
||||
public class PersonDocument extends Person {
|
||||
|
||||
public PersonDocument(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PersonNoId extends Person {
|
||||
|
||||
public PersonNoId(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Persistent
|
||||
public class PersonPersistent extends PersonWithId {
|
||||
|
||||
public PersonPersistent(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.annotation.Reference;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PersonWithChildren extends Person {
|
||||
|
||||
@Reference
|
||||
private List<Child> children;
|
||||
|
||||
public PersonWithChildren(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Child> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PersonWithId extends Person {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
public PersonWithId(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
22
spring-data-commons-core/src/test/resources/log4j.xml
Normal file
22
spring-data-commons-core/src/test/resources/log4j.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d %-5p %c{1} - %m%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<category name="org.springframework.data.mapping">
|
||||
<level value="DEBUG"/>
|
||||
</category>
|
||||
<category name="org.springframework">
|
||||
<level value="WARN"/>
|
||||
</category>
|
||||
|
||||
<root>
|
||||
<appender-ref ref="console"/>
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
||||
7
spring-data-commons-core/src/test/resources/mapping.xml
Normal file
7
spring-data-commons-core/src/test/resources/mapping.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
</beans>
|
||||
@@ -11,7 +11,11 @@ Import-Template:
|
||||
org.springframework.context.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.dao.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.util.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.spel.standard.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.spel.support.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.transaction.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.validation.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.data.core.*;version="[1.0.0, 2.0.0)",
|
||||
org.springframework.data.persistence.*;version="[1.0.0, 2.0.0)",
|
||||
org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
|
||||
Reference in New Issue
Block a user