DATACMNS-266 - Use new common Maven build infrastructure.
Simplified project setup to be a single module build again. Using Spring Data Build parent POM to simplify project setup. See https://github.com/SpringSource/spring-data-build#spring-data-build-infrastructure
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2011-12 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.convert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link TypeInformationMapper} implementation that can be either set up using a {@link MappingContext} or manually set
|
||||
* up {@link Map} of {@link String} aliases to types. If a {@link MappingContext} is used the {@link Map} will be build
|
||||
* inspecting the {@link PersistentEntity} instances for type alias information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class ConfigurableTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
private final Map<TypeInformation<?>, Object> typeMap;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConfigurableTypeMapper} for the given type map.
|
||||
*
|
||||
* @param sourceTypeMap must not be {@literal null}.
|
||||
*/
|
||||
public ConfigurableTypeInformationMapper(Map<? extends Class<?>, String> sourceTypeMap) {
|
||||
|
||||
Assert.notNull(sourceTypeMap);
|
||||
this.typeMap = new HashMap<TypeInformation<?>, Object>(sourceTypeMap.size());
|
||||
|
||||
for (Entry<? extends Class<?>, String> entry : sourceTypeMap.entrySet()) {
|
||||
TypeInformation<?> key = ClassTypeInformation.from(entry.getKey());
|
||||
String value = entry.getValue();
|
||||
|
||||
if (typeMap.containsValue(value)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Detected mapping ambiguity! String %s cannot be mapped to more than one type!", value));
|
||||
}
|
||||
|
||||
this.typeMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
public Object createAliasFor(TypeInformation<?> type) {
|
||||
return typeMap.get(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2011-2013 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.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link MongoTypeMapper} allowing configuration of the key to lookup and store type
|
||||
* information in {@link DBObject}. The key defaults to {@link #DEFAULT_TYPE_KEY}. Actual type-to-{@link String}
|
||||
* conversion and back is done in {@link #getTypeString(TypeInformation)} or {@link #getTypeInformation(String)}
|
||||
* respectively.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DefaultTypeMapper<S> implements TypeMapper<S> {
|
||||
|
||||
private final TypeAliasAccessor<S> accessor;
|
||||
private final List<? extends TypeInformationMapper> mappers;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor}. It will use a
|
||||
* {@link SimpleTypeInformationMapper} to calculate type aliases.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
*/
|
||||
public DefaultTypeMapper(TypeAliasAccessor<S> accessor) {
|
||||
this(accessor, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor} and {@link TypeInformationMapper}
|
||||
* s.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param mappers must not be {@literal null}.
|
||||
*/
|
||||
public DefaultTypeMapper(TypeAliasAccessor<S> accessor, List<? extends TypeInformationMapper> mappers) {
|
||||
this(accessor, null, mappers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor}, {@link MappingContext} and
|
||||
* additional {@link TypeInformationMapper}s. Will register a {@link MappingContextTypeInformationMapper} before the
|
||||
* given additional mappers.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param mappingContext
|
||||
* @param additionalMappers must not be {@literal null}.
|
||||
*/
|
||||
public DefaultTypeMapper(TypeAliasAccessor<S> accessor,
|
||||
MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext,
|
||||
List<? extends TypeInformationMapper> additionalMappers) {
|
||||
|
||||
Assert.notNull(accessor);
|
||||
Assert.notNull(additionalMappers);
|
||||
|
||||
List<TypeInformationMapper> mappers = new ArrayList<TypeInformationMapper>(additionalMappers.size() + 1);
|
||||
if (mappingContext != null) {
|
||||
mappers.add(new MappingContextTypeInformationMapper(mappingContext));
|
||||
}
|
||||
mappers.addAll(additionalMappers);
|
||||
|
||||
this.mappers = Collections.unmodifiableList(mappers);
|
||||
this.accessor = accessor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#readType(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> readType(S source) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Object alias = accessor.readAliasFrom(source);
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (TypeInformationMapper mapper : mappers) {
|
||||
TypeInformation<?> type = mapper.resolveTypeFrom(alias);
|
||||
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#readType(java.lang.Object, org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> TypeInformation<? extends T> readType(S source, TypeInformation<T> basicType) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Class<?> documentsTargetType = getDefaultedTypeToBeUsed(source);
|
||||
|
||||
if (documentsTargetType == null) {
|
||||
return basicType;
|
||||
}
|
||||
|
||||
Class<T> rawType = basicType == null ? null : basicType.getType();
|
||||
|
||||
boolean isMoreConcreteCustomType = rawType == null ? true : rawType.isAssignableFrom(documentsTargetType)
|
||||
&& !rawType.equals(documentsTargetType);
|
||||
return isMoreConcreteCustomType ? (TypeInformation<? extends T>) ClassTypeInformation.from(documentsTargetType)
|
||||
: basicType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type discovered through {@link #readType(Object)} but defaulted to the one returned by
|
||||
* {@link #getFallbackTypeFor(Object)}.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
private Class<?> getDefaultedTypeToBeUsed(S source) {
|
||||
|
||||
TypeInformation<?> documentsTargetTypeInformation = readType(source);
|
||||
documentsTargetTypeInformation = documentsTargetTypeInformation == null ? getFallbackTypeFor(source)
|
||||
: documentsTargetTypeInformation;
|
||||
return documentsTargetTypeInformation == null ? null : documentsTargetTypeInformation.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type fallback {@link TypeInformation} in case none could be extracted from the given source.
|
||||
*
|
||||
* @param source will never be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected TypeInformation<?> getFallbackTypeFor(S source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#writeType(java.lang.Class, java.lang.Object)
|
||||
*/
|
||||
public void writeType(Class<?> type, S dbObject) {
|
||||
writeType(ClassTypeInformation.from(type), dbObject);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#writeType(org.springframework.data.util.TypeInformation, java.lang.Object)
|
||||
*/
|
||||
public void writeType(TypeInformation<?> info, S sink) {
|
||||
|
||||
Assert.notNull(info);
|
||||
|
||||
for (TypeInformationMapper mapper : mappers) {
|
||||
Object alias = mapper.createAliasFor(info);
|
||||
if (alias != null) {
|
||||
accessor.writeTypeTo(sink, alias);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.convert;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
|
||||
/**
|
||||
* Combined {@link EntityReader} and {@link EntityWriter} and add the ability to access a {@link MappingContext} and
|
||||
* {@link ConversionService}.
|
||||
*
|
||||
* @param <E> the concrete {@link PersistentEntity} implementation the converter is based on.
|
||||
* @param <P> the concrete {@link PersistentProperty} implementation the converter is based on.
|
||||
* @param <T> the most common type the {@link EntityConverter} can actually convert.
|
||||
* @param <S> the store specific source and sink an {@link EntityConverter} can deal with.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityConverter<E extends PersistentEntity<?, P>, P extends PersistentProperty<P>, T, S> extends
|
||||
EntityReader<T, S>, EntityWriter<T, S> {
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link MappingContext} used by the converter.
|
||||
*
|
||||
* @return never {@literal null}
|
||||
*/
|
||||
MappingContext<? extends E, P> getMappingContext();
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link ConversionService} used by the converter.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
ConversionService getConversionService();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.convert;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
|
||||
/**
|
||||
* SPI to abstract strategies to create instances for {@link PersistentEntity}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityInstantiator {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the given entity using the given source to pull data from.
|
||||
*
|
||||
* @param entity will not be {@literal null}.
|
||||
* @param provider will not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
|
||||
ParameterValueProvider<P> provider);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012 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.convert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple value object allowing access to {@link EntityInstantiator} instances for a given type falling back to a
|
||||
* default one.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class EntityInstantiators {
|
||||
|
||||
private final EntityInstantiator fallback;
|
||||
private final Map<Class<?>, EntityInstantiator> customInstantiators;
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiators} using the default fallback instantiator and no custom ones.
|
||||
*/
|
||||
public EntityInstantiators() {
|
||||
this(Collections.<Class<?>, EntityInstantiator> emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiators} using the given {@link EntityInstantiator} as fallback.
|
||||
*
|
||||
* @param fallback must not be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiators(EntityInstantiator fallback) {
|
||||
this(fallback, Collections.<Class<?>, EntityInstantiator> emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiators} using the default fallback instantiator and the given custom ones.
|
||||
*
|
||||
* @param customInstantiators must not be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiators(Map<Class<?>, EntityInstantiator> customInstantiators) {
|
||||
this(ReflectionEntityInstantiator.INSTANCE, customInstantiators);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiator} using the given fallback {@link EntityInstantiator} and the given custom
|
||||
* ones.
|
||||
*
|
||||
* @param fallback must not be {@literal null}.
|
||||
* @param customInstantiators must not be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiators(EntityInstantiator defaultInstantiator,
|
||||
Map<Class<?>, EntityInstantiator> customInstantiators) {
|
||||
|
||||
Assert.notNull(defaultInstantiator);
|
||||
Assert.notNull(customInstantiators);
|
||||
|
||||
this.fallback = defaultInstantiator;
|
||||
this.customInstantiators = customInstantiators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link EntityInstantiator} to be used to create the given {@link PersistentEntity}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiator getInstantiatorFor(PersistentEntity<?, ?> entity) {
|
||||
|
||||
Assert.notNull(entity);
|
||||
Class<?> type = entity.getType();
|
||||
|
||||
if (!customInstantiators.containsKey(type)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
EntityInstantiator instantiator = customInstantiators.get(entity.getType());
|
||||
return instantiator == null ? fallback : instantiator;
|
||||
}
|
||||
}
|
||||
@@ -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.convert;
|
||||
|
||||
/**
|
||||
* Interface to read object from store specific sources.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityReader<T, S> {
|
||||
|
||||
/**
|
||||
* Reads the given source into the given type.
|
||||
*
|
||||
* @param type they type to convert the given source to.
|
||||
* @param source the source to create an object of the given type from.
|
||||
* @return
|
||||
*/
|
||||
<R extends T> R read(Class<R> type, S source);
|
||||
}
|
||||
@@ -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.convert;
|
||||
|
||||
/**
|
||||
* Interface to write objects into store specific sinks.
|
||||
*
|
||||
* @param <T> the entity type the converter can handle
|
||||
* @param <S> the store specific sink the converter is able to write to
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityWriter<T, S> {
|
||||
|
||||
void write(T source, S sink);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.convert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link TypeInformationMapper} implementation that can be either set up using a {@link MappingContext} or manually set
|
||||
* up {@link Map} of {@link String} aliases to types. If a {@link MappingContext} is used the {@link Map} will be build
|
||||
* inspecting the {@link PersistentEntity} instances for type alias information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingContextTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
private final Map<TypeInformation<?>, Object> typeMap;
|
||||
private final MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext;
|
||||
|
||||
/**
|
||||
* Creates a {@link MappingContextTypeInformationMapper} from the given {@link MappingContext}. Inspects all
|
||||
* {@link PersistentEntity} instances for alias information and builds a {@link Map} of aliases to types from it.
|
||||
*
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public MappingContextTypeInformationMapper(MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext) {
|
||||
|
||||
Assert.notNull(mappingContext);
|
||||
|
||||
this.typeMap = new HashMap<TypeInformation<?>, Object>();
|
||||
this.mappingContext = mappingContext;
|
||||
|
||||
for (PersistentEntity<?, ?> entity : mappingContext.getPersistentEntities()) {
|
||||
safelyAddToCache(entity.getTypeInformation(), entity.getTypeAlias());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
public Object createAliasFor(TypeInformation<?> type) {
|
||||
|
||||
Object key = typeMap.get(type);
|
||||
|
||||
if (key != null) {
|
||||
return key;
|
||||
}
|
||||
|
||||
PersistentEntity<?, ?> entity = mappingContext.getPersistentEntity(type);
|
||||
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object alias = entity.getTypeAlias();
|
||||
safelyAddToCache(type, alias);
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given alias to the cache in a {@literal null}-safe manner.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param alias can be {@literal null}.
|
||||
*/
|
||||
private void safelyAddToCache(TypeInformation<?> key, Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeMap.containsValue(alias)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Detected mapping ambiguity! String %s cannot be mapped to more than one type!", alias));
|
||||
}
|
||||
|
||||
typeMap.put(key, alias);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
for (PersistentEntity<?, ?> entity : mappingContext.getPersistentEntities()) {
|
||||
if (alias.equals(entity.getTypeAlias())) {
|
||||
return entity.getTypeInformation();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011 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.convert;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Annotation to clarify intended usage of a {@link Converter} as reading converter in case the conversion types leave
|
||||
* room for disambiguation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Target(TYPE)
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ReadingConverter {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.convert;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
|
||||
/**
|
||||
* {@link EntityInstantiator} that uses the {@link PersistentEntity}'s {@link PreferredConstructor} to instantiate an
|
||||
* instance of the entity via reflection.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public enum ReflectionEntityInstantiator implements EntityInstantiator {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
|
||||
ParameterValueProvider<P> provider) {
|
||||
|
||||
PreferredConstructor<? extends T, P> constructor = entity.getPersistenceConstructor();
|
||||
|
||||
if (constructor == null) {
|
||||
|
||||
try {
|
||||
Class<?> clazz = entity.getType();
|
||||
if (clazz.isArray()) {
|
||||
Class<?> ctype = clazz;
|
||||
int dims = 0;
|
||||
while (ctype.isArray()) {
|
||||
ctype = ctype.getComponentType();
|
||||
dims++;
|
||||
}
|
||||
return (T) Array.newInstance(clazz, dims);
|
||||
} else {
|
||||
return BeanUtils.instantiateClass(entity.getType());
|
||||
}
|
||||
} catch (BeanInstantiationException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
if (null != provider && constructor.hasParameters()) {
|
||||
for (Parameter<?, P> parameter : constructor.getParameters()) {
|
||||
params.add(provider.getParameterValue(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return BeanUtils.instantiateClass(constructor.getConstructor(), params.toArray());
|
||||
} catch (BeanInstantiationException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2011 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.convert;
|
||||
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Basic {@link TypeInformationMapper} implementation that interprets the alias handles as fully qualified class name
|
||||
* and tries to load a class with the given name to build {@link TypeInformation}. Returns the fully qualified class
|
||||
* name for alias creation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
public static final SimpleTypeInformationMapper INSTANCE = new SimpleTypeInformationMapper();
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} that shall be used when the given {@link String} value is found as type hint.
|
||||
* The implementation will simply interpret the given value as fully-qualified class name and try to load the class.
|
||||
* Will return {@literal null} in case the given {@link String} is empty.
|
||||
*
|
||||
* @param value the type to load, must not be {@literal null}.
|
||||
* @return the type to be used for the given {@link String} representation or {@literal null} if nothing found or the
|
||||
* class cannot be loaded.
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (!(alias instanceof String)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String value = (String) alias;
|
||||
|
||||
if (!StringUtils.hasText(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return ClassTypeInformation.from(ClassUtils.forName(value, null));
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the given type information into the String representation that shall be stored. Default implementation simply
|
||||
* returns the fully-qualified class name.
|
||||
*
|
||||
* @param typeInformation must not be {@literal null}.
|
||||
* @return the String representation to be stored or {@literal null} if no type information shall be stored.
|
||||
*/
|
||||
public String createAliasFor(TypeInformation<?> type) {
|
||||
|
||||
return type.getType().getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2011 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.convert;
|
||||
|
||||
/**
|
||||
* Interface to abstract implementations of how to access a type alias from a given source or sink.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TypeAliasAccessor<S> {
|
||||
|
||||
/**
|
||||
* Reads the type alias to be used from the given source.
|
||||
*
|
||||
* @param source
|
||||
* @return can be {@literal null} in case no alias was found.
|
||||
*/
|
||||
Object readAliasFrom(S source);
|
||||
|
||||
/**
|
||||
* Writes the given type alias to the given sink.
|
||||
*
|
||||
* @param sink
|
||||
* @param alias
|
||||
*/
|
||||
void writeTypeTo(S sink, Object alias);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2011 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.convert;
|
||||
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Interface to abstract the mapping from a type alias to the actual type.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TypeInformationMapper {
|
||||
|
||||
/**
|
||||
* Returns the actual {@link TypeInformation} to be used for the given alias.
|
||||
*
|
||||
* @param alias can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
TypeInformation<?> resolveTypeFrom(Object alias);
|
||||
|
||||
/**
|
||||
* Returns the alias to be used for the given {@link TypeInformation}.
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
Object createAliasFor(TypeInformation<?> type);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2011 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.convert;
|
||||
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Interface to define strategies how to store type information in a store specific sink or source.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TypeMapper<S> {
|
||||
|
||||
/**
|
||||
* Reads the {@link TypeInformation} from the given source.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
TypeInformation<?> readType(S source);
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} from the given source if it is a more concrete type than the given default one.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param defaultType
|
||||
* @return
|
||||
*/
|
||||
<T> TypeInformation<? extends T> readType(S source, TypeInformation<T> defaultType);
|
||||
|
||||
/**
|
||||
* Writes type information for the given type into the given sink.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param dbObject must not be {@literal null}.
|
||||
*/
|
||||
void writeType(Class<?> type, S dbObject);
|
||||
|
||||
/**
|
||||
* Writes type information for the given {@link TypeInformation} into the given sink.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param dbObject must not be {@literal null}.
|
||||
*/
|
||||
void writeType(TypeInformation<?> type, S dbObject);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011 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.convert;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Annotation to clarify intended usage of a {@link Converter} as writing converter in case the conversion types leave
|
||||
* room for disambiguation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Target(TYPE)
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WritingConverter {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* General purpose conversion framework to read objects from a data store abstraction and write it back.
|
||||
*
|
||||
* @see org.springframework.data.convert.EntityConverter
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
Reference in New Issue
Block a user