Deferring object mapper until Spring 3.1 when it will be used by other projects
This commit is contained in:
parent
6ef9c2d710
commit
3cdb942cbe
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping;
|
||||
|
||||
/**
|
||||
* Maps between a source and target.
|
||||
* @author Keith Donald
|
||||
* @param <S> the source type mapped from
|
||||
* @param <T> the target type mapped to
|
||||
*/
|
||||
public interface Mapper<S, T> {
|
||||
|
||||
/**
|
||||
* Map the source to the target.
|
||||
* @param source the source to map from
|
||||
* @param target the target to map to
|
||||
* @return the mapped target object
|
||||
* @throws MappingException if the mapping process failed
|
||||
*/
|
||||
T map(S source, T target);
|
||||
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Thrown in a map operation fails.
|
||||
* @see Mapper#map(Object, Object)
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public final class MappingException extends RuntimeException {
|
||||
|
||||
private List<MappingFailure> mappingFailures;
|
||||
|
||||
public MappingException(List<MappingFailure> mappingFailures) {
|
||||
super((String) null);
|
||||
this.mappingFailures = mappingFailures;
|
||||
}
|
||||
|
||||
public int getMappingFailureCount() {
|
||||
return this.mappingFailures.size();
|
||||
}
|
||||
|
||||
public List<MappingFailure> getMappingFailures() {
|
||||
return this.mappingFailures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
StringBuilder sb = new StringBuilder(getMappingFailureCount() + " mapping failure(s) occurred:");
|
||||
int i = 1;
|
||||
for (Iterator<MappingFailure> it = this.mappingFailures.iterator(); it.hasNext(); i++) {
|
||||
MappingFailure failure = it.next();
|
||||
sb.append(" #").append(i + ") ").append(failure.getMessage());
|
||||
if (it.hasNext()) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintStream ps) {
|
||||
super.printStackTrace(ps);
|
||||
synchronized (ps) {
|
||||
ps.println();
|
||||
ps.println("Mapping Failure Traces:");
|
||||
int i = 1;
|
||||
for (Iterator<MappingFailure> it = this.mappingFailures.iterator(); it.hasNext(); i++) {
|
||||
MappingFailure failure = it.next();
|
||||
ps.println("- MappingFailure #" + i + ":");
|
||||
Throwable t = failure.getCause();
|
||||
if (t != null) {
|
||||
t.printStackTrace(ps);
|
||||
} else {
|
||||
ps.println("null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintWriter pw) {
|
||||
super.printStackTrace(pw);
|
||||
synchronized (pw) {
|
||||
pw.println();
|
||||
pw.println("Mapping Failure Traces:");
|
||||
int i = 1;
|
||||
for (Iterator<MappingFailure> it = this.mappingFailures.iterator(); it.hasNext(); i++) {
|
||||
MappingFailure failure = it.next();
|
||||
pw.println("- MappingFailure #" + i + ":");
|
||||
Throwable t = failure.getCause();
|
||||
if (t != null) {
|
||||
t.printStackTrace(pw);
|
||||
} else {
|
||||
pw.println("null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping;
|
||||
|
||||
/**
|
||||
* Indicates an individual mapping failed.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public final class MappingFailure {
|
||||
|
||||
private final Throwable cause;
|
||||
|
||||
/**
|
||||
* Create a new mapping failure caused by the exception.
|
||||
* @param cause the failure cause
|
||||
*/
|
||||
public MappingFailure(Throwable cause) {
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* The failure message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return getCause().getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* The cause of this failure.
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[MappingFailure cause = " + cause + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
|
||||
final class BeanMappableType implements MappableType<Object> {
|
||||
|
||||
public boolean isInstance(Object object) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public EvaluationContext getEvaluationContext(Object object, ConversionService conversionService) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(object);
|
||||
context.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||
return context;
|
||||
}
|
||||
|
||||
public Set<String> getFieldNames(Object object) {
|
||||
Set<String> fields = new LinkedHashSet<String>();
|
||||
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(object.getClass());
|
||||
for (PropertyDescriptor descriptor : descriptors) {
|
||||
String propertyName = descriptor.getName();
|
||||
if (propertyName.equals("class")) {
|
||||
continue;
|
||||
}
|
||||
fields.add(descriptor.getName());
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
public Map<String, Object> getNestedFields(String fieldName, Object object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Creates a mapping target by calling a converter.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class ConverterMappingTargetFactory implements MappingTargetFactory {
|
||||
|
||||
private Converter converter;
|
||||
|
||||
public ConverterMappingTargetFactory(Converter converter) {
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
public boolean supports(TypeDescriptor targetType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object createTarget(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return this.converter.convert(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
/**
|
||||
* Default mappable type factory that registers Map and Bean mappable types.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class DefaultMappableTypeFactory extends MappableTypeFactory {
|
||||
public DefaultMappableTypeFactory() {
|
||||
add(new MapMappableType());
|
||||
add(new BeanMappableType());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Creates a mapping target by calling its default constructor.
|
||||
* @author Keith Donald
|
||||
* @see BeanUtils#instantiate(Class)
|
||||
*/
|
||||
final class DefaultMappingTargetFactory implements MappingTargetFactory {
|
||||
|
||||
private static final DefaultMappingTargetFactory INSTANCE = new DefaultMappingTargetFactory();
|
||||
|
||||
private DefaultMappingTargetFactory() {
|
||||
|
||||
}
|
||||
|
||||
public boolean supports(TypeDescriptor targetType) {
|
||||
return ClassUtils.hasConstructor(targetType.getType(), null);
|
||||
}
|
||||
|
||||
public Object createTarget(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return BeanUtils.instantiate(targetType.getType());
|
||||
}
|
||||
|
||||
public static MappingTargetFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.expression.Expression;
|
||||
|
||||
/**
|
||||
* A mapping between a source field and a target field.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class FieldToFieldMapping implements SpelMapping {
|
||||
|
||||
private final Expression sourceField;
|
||||
|
||||
private final Expression targetField;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Converter converter;
|
||||
|
||||
private final Expression condition;
|
||||
|
||||
public FieldToFieldMapping(Expression sourceField, Expression targetField, Converter<?, ?> converter, Expression condition) {
|
||||
this.sourceField = sourceField;
|
||||
this.targetField = targetField;
|
||||
this.converter = converter;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public String getSourceField() {
|
||||
return this.sourceField.getExpressionString();
|
||||
}
|
||||
|
||||
public String getTargetField() {
|
||||
return this.targetField.getExpressionString();
|
||||
}
|
||||
|
||||
public boolean mapsField(String field) {
|
||||
return getSourceField().equals(field);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void map(SpelMappingContext context) {
|
||||
if (!context.conditionHolds(this.condition)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Object value = context.getSourceFieldValue(this.sourceField);
|
||||
if (this.converter != null) {
|
||||
value = this.converter.convert(value);
|
||||
}
|
||||
context.setTargetFieldValue(this.targetField, value);
|
||||
} catch (Exception e) {
|
||||
context.addMappingFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getSourceField().hashCode() + getTargetField().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FieldToFieldMapping)) {
|
||||
return false;
|
||||
}
|
||||
FieldToFieldMapping m = (FieldToFieldMapping) o;
|
||||
return getSourceField().equals(m.getSourceField()) && getTargetField().equals(m.getTargetField());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[FieldToFieldMapping<" + getSourceField() + " -> " + getTargetField() + ">]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* A mapping between a source field and several target fields.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class FieldToMultiFieldMapping implements SpelMapping {
|
||||
|
||||
private final Expression sourceField;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Mapper targetFieldMapper;
|
||||
|
||||
private final Expression condition;
|
||||
|
||||
public FieldToMultiFieldMapping(Expression sourceField, Mapper<?, ?> targetFieldMapper, Expression condition) {
|
||||
this.sourceField = sourceField;
|
||||
this.targetFieldMapper = targetFieldMapper;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public String getSourceField() {
|
||||
return this.sourceField.getExpressionString();
|
||||
}
|
||||
|
||||
public boolean mapsField(String field) {
|
||||
return getSourceField().equals(field);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void map(SpelMappingContext context) {
|
||||
if (!context.conditionHolds(this.condition)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Object value = context.getSourceFieldValue(this.sourceField);
|
||||
this.targetFieldMapper.map(value, context.getTarget());
|
||||
} catch (Exception e) {
|
||||
context.addMappingFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getSourceField().hashCode() + this.targetFieldMapper.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FieldToMultiFieldMapping)) {
|
||||
return false;
|
||||
}
|
||||
FieldToMultiFieldMapping m = (FieldToMultiFieldMapping) o;
|
||||
return getSourceField().equals(m.getSourceField()) && this.targetFieldMapper.equals(m.targetFieldMapper);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[FieldToFieldMapping<" + getSourceField() + " -> " + this.targetFieldMapper + ">]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.core.style.StylerUtils;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* A mapping between several source fields and one or more target fields.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class FlexibleFieldMapping implements SpelMapping {
|
||||
|
||||
private String[] fields;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Mapper flexibleFieldMapper;
|
||||
|
||||
private Expression condition;
|
||||
|
||||
public FlexibleFieldMapping(String[] fields, Mapper<?, ?> flexibleFieldMapper, Expression condition) {
|
||||
this.fields = fields;
|
||||
this.flexibleFieldMapper = flexibleFieldMapper;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public String[] getSourceFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public boolean mapsField(String field) {
|
||||
for (String f : this.fields) {
|
||||
if (f.equals(field)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void map(SpelMappingContext context) {
|
||||
if (!context.conditionHolds(this.condition)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.flexibleFieldMapper.map(context.getSource(), context.getTarget());
|
||||
} catch (Exception e) {
|
||||
context.addMappingFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.flexibleFieldMapper.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FlexibleFieldMapping)) {
|
||||
return false;
|
||||
}
|
||||
FlexibleFieldMapping m = (FlexibleFieldMapping) o;
|
||||
return this.flexibleFieldMapper.equals(m.flexibleFieldMapper);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[FlexibleFieldMapping<" + StylerUtils.style(this.fields) + " -> " + this.flexibleFieldMapper + ">]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
|
||||
final class MapMappableType implements MappableType<Map<? extends Object, ? extends Object>> {
|
||||
|
||||
public boolean isInstance(Object object) {
|
||||
return object instanceof Map<?, ?>;
|
||||
}
|
||||
|
||||
public EvaluationContext getEvaluationContext(Map<? extends Object, ? extends Object> object,
|
||||
ConversionService conversionService) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(object);
|
||||
context.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||
context.addPropertyAccessor(new MapAccessor());
|
||||
return context;
|
||||
}
|
||||
|
||||
public Set<String> getFieldNames(Map<? extends Object, ? extends Object> object) {
|
||||
Set<String> fieldNames = new LinkedHashSet<String>(object.size(), 1);
|
||||
for (Object key : object.keySet()) {
|
||||
if (key != null && key instanceof String) {
|
||||
fieldNames.add((String) key);
|
||||
}
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
public Map<String, Object> getNestedFields(String fieldName, Map<? extends Object, ? extends Object> object) {
|
||||
Map<String, Object> fields = new LinkedHashMap<String, Object>(object.size(), 1);
|
||||
for (Map.Entry<? extends Object, ? extends Object> entry : object.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
if (key != null && key instanceof String) {
|
||||
String name = (String) key;
|
||||
if (name.startsWith(fieldName + ".")) {
|
||||
fields.put(name.substring(fieldName.length() + 1), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
|
||||
/**
|
||||
* Encapsulates mapping context for a type of object.
|
||||
* @param <T> the object type
|
||||
* @author Keith Donald
|
||||
*/
|
||||
interface MappableType<T> {
|
||||
|
||||
/**
|
||||
* Is this object to map an instanceof this mappable type?
|
||||
* @param object the object to test
|
||||
*/
|
||||
boolean isInstance(Object object);
|
||||
|
||||
/**
|
||||
* A evaluation context for accessing the object.
|
||||
*/
|
||||
EvaluationContext getEvaluationContext(T object, ConversionService conversionService);
|
||||
|
||||
/**
|
||||
* The names of the fields on the object that are eligible for mapping, including any nested fields.
|
||||
*/
|
||||
Set<String> getFieldNames(T object);
|
||||
|
||||
/**
|
||||
* A map of the nested fields on the object that are nested relative to <code>fieldName</code>.
|
||||
*/
|
||||
Map<String, Object> getNestedFields(String fieldName, T object);
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Generic MappableTypeFactory that has no mappable types registered by default.
|
||||
* Call {@link #add(MappableType)} to register.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class MappableTypeFactory {
|
||||
|
||||
private Set<MappableType<?>> mappableTypes = new LinkedHashSet<MappableType<?>>();
|
||||
|
||||
/**
|
||||
* Add a MappableType to this factory.
|
||||
* @param mappableType the mappable type
|
||||
*/
|
||||
public void add(MappableType<?> mappableType) {
|
||||
this.mappableTypes.add(mappableType);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> MappableType<T> getMappableType(T object) {
|
||||
for (MappableType type : mappableTypes) {
|
||||
if (type.isInstance(object)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Object of type [" + object.getClass().getName()
|
||||
+ "] is not mappable - no suitable MappableType exists");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* A fluent interface for configuring a {@link Mapper} between a source type and a target type.
|
||||
* To use, call one or more of the builder methods on this class, then {@link #getMapper()} to obtain the Mapper instance.
|
||||
* @author Keith Donald
|
||||
* @param <S> the source type to map from
|
||||
* @param <T> the target type to map to
|
||||
* @see #setAutoMappingEnabled(boolean)
|
||||
* @see #addMapping(String)
|
||||
* @see #addMapping(String, Converter)
|
||||
* @see #addMapping(String, Mapper)
|
||||
* @see #addMapping(String, String)
|
||||
* @see #addMapping(String, String, Converter)
|
||||
* @see #addMapping(Mapper)
|
||||
* @see #addConverter(Converter)
|
||||
* @see #getMapper()
|
||||
*/
|
||||
public interface MapperBuilder<S, T> {
|
||||
|
||||
/**
|
||||
* Sets whether "auto mapping" is enabled.
|
||||
* When enabled, source and target fields with the same name will automatically be mapped unless an explicit mapping override has been registered.
|
||||
* Set to false to require explicit registration of all source-to-target mapping rules.
|
||||
* Default is enabled (true).
|
||||
* @param autoMappingEnabled auto mapping status
|
||||
*/
|
||||
MapperBuilder<S, T> setAutoMappingEnabled(boolean autoMappingEnabled);
|
||||
|
||||
/**
|
||||
* Register a mapping between a source field and a target field.
|
||||
* The source and target field names will be the same value.
|
||||
* For example, calling <code>addMapping("order")</code> will register a mapping that maps between the <code>order</code> field on the source and the <code>order</code> field on the target.
|
||||
* This is a convenience method for calling {@link #addMapping(String, String)} with the same source and target value..
|
||||
* @param field the field mapping expression
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addMapping(String field);
|
||||
|
||||
/**
|
||||
* Register a mapping between a source field and a target field that first converts the source field value using the provided Converter.
|
||||
* The source and target field expressions will be the same value.
|
||||
* For example, calling <code>addMapping("order")</code> will register a mapping that maps between the <code>order</code> field on the source and the <code>order</code> field on the target.
|
||||
* This is a convenience method for calling {@link #addMapping(String, String, Converter)} with the same source and target value..
|
||||
* @param field the field mapping expression
|
||||
* @param converter the converter that will convert the source field value before mapping the value to the target field
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addMapping(String field, Converter<?, ?> converter);
|
||||
|
||||
/**
|
||||
* Register a mapping between a source field and multiple target fields.
|
||||
* Use this method when you need to map a single source field value to multiple fields on the target.
|
||||
* For example, calling <code>addMapping("name", firstAndLastNameMapper)</code> might register a mapping that maps the <code>name</code> field on the source to the <code>firstName</code> and <code>lastName</code> fields on the target.
|
||||
* The target field {@link Mapper} will be passed the value of the source field for its source and the target object T for its target.
|
||||
* @param field the source field expression
|
||||
* @param mapper the mapper of the target fields
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addMapping(String field, Mapper<?, T> mapper);
|
||||
|
||||
/**
|
||||
* Register a mapping between a source field and a target field.
|
||||
* Use this method when the name of the source field and the name of the target field are different.
|
||||
* For example, calling <code>addMapping("order", "primaryOrder")</code> will register a mapping that maps between the <code>order</code> field on the source and the <code>primaryOrder</code> field on the target.
|
||||
* @param sourceField the source field mapping expression
|
||||
* @param targetField the target field mapping expression
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addMapping(String sourceField, String targetField);
|
||||
|
||||
/**
|
||||
* Register a mapping between a source field and a target field that first converts the source field value using the provided Converter.
|
||||
* Use this method when the name of the source field and the name of the target field are different.
|
||||
* For example, calling <code>addMapping("order", "primaryOrder")</code> will register a mapping that maps between the <code>order</code> field on the source and the <code>primaryOrder</code> field on the target.
|
||||
* @param sourceField the source field mapping expression
|
||||
* @param targetField the target field mapping expression
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addMapping(String sourceField, String targetField, Converter<?, ?> converter);
|
||||
|
||||
/**
|
||||
* Register a flexible mapping between multiple source fields and one or more target fields.
|
||||
* For example, calling <code>addMapping(dateAndTimeFieldsToDateTimeFieldMapper)</code> might register a mapping that maps the <code>date</code> and <code>time</code> fields on the source to the <code>dateTime</code> field on the target.
|
||||
* The provided {@link Mapper} will be passed the source object S for its source and the target object T for its target.
|
||||
* @param fields the source field mapping expressions
|
||||
* @param mapper the fields to field mapper
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addMapping(String[] fields, Mapper<S, T> mapper);
|
||||
|
||||
/**
|
||||
* Register a mapping that delegates to an assembler to convert multiple nested source field values to a single target field value.
|
||||
* The source field names that will be mapped all begin with the prefix <code>field.</code>.
|
||||
* For example, adding an assembler mapping for a field named <code>dateTime</code> would pass all nested <code>dateTime.*</code> fields to the assembler.
|
||||
* Such fields might be <code>year</code>, <code>month</code>, <code>day</code>, etc.
|
||||
* @param fields the name of the source field whose value will be assembled from multiple nested fields that begin with the same name
|
||||
* @param assembler the assembler that will perform value assembly from the field values
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addAssemblerMapping(String field, Converter<? extends Map<?, ?>, ?> assembler);
|
||||
|
||||
/**
|
||||
* Register a conditional mapping between a source field and a target field.
|
||||
* The source and target field names will be the same value.
|
||||
* @param field the field mapping expression
|
||||
* @param condition the boolean expression that determines if this mapping executes
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addConditionalMapping(String field, String condition);
|
||||
|
||||
/**
|
||||
* Register a condition mapping between a source field and a target field that first converts the source field value using the provided Converter.
|
||||
* The source and target field expressions will be the same value.
|
||||
* @param field the field mapping expression
|
||||
* @param converter the converter that converts the source field value before mapping
|
||||
* @param condition the boolean expression that determines if this mapping executes
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addConditionalMapping(String field, Converter<?, ?> converter, String condition);
|
||||
|
||||
/**
|
||||
* Register a conditional mapping between a source field and multiple target fields.
|
||||
* Use this method when you need to map a single source field value to multiple fields on the target.
|
||||
* For example, calling <code>addMapping("name", firstAndLastNameMapper)</code> might register a mapping that maps the <code>name</code> field on the source to the <code>firstName</code> and <code>lastName</code> fields on the target.
|
||||
* The target field {@link Mapper} will be passed the value of the source field for its source and the target object T for its target.
|
||||
* @param field the source field expression
|
||||
* @param mapper the mapper of the target fields
|
||||
* @param condition the boolean expression that determines if this mapping executes
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addConditionalMapping(String field, Mapper<?, T> mapper, String condition);
|
||||
|
||||
/**
|
||||
* Register a conditional mapping between a source field and a target field.
|
||||
* Use this method when the name of the source field and the name of the target field are different.
|
||||
* For example, calling <code>addMapping("order", "primaryOrder")</code> will register a mapping that maps between the <code>order</code> field on the source and the <code>primaryOrder</code> field on the target.
|
||||
* @param sourceField the source field mapping expression
|
||||
* @param targetField the target field mapping expression
|
||||
* @param condition the boolean expression that determines if this mapping executes
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addConditionalMapping(String sourceField, String targetField, String condition);
|
||||
|
||||
/**
|
||||
* Register a conditional mapping between a source field and a target field that first converts the source field value using the provided Converter.
|
||||
* Use this method when the name of the source field and the name of the target field are different.
|
||||
* For example, calling <code>addMapping("order", "primaryOrder")</code> will register a mapping that maps between the <code>order</code> field on the source and the <code>primaryOrder</code> field on the target.
|
||||
* @param sourceField the source field mapping expression
|
||||
* @param targetField the target field mapping expression
|
||||
* @param converter the converter that converts the source field value before mapping
|
||||
* @param condition the boolean expression that determines if this mapping executes
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addConditionalMapping(String sourceField, String targetField, Converter<?, ?> converter, String condition);
|
||||
|
||||
/**
|
||||
* Register a flexible conditional mapping between multiple source fields and one ore more target fields.
|
||||
* For example, calling <code>addMapping(dateAndTimeFieldsToDateTimeFieldMapper)</code> might register a mapping that maps the <code>date</code> and <code>time</code> fields on the source to the <code>dateTime</code> field on the target.
|
||||
* The provided {@link Mapper} will be passed the source object S for its source and the target object T for its target.
|
||||
* @param fields the source field mapping expressions
|
||||
* @param mapper the fields to field mapper
|
||||
* @param condition the boolean expression that determines if this mapping executes
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addConditionalMapping(String[] fields, Mapper<S, T> mapper, String condition);
|
||||
|
||||
/**
|
||||
* Register a Mapper that will be used to map between nested source and target fields of a specific sourceType/targetType pair.
|
||||
* The source and target field types are determined by introspecting the parameterized types on the Mapper generic interface.
|
||||
* The target instance that is mapped is constructed by calling its default constructor.
|
||||
* @param nestedMapper the nested mapper
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addNestedMapper(Mapper<?, ?> nestedMapper);
|
||||
|
||||
/**
|
||||
* Register a Mapper that will be used to map between nested source and target fields of a specific sourceType/targetType pair.
|
||||
* The source and target field types are determined by introspecting the parameterized types on the Mapper generic interface.
|
||||
* The target instance that is mapped is constructed by calling the provided Converter.
|
||||
* @param nestedMapper the nested mapper
|
||||
* @param converter the target converter
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
*/
|
||||
MapperBuilder<S, T> addNestedMapper(Mapper<?, ?> nestedMapper, Converter<?, ?> converter);
|
||||
|
||||
/**
|
||||
* Register a custom type converter to use to convert between two mapped types.
|
||||
* The Converter may convert between simple types, such as Strings to Dates.
|
||||
* Alternatively, it may convert between complex types and initiate a recursive mapping operation between two object fields.
|
||||
* @return this, for configuring additional field mapping options fluently
|
||||
* @see Converter
|
||||
* @see MappingConverter
|
||||
*/
|
||||
MapperBuilder<S, T> addConverter(Converter<?, ?> converter);
|
||||
|
||||
/**
|
||||
* Set the source fields to exclude from mapping.
|
||||
* @param fields the source fields as var args
|
||||
*/
|
||||
MapperBuilder<S, T> setExcludedFields(String... fields);
|
||||
|
||||
/**
|
||||
* Get the Mapper produced by this builder.
|
||||
* Call this method after instructing the builder.
|
||||
* @return the Mapper between S and T ready for use
|
||||
*/
|
||||
Mapper<S, T> getMapper();
|
||||
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* Factory for creating general-purpose Mappers without depending on a concrete Mapper implementation class.
|
||||
* @see #defaultMapper()
|
||||
* @see #mapperBuilder()
|
||||
* @see #mapperBuilder(Class, Class)
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class MapperFactory {
|
||||
|
||||
private static final SpelMapper DEFAULT_MAPPER = new SpelMapper();
|
||||
|
||||
/**
|
||||
* Get the default Mapper instance suitable for mapping between most object types using "auto mapping" based on field names.
|
||||
* The Mapper returned is shared and immutable and should not be downcast & modified.
|
||||
* @return the default mapper
|
||||
*/
|
||||
public static Mapper<Object, Object> defaultMapper() {
|
||||
return DEFAULT_MAPPER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a builder for a new Mapper instance, allowing customization of object mapping policy.
|
||||
* @return the MapperBuilder
|
||||
*/
|
||||
public static MapperBuilder<Object, Object> mapperBuilder() {
|
||||
return new SpelMapperBuilder<Object, Object>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a builder for a new Mapper instance that maps between objects of sourceType and targetType.
|
||||
* Allows for customization of object mapping policy.
|
||||
* Use this method as an alterntative to {@link #mapperBuilder()} when you'd like more type-safety and validation when configuring and using the Mapper.
|
||||
* @return the MapperBuilder
|
||||
*/
|
||||
public static <S, T> MapperBuilder<S, T> mapperBuilder(Class<S> sourceType, Class<T> targetType) {
|
||||
return new SpelMapperBuilder<S, T>(sourceType, targetType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
|
||||
/**
|
||||
* Holds thread-specific context about a mapping operation
|
||||
* @author Keith Donald
|
||||
* @see SpelMapper#map(Object, Object)
|
||||
*/
|
||||
abstract class MappingContextHolder {
|
||||
|
||||
private static final ThreadLocal<Stack<Object>> mappingContextHolder = new NamedThreadLocal<Stack<Object>>(
|
||||
"Mapping context");
|
||||
|
||||
/**
|
||||
* Push a source object being mapped onto the context.
|
||||
*/
|
||||
public static void push(Object source) {
|
||||
Stack<Object> context = getContext();
|
||||
if (context == null) {
|
||||
context = new Stack<Object>();
|
||||
mappingContextHolder.set(context);
|
||||
}
|
||||
context.add(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the source being mapped or has already been mapped?
|
||||
*/
|
||||
public static boolean contains(Object source) {
|
||||
Stack<Object> context = getContext();
|
||||
return context != null ? context.contains(source) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the source object being mapped off the context; mapping is complete.
|
||||
*/
|
||||
public static void pop() {
|
||||
Stack<Object> context = getContext();
|
||||
if (context != null) {
|
||||
context.pop();
|
||||
if (context.isEmpty()) {
|
||||
mappingContextHolder.set(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a level of bullets for indenting mapping debug logs based on the depth in the object graph.
|
||||
*/
|
||||
public static String getLevel() {
|
||||
int size = getContext().size();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
builder.append("*");
|
||||
}
|
||||
builder.append(" ");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static Stack<Object> getContext() {
|
||||
return mappingContextHolder.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConverter;
|
||||
|
||||
final class MappingConversionService extends DefaultConversionService {
|
||||
|
||||
@Override
|
||||
protected GenericConverter getDefaultConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return new MappingConverter(new SpelMapper(), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.GenericConverter;
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* Adapts a Mapper to a Converter, allowing the conversion between two object types to be completed by a Mapper.
|
||||
* Delegates to a {@link MappingTargetFactory} to construct the conversion target object that will be mapped.
|
||||
* The default MapperTargetFactory instantiates a target by calling its default constructor.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class MappingConverter implements GenericConverter {
|
||||
|
||||
private final Mapper mapper;
|
||||
|
||||
private final MappingTargetFactory mappingTargetFactory;
|
||||
|
||||
/**
|
||||
* Creates a new Converter that delegates to the mapper to complete the type conversion process.
|
||||
* Uses the specified MappingTargetFactory to create the target object to map and return.
|
||||
* @param mapper the mapper
|
||||
*/
|
||||
public MappingConverter(Mapper mapper, MappingTargetFactory mappingTargetFactory) {
|
||||
this.mapper = mapper;
|
||||
if (mappingTargetFactory != null) {
|
||||
this.mappingTargetFactory = mappingTargetFactory;
|
||||
} else {
|
||||
this.mappingTargetFactory = DefaultMappingTargetFactory.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
if (MappingContextHolder.contains(source)) {
|
||||
return source;
|
||||
}
|
||||
if (sourceType.isAssignableTo(targetType) && isCopyByReference(sourceType, targetType)) {
|
||||
return source;
|
||||
}
|
||||
return createTargetAndMap(source, sourceType, targetType);
|
||||
}
|
||||
|
||||
private boolean isCopyByReference(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Object createTargetAndMap(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (this.mappingTargetFactory.supports(targetType)) {
|
||||
Object target = this.mappingTargetFactory.createTarget(source, sourceType, targetType);
|
||||
return this.mapper.map(source, target);
|
||||
} else {
|
||||
IllegalStateException cause = new IllegalStateException("["
|
||||
+ this.mappingTargetFactory.getClass().getName() + "] does not support targetType ["
|
||||
+ targetType.getName() + "]");
|
||||
throw new ConversionFailedException(sourceType, targetType, source, cause);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* A factory for customizing how the target of a map operation is constructed.
|
||||
* Used by a {@link MappingConverter} when executing a type conversion.
|
||||
* @author Keith Donald
|
||||
* @see MappingConverter
|
||||
* @see Mapper#map(Object, Object)
|
||||
*/
|
||||
interface MappingTargetFactory {
|
||||
|
||||
/**
|
||||
* Does this factory support creating mapping targets of the specified type
|
||||
* @param targetType the target type
|
||||
* @return true if so, false otherwise
|
||||
*/
|
||||
public boolean supports(TypeDescriptor targetType);
|
||||
|
||||
/**
|
||||
* Create the target object to be mapped to.
|
||||
* @param source the source object to map from
|
||||
* @param sourceType the source object type descriptor
|
||||
* @param targetType the target object type descriptor
|
||||
* @return the target
|
||||
*/
|
||||
public Object createTarget(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
|
||||
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.style.StylerUtils;
|
||||
import org.springframework.expression.Expression;
|
||||
|
||||
/**
|
||||
* A mapping between several source fields and a target field.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class MultiFieldToFieldMapping implements SpelMapping {
|
||||
|
||||
private final String sourceField;
|
||||
|
||||
private final Expression targetField;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Converter targetFieldValueAssembler;
|
||||
|
||||
private final Expression condition;
|
||||
|
||||
public MultiFieldToFieldMapping(String sourceField, Expression targetField, Converter<? extends Map<?,?>, ?> assembler,
|
||||
Expression condition) {
|
||||
this.sourceField = sourceField;
|
||||
this.targetField = targetField;
|
||||
this.targetFieldValueAssembler = assembler;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public String getSourceField() {
|
||||
return this.sourceField + ".*";
|
||||
}
|
||||
|
||||
public String getTargetField() {
|
||||
return this.targetField.getExpressionString();
|
||||
}
|
||||
|
||||
public boolean mapsField(String field) {
|
||||
return field.startsWith(this.sourceField + ".");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void map(SpelMappingContext context) {
|
||||
if (!context.conditionHolds(this.condition)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Map<String, Object> nestedFields = context.getSourceNestedFields(this.sourceField);
|
||||
Object value = this.targetFieldValueAssembler.convert(nestedFields);
|
||||
context.setTargetFieldValue(this.targetField, value);
|
||||
} catch (Exception e) {
|
||||
context.addMappingFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getSourceField().hashCode() + getTargetField().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof MultiFieldToFieldMapping)) {
|
||||
return false;
|
||||
}
|
||||
MultiFieldToFieldMapping m = (MultiFieldToFieldMapping) o;
|
||||
return getSourceField().equals(m.getSourceField()) && getTargetField().equals(m.getTargetField());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[MultiFieldToFieldMapping<" + StylerUtils.style(getSourceField()) + " -> " + getTargetField() + ">]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParserConfiguration;
|
||||
import org.springframework.mapping.Mapper;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A general-purpose object mapper implementation based on the Spring Expression Language (SpEL).
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class SpelMapper implements Mapper<Object, Object> {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpelMapper.class);
|
||||
|
||||
private final SpelExpressionParser sourceExpressionParser = new SpelExpressionParser();
|
||||
|
||||
private final SpelExpressionParser targetExpressionParser = new SpelExpressionParser(
|
||||
SpelExpressionParserConfiguration.CreateObjectIfAttemptToReferenceNull
|
||||
| SpelExpressionParserConfiguration.GrowListsOnIndexBeyondSize);
|
||||
|
||||
private final Set<SpelMapping> mappings = new LinkedHashSet<SpelMapping>();
|
||||
|
||||
private MappableTypeFactory mappableTypeFactory = new DefaultMappableTypeFactory();
|
||||
|
||||
private boolean autoMappingEnabled = true;
|
||||
|
||||
private MappingConversionService conversionService = new MappingConversionService();
|
||||
|
||||
public SpelMapper() {
|
||||
|
||||
}
|
||||
|
||||
public SpelMapper(Class sourceType, Class targetType) {
|
||||
// TODO - addMapping assertions based on specified sourceType and targetType
|
||||
}
|
||||
|
||||
public void setAutoMappingEnabled(boolean autoMappingEnabled) {
|
||||
this.autoMappingEnabled = autoMappingEnabled;
|
||||
}
|
||||
|
||||
public void setMappableTypeFactory(MappableTypeFactory mappableTypeFactory) {
|
||||
this.mappableTypeFactory = mappableTypeFactory;
|
||||
}
|
||||
|
||||
public void setExcludedFields(String[] fields) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void addFieldToFieldMapping(String sourceField, String targetField, Converter<?, ?> converter,
|
||||
String condition) {
|
||||
this.mappings.add(new FieldToFieldMapping(parseSourceField(sourceField), parseTargetField(targetField),
|
||||
converter, parseCondition(condition)));
|
||||
}
|
||||
|
||||
public void addFieldToMultiFieldMapping(String field, Mapper<?, ?> mapper, String condition) {
|
||||
this.mappings.add(new FieldToMultiFieldMapping(parseSourceField(field), mapper, parseCondition(condition)));
|
||||
}
|
||||
|
||||
public void addMultiFieldToFieldMapping(String[] fields, Mapper<?, ?> mapper, String condition) {
|
||||
this.mappings.add(new FlexibleFieldMapping(fields, mapper, parseCondition(condition)));
|
||||
}
|
||||
|
||||
public void addMultiFieldToFieldMapping(String sourceField, String targetField,
|
||||
Converter<? extends Map<?, ?>, ?> assembler, String condition) {
|
||||
this.mappings.add(new MultiFieldToFieldMapping(sourceField, parseTargetField(targetField), assembler,
|
||||
parseCondition(condition)));
|
||||
}
|
||||
|
||||
public void addNestedMapper(Mapper<?, ?> nestedMapper, MappingTargetFactory targetFactory) {
|
||||
Class<?>[] typeInfo = getRequiredTypeInfo(nestedMapper);
|
||||
addNestedMapper(typeInfo[0], typeInfo[1], nestedMapper, targetFactory);
|
||||
}
|
||||
|
||||
public void addNestedMapper(Class<?> sourceType, Class<?> targetType, Mapper<?, ?> nestedMapper,
|
||||
MappingTargetFactory targetFactory) {
|
||||
this.conversionService.addGenericConverter(sourceType, targetType, new MappingConverter(nestedMapper,
|
||||
targetFactory));
|
||||
}
|
||||
|
||||
public ConverterRegistry getConverterRegistry() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
public Object map(Object source, Object target) {
|
||||
Assert.notNull(source, "The source to map from cannot be null");
|
||||
Assert.notNull(target, "The target to map to cannot be null");
|
||||
try {
|
||||
MappingContextHolder.push(source);
|
||||
MappableType<?> sourceType = this.mappableTypeFactory.getMappableType(source);
|
||||
MappableType<?> targetType = this.mappableTypeFactory.getMappableType(target);
|
||||
SpelMappingContext context = new SpelMappingContext(source, sourceType, target, targetType,
|
||||
this.conversionService);
|
||||
for (SpelMapping mapping : this.mappings) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MappingContextHolder.getLevel() + mapping);
|
||||
}
|
||||
mapping.map(context);
|
||||
}
|
||||
Set<FieldToFieldMapping> autoMappings = getAutoMappings(context);
|
||||
for (SpelMapping mapping : autoMappings) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MappingContextHolder.getLevel() + mapping + " (auto)");
|
||||
}
|
||||
mapping.map(context);
|
||||
}
|
||||
context.handleFailures();
|
||||
return target;
|
||||
} finally {
|
||||
MappingContextHolder.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
private Expression parseSourceField(String sourceFieldExpression) {
|
||||
try {
|
||||
return sourceExpressionParser.parseExpression(sourceFieldExpression);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The mapping source '" + sourceFieldExpression
|
||||
+ "' is not a parseable value expression", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Expression parseCondition(String condition) {
|
||||
if (condition == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return sourceExpressionParser.parseExpression(condition);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The mapping condition '" + condition
|
||||
+ "' is not a parseable value expression", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Expression parseTargetField(String targetFieldExpression) {
|
||||
try {
|
||||
return targetExpressionParser.parseExpression(targetFieldExpression);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The mapping target '" + targetFieldExpression
|
||||
+ "' is not a parseable property expression", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?>[] getRequiredTypeInfo(Mapper<?, ?> mapper) {
|
||||
return GenericTypeResolver.resolveTypeArguments(mapper.getClass(), Mapper.class);
|
||||
}
|
||||
|
||||
private Set<FieldToFieldMapping> getAutoMappings(SpelMappingContext context) {
|
||||
if (this.autoMappingEnabled) {
|
||||
Set<FieldToFieldMapping> autoMappings = new LinkedHashSet<FieldToFieldMapping>();
|
||||
Set<String> sourceFields = context.getSourceFieldNames();
|
||||
for (String field : sourceFields) {
|
||||
if (!explicitlyMapped(field)) {
|
||||
Expression sourceField;
|
||||
try {
|
||||
sourceField = sourceExpressionParser.parseExpression(field);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The source field '" + field
|
||||
+ "' is not a parseable value expression", e);
|
||||
}
|
||||
Expression targetField;
|
||||
try {
|
||||
targetField = targetExpressionParser.parseExpression(field);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The target field '" + field
|
||||
+ "' is not a parseable value expression", e);
|
||||
}
|
||||
try {
|
||||
if (context.isTargetFieldWriteable(targetField)) {
|
||||
autoMappings.add(new FieldToFieldMapping(sourceField, targetField, null, null));
|
||||
}
|
||||
} catch (EvaluationException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return autoMappings;
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean explicitlyMapped(String field) {
|
||||
for (SpelMapping mapping : this.mappings) {
|
||||
if (mapping.mapsField(field)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.mapping.Mapper;
|
||||
|
||||
/**
|
||||
* MapperBuilder that builds {@link SpelMapper} instances.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
final class SpelMapperBuilder<S, T> implements MapperBuilder<S, T> {
|
||||
|
||||
private final SpelMapper mapper;
|
||||
|
||||
public SpelMapperBuilder() {
|
||||
this.mapper = new SpelMapper();
|
||||
}
|
||||
|
||||
public SpelMapperBuilder(Class<S> sourceType, Class<T> targetType) {
|
||||
this.mapper = new SpelMapper(sourceType, targetType);
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> setAutoMappingEnabled(boolean autoMappingEnabled) {
|
||||
this.mapper.setAutoMappingEnabled(autoMappingEnabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addMapping(String field) {
|
||||
this.mapper.addFieldToFieldMapping(field, field, null, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addMapping(String field, Converter<?, ?> converter) {
|
||||
this.mapper.addFieldToFieldMapping(field, field, converter, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addMapping(String field, Mapper<?, T> mapper) {
|
||||
this.mapper.addFieldToMultiFieldMapping(field, mapper, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addMapping(String sourceField, String targetField) {
|
||||
this.mapper.addFieldToFieldMapping(sourceField, targetField, null, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addMapping(String sourceField, String targetField, Converter<?, ?> converter) {
|
||||
this.mapper.addFieldToFieldMapping(sourceField, targetField, converter, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addMapping(String[] fields, Mapper<S, T> mapper) {
|
||||
this.mapper.addMultiFieldToFieldMapping(fields, mapper, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addAssemblerMapping(String field, Converter<? extends Map<?, ?>, ?> assembler) {
|
||||
this.mapper.addMultiFieldToFieldMapping(field, field, assembler, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConditionalMapping(String field, String condition) {
|
||||
this.mapper.addFieldToFieldMapping(field, field, null, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConditionalMapping(String field, Converter<?, ?> converter, String condition) {
|
||||
this.mapper.addFieldToFieldMapping(field, field, converter, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConditionalMapping(String field, Mapper<?, T> mapper, String condition) {
|
||||
this.mapper.addFieldToMultiFieldMapping(field, mapper, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConditionalMapping(String sourceField, String targetField, String condition) {
|
||||
this.mapper.addFieldToFieldMapping(sourceField, targetField, null, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConditionalMapping(String sourceField, String targetField, Converter<?, ?> converter,
|
||||
String condition) {
|
||||
this.mapper.addFieldToFieldMapping(sourceField, targetField, converter, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConditionalMapping(String[] fields, Mapper<S, T> mapper, String condition) {
|
||||
this.mapper.addMultiFieldToFieldMapping(fields, mapper, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addNestedMapper(Mapper<?, ?> nestedMapper) {
|
||||
this.mapper.addNestedMapper(nestedMapper, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addNestedMapper(Mapper<?, ?> nestedMapper, Converter<?, ?> converter) {
|
||||
this.mapper.addNestedMapper(nestedMapper, new ConverterMappingTargetFactory(converter));
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> addConverter(Converter<?, ?> converter) {
|
||||
this.mapper.getConverterRegistry().addConverter(converter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperBuilder<S, T> setExcludedFields(String... fields) {
|
||||
this.mapper.setExcludedFields(fields);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Mapper<S, T> getMapper() {
|
||||
return (Mapper<S, T>) this.mapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
/**
|
||||
* A single {@link SpelMapper} mapping.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
interface SpelMapping {
|
||||
|
||||
/**
|
||||
* Return true if this maps the source field.
|
||||
*/
|
||||
boolean mapsField(String field);
|
||||
|
||||
/**
|
||||
* Execute this mapping.
|
||||
* @param context the mapping context
|
||||
*/
|
||||
void map(SpelMappingContext context);
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.mapping.support;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.mapping.MappingException;
|
||||
import org.springframework.mapping.MappingFailure;
|
||||
|
||||
final class SpelMappingContext {
|
||||
|
||||
private final MappableType sourceType;
|
||||
|
||||
private final EvaluationContext sourceEvaluationContext;
|
||||
|
||||
private final EvaluationContext targetEvaluationContext;
|
||||
|
||||
private final List<MappingFailure> failures = new LinkedList<MappingFailure>();
|
||||
|
||||
public SpelMappingContext(Object source, MappableType sourceType, Object target, MappableType targetType,
|
||||
ConversionService conversionService) {
|
||||
this.sourceType = sourceType;
|
||||
this.sourceEvaluationContext = sourceType.getEvaluationContext(source, conversionService);
|
||||
this.targetEvaluationContext = targetType.getEvaluationContext(target, conversionService);
|
||||
}
|
||||
|
||||
public Object getSource() {
|
||||
return this.sourceEvaluationContext.getRootObject().getValue();
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.targetEvaluationContext.getRootObject().getValue();
|
||||
}
|
||||
|
||||
public boolean conditionHolds(Expression condition) {
|
||||
if (condition == null) {
|
||||
return true;
|
||||
}
|
||||
return Boolean.TRUE.equals(condition.getValue(this.sourceEvaluationContext));
|
||||
}
|
||||
|
||||
public Object getSourceFieldValue(Expression sourceField) {
|
||||
return sourceField.getValue(this.sourceEvaluationContext);
|
||||
}
|
||||
|
||||
public Set<String> getSourceFieldNames() {
|
||||
return this.sourceType.getFieldNames(getSource());
|
||||
}
|
||||
|
||||
public Map<String, Object> getSourceNestedFields(String sourceFieldName) {
|
||||
return this.sourceType.getNestedFields(sourceFieldName, getSource());
|
||||
}
|
||||
|
||||
public void setTargetFieldValue(Expression targetField, Object value) {
|
||||
targetField.setValue(this.targetEvaluationContext, value);
|
||||
}
|
||||
|
||||
public void addMappingFailure(Throwable cause) {
|
||||
this.failures.add(new MappingFailure(cause));
|
||||
}
|
||||
|
||||
public void handleFailures() {
|
||||
if (!this.failures.isEmpty()) {
|
||||
throw new MappingException(this.failures);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTargetFieldWriteable(Expression targetField) {
|
||||
return targetField.isWritable(this.targetEvaluationContext);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue