org.atemsource.atem.utility.transform.api.TypeTransformationBuilder Maven / Gradle / Ivy
/*******************************************************************************
* Stefan Meyer, 2012 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.atemsource.atem.utility.transform.api;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;
import org.atemsource.atem.api.BeanLocator;
import org.atemsource.atem.api.EntityTypeRepository;
import org.atemsource.atem.api.attribute.Attribute;
import org.atemsource.atem.api.attribute.CollectionAttribute;
import org.atemsource.atem.api.attribute.MapAttribute;
import org.atemsource.atem.api.type.EntityType;
import org.atemsource.atem.api.type.EntityTypeBuilder;
import org.atemsource.atem.api.type.PrimitiveType;
import org.atemsource.atem.impl.meta.DerivedObject;
import org.atemsource.atem.utility.path.AttributePathBuilderFactory;
import org.atemsource.atem.utility.transform.api.meta.DerivedType;
import org.atemsource.atem.utility.transform.impl.EntityTypeTransformation;
import org.atemsource.atem.utility.transform.impl.builder.CollectionAttributeTransformationBuilder;
import org.atemsource.atem.utility.transform.impl.builder.MapAttributeTransformationBuilder;
import org.atemsource.atem.utility.transform.impl.builder.OneToOneAttributeTransformationBuilder;
import org.atemsource.atem.utility.transform.impl.builder.SingleAttributeTransformationBuilder;
import org.atemsource.atem.utility.transform.impl.builder.TransformationFinder;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class TypeTransformationBuilder
{
@Inject
private BeanLocator beanLocator;
private ConverterFactory converterFactory;
@Inject
private EntityTypeRepository entityTypeRepository;
private final Logger logger = Logger.getLogger(getClass());
@Inject
private AttributePathBuilderFactory pathFactory;
private EntityTypeTransformation selfReference;
private EntityType sourceType;
private EntityTypeTransformation superTransformation;
private EntityTypeBuilder targetTypeBuilder;
private Transformation transformation;
private final List transformations = new ArrayList();
public TypeTransformationBuilder()
{
}
private void addDerivation(EntityTypeTransformation transformation, EntityType newType,
EntityType originalType)
{
DerivedType deriveType = new DerivedType();
deriveType.setOriginalType(originalType);
deriveType.setTransformation(transformation);
Attribute metaAttribute =
entityTypeRepository.getEntityType(EntityType.class).getMetaAttribute(DerivedObject.META_ATTRIBUTE_CODE);
if (metaAttribute != null)
{
metaAttribute.setValue(newType, deriveType);
}
logger.info("finished init of " + newType.getCode());
}
public void addTransformation(JavaTransformation javaTransformation)
{
selfReference.addTransformation(javaTransformation);
}
public EntityTypeTransformation buildTypeTransformation()
{
for (AttributeTransformationBuilder transformation : transformations)
{
transformation.build(targetTypeBuilder);
}
targetTypeBuilder.setAbstract(sourceType.isAbstractType());
EntityType targetType = targetTypeBuilder.createEntityType();
if (transformation != null)
{
selfReference.setTypeConverter(transformation);
}
else
{
selfReference.setTypeConverter(createTypeCreator(targetType));
}
if (superTransformation != null)
{
EntityTypeTransformation superEntityTypeTransformation =
(EntityTypeTransformation) superTransformation;
selfReference.setSuperTransformation(superEntityTypeTransformation);
superEntityTypeTransformation.addSubTransformation(selfReference);
}
for (AttributeTransformationBuilder transformation : transformations)
{
selfReference.addTransformation(transformation.create(targetType));
}
selfReference.setEntityTypeB(targetType);
selfReference.setEntityTypeA(sourceType);
addDerivation(selfReference, targetType, sourceType);
return selfReference;
}
protected TypeCreator createTypeCreator(EntityType targetType)
{
TypeCreator instance = beanLocator.getInstance(TypeCreator.class);
instance.initialize(sourceType, targetType);
return instance;
}
public TypeTransformationBuilder finder(TransformationFinder finder)
{
selfReference.setFinder(finder);
return this;
}
public ConverterFactory getConverterFactory()
{
return converterFactory;
}
public EntityTypeTransformation getReference()
{
return selfReference;
}
public EntityType getSourceType()
{
return sourceType;
}
public void includeSuper(EntityTypeTransformation transformation)
{
targetTypeBuilder.superType((EntityType) transformation.getTypeB());
superTransformation = transformation;
}
@PostConstruct
public void initialize()
{
selfReference = beanLocator.getInstance(EntityTypeTransformation.class);
}
public void setConverterFactory(ConverterFactory converterFactory)
{
this.converterFactory = converterFactory;
}
public void setSourceType(Class sourceType)
{
this.sourceType = entityTypeRepository.getEntityType(sourceType);
}
public void setSourceType(EntityType sourceType)
{
this.sourceType = sourceType;
}
public void setTargetTypeBuilder(EntityTypeBuilder targetTypeBuilder)
{
this.targetTypeBuilder = targetTypeBuilder;
}
public void setTypeTransfomation(Transformation transformation)
{
this.transformation = transformation;
}
public OneToOneAttributeTransformationBuilder> transform()
{
OneToOneAttributeTransformationBuilder> builder =
beanLocator.getInstance(SingleAttributeTransformationBuilder.class);
builder.setSourceType(sourceType);
builder.setConverterFactory(converterFactory);
transformations.add(builder);
return builder;
}
public OneToOneAttributeTransformationBuilder transform(Class attributeClass)
{
if (CollectionAttribute.class.isAssignableFrom(attributeClass))
{
return transformCollection();
}
else if (MapAttribute.class.isAssignableFrom(attributeClass))
{
return transformMap();
}
else
{
return transform();
}
}
public CollectionAttributeTransformationBuilder transformCollection()
{
CollectionAttributeTransformationBuilder builder =
beanLocator.getInstance(CollectionAttributeTransformationBuilder.class);
builder.setSourceType(sourceType);
builder.setConverterFactory(converterFactory);
transformations.add(builder);
return builder;
}
public A transformCustom(Class builderClass)
{
A builder = beanLocator.getInstance(builderClass);
builder.setSourceType(sourceType);
builder.setConverterFactory(converterFactory);
builder.setTargetTypeBuilder(targetTypeBuilder);
transformations.add(builder);
return builder;
}
public MapAttributeTransformationBuilder transformMap()
{
MapAttributeTransformationBuilder builder = beanLocator.getInstance(MapAttributeTransformationBuilder.class);
builder.setSourceType(sourceType);
builder.setConverterFactory(converterFactory);
transformations.add(builder);
return builder;
}
public void transformPrimitives(String... excludedAttributes)
{
for (Attribute attribute : getSourceType().getAttributes())
{
if (ArrayUtils.contains(excludedAttributes, attribute.getCode())
&& attribute.getTargetType() instanceof PrimitiveType)
{
// TODO add conversion from local and global standard
// transformers
Converter converter = converterFactory.get(attribute.getTargetType());
OneToOneAttributeTransformationBuilder> transform =
transform();
transform.from(attribute.getCode()).to(attribute.getCode());// .convert(converter);
if (converter != null)
{
transform.convert(converter);
}
}
}
}
}