/*
* This code is distributed under The GNU Lesser General Public License (LGPLv3)
* Please visit GNU site for LGPLv3 http://www.gnu.org/copyleft/lesser.html
*
* Copyright Denis Pavlov 2009
* Web: http://www.genericdtoassembler.org
* SVN: https://svn.code.sf.net/p/geda-genericdto/code/trunk/
* SVN (mirror): http://geda-genericdto.googlecode.com/svn/trunk/
*/
package com.inspiresoftware.lib.dto.geda.assembler;
import com.inspiresoftware.lib.dto.geda.adapter.BeanFactory;
import com.inspiresoftware.lib.dto.geda.assembler.extension.MethodSynthesizer;
import com.inspiresoftware.lib.dto.geda.dsl.Registry;
import com.inspiresoftware.lib.dto.geda.exception.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Composite assembler to allow many entities to become a single Dto.
*
* @author Denis Pavlov
* @since 2.0.2
*
*/
@SuppressWarnings("unchecked")
public class DTOtoEntitiesAssemblerDecoratorImpl implements Assembler {
private final Map<Class, Assembler> composite = new HashMap<Class, Assembler>();
private final Class dtoClass;
DTOtoEntitiesAssemblerDecoratorImpl(final Class dto,
final Class[] entities,
final ClassLoader classLoader,
final MethodSynthesizer synthesizer,
final Registry registry)
throws InspectionScanningException, UnableToCreateInstanceException, InspectionPropertyNotFoundException,
InspectionBindingNotFoundException, AnnotationMissingBindingException, AnnotationValidatingBindingException,
GeDARuntimeException, AnnotationDuplicateBindingException {
dtoClass = dto;
for (final Class entity : entities) {
composite.put(entity, new DTOtoEntityAssemblerImpl(dto, entity, classLoader, synthesizer, registry, false));
}
}
/** {@inheritDoc} */
public void assembleDto(final Object dto, final Object entity,
final Map<String, Object> converters,
final BeanFactory dtoBeanFactory)
throws InspectionInvalidDtoInstanceException, InspectionInvalidEntityInstanceException, BeanFactoryNotFoundException,
BeanFactoryUnableToCreateInstanceException, AnnotationMissingException, NotValueConverterException,
ValueConverterNotFoundException, UnableToCreateInstanceException, CollectionEntityGenericReturnTypeException,
InspectionScanningException, InspectionPropertyNotFoundException, InspectionBindingNotFoundException,
AnnotationMissingBindingException, AnnotationValidatingBindingException, GeDARuntimeException,
AnnotationDuplicateBindingException {
final Object[] values;
if (entity instanceof Object[]) {
values = (Object[]) entity;
} else {
values = new Object[] { entity };
}
for (final Object value : values) {
if (value != null) {
for (final Class type : composite.keySet()) {
if (type.isAssignableFrom(value.getClass())) {
final Assembler asm = composite.get(type);
asm.assembleDto(dto, value, converters, dtoBeanFactory);
break;
}
}
}
}
}
/** {@inheritDoc} */
public void assembleDtos(final Collection dtos, final Collection entities,
final Map<String, Object> converters,
final BeanFactory dtoBeanFactory)
throws InvalidDtoCollectionException, UnableToCreateInstanceException, InspectionInvalidDtoInstanceException,
InspectionInvalidEntityInstanceException, BeanFactoryNotFoundException, BeanFactoryUnableToCreateInstanceException,
AnnotationMissingException, NotValueConverterException, ValueConverterNotFoundException,
CollectionEntityGenericReturnTypeException, InspectionScanningException, InspectionPropertyNotFoundException,
InspectionBindingNotFoundException, AnnotationMissingBindingException, AnnotationValidatingBindingException,
GeDARuntimeException, AnnotationDuplicateBindingException {
if (dtos instanceof Collection && dtos.isEmpty() && entities instanceof Collection) {
for (Object entity : entities) {
try {
final Object dto = this.dtoClass.newInstance();
assembleDto(dto, entity, converters, dtoBeanFactory);
dtos.add(dto);
} catch (InstantiationException exp) {
throw new UnableToCreateInstanceException(this.dtoClass.getCanonicalName(),
"Unable to create dto instance for: " + this.dtoClass.getName(), exp);
} catch (IllegalAccessException exp) {
throw new UnableToCreateInstanceException(this.dtoClass.getCanonicalName(),
"Unable to create dto instance for: " + this.dtoClass.getName(), exp);
}
}
} else {
throw new InvalidDtoCollectionException();
}
}
/** {@inheritDoc} */
public void assembleEntity(final Object dto, final Object entity,
final Map<String, Object> converters, final BeanFactory entityBeanFactory)
throws InspectionInvalidDtoInstanceException, InspectionInvalidEntityInstanceException, BeanFactoryNotFoundException,
BeanFactoryUnableToCreateInstanceException, NotEntityRetrieverException, EntityRetrieverNotFoundException,
NotValueConverterException, ValueConverterNotFoundException, AnnotationMissingBeanKeyException,
AnnotationMissingException, UnableToCreateInstanceException, CollectionEntityGenericReturnTypeException,
InspectionScanningException, InspectionPropertyNotFoundException, InspectionBindingNotFoundException,
AnnotationMissingBindingException, AnnotationValidatingBindingException, GeDARuntimeException,
AnnotationDuplicateBindingException, DtoToEntityMatcherNotFoundException, NotDtoToEntityMatcherException {
final Object[] values;
if (entity instanceof Object[]) {
values = (Object[]) entity;
} else {
values = new Object[] { entity };
}
for (final Object value : values) {
if (value != null) {
for (final Class type : composite.keySet()) {
if (type.isAssignableFrom(value.getClass())) {
final Assembler asm = composite.get(type);
asm.assembleEntity(dto, value, converters, entityBeanFactory);
break;
}
}
}
}
}
/** {@inheritDoc} */
public void assembleEntities(final Collection dtos, final Collection entities,
final Map<String, Object> converters, final BeanFactory entityBeanFactory)
throws UnableToCreateInstanceException, InvalidEntityCollectionException, InspectionInvalidDtoInstanceException,
InspectionInvalidEntityInstanceException, BeanFactoryNotFoundException, BeanFactoryUnableToCreateInstanceException,
NotEntityRetrieverException, EntityRetrieverNotFoundException, NotValueConverterException,
ValueConverterNotFoundException, AnnotationMissingBeanKeyException, AnnotationMissingException,
CollectionEntityGenericReturnTypeException, InspectionScanningException, InspectionPropertyNotFoundException,
InspectionBindingNotFoundException, AnnotationMissingBindingException, AnnotationValidatingBindingException,
GeDARuntimeException, AnnotationDuplicateBindingException, DtoToEntityMatcherNotFoundException,
NotDtoToEntityMatcherException {
throw new UnsupportedOperationException("Unsupported conversion of collection of composite DTO's to collection of entities");
}
/** {@inheritDoc} */
public void releaseResources() {
final Iterator<Map.Entry<Class, Assembler>> it = composite.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<Class, Assembler> entry = it.next();
entry.getValue().releaseResources();
it.remove();
}
}
}