All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.inspiresoftware.lib.dto.geda.impl.DTOSupportImpl Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
/*
 * 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.inspire-software.com
 * SVN: https://geda-genericdto.svn.sourceforge.net/svnroot/geda-genericdto
 */

package com.inspiresoftware.lib.dto.geda.impl;

import com.inspiresoftware.lib.dto.geda.DTOAdaptersRegistrar;
import com.inspiresoftware.lib.dto.geda.DTODSLRegistrar;
import com.inspiresoftware.lib.dto.geda.DTOSupport;
import com.inspiresoftware.lib.dto.geda.adapter.BeanFactory;
import com.inspiresoftware.lib.dto.geda.adapter.ExtensibleBeanFactory;
import com.inspiresoftware.lib.dto.geda.adapter.repository.AdaptersRepository;
import com.inspiresoftware.lib.dto.geda.adapter.repository.impl.AdaptersRepositoryImpl;
import com.inspiresoftware.lib.dto.geda.annotations.Dto;
import com.inspiresoftware.lib.dto.geda.assembler.Assembler;
import com.inspiresoftware.lib.dto.geda.assembler.DTOAssembler;
import com.inspiresoftware.lib.dto.geda.assembler.dsl.Registry;
import com.inspiresoftware.lib.dto.geda.assembler.dsl.impl.DefaultDSLRegistry;
import com.inspiresoftware.lib.dto.geda.event.DTOEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Basic implementation of the DTOSupport interface that provides the connection point
 * between Spring AOP and the GeDA assembler worlds.
 *
 * This particular implementation supports the following context listeners:
 * onDtoAssembly - fired just before transfer takes place
 * onEntityAssembly - fired just before transfer takes place
 * onDtoAssembled - fired immediately after assembly
 * onDtoFailed - fired immediately after failed assembly
 * onEntityAssembled - fired immediately after assembly
 * onEntityFailed - fired immediately after failed assembly
 *
 * All event listeners provided with the following context:
 * listener.onEvent(context, DTO, Entity [, Throwable])
 *
 * 

* User: denispavlov * Date: Sep 27, 2011 * Time: 5:33:05 PM */ public class DTOSupportImpl implements DTOSupport, InitializingBean { private static final Logger LOG = LoggerFactory.getLogger(DTOSupportImpl.class); private BeanFactory beanFactory; private DTOAdaptersRegistrar adaptersRegistrar; private DTODSLRegistrar dslRegistrar; private final AdaptersRepository dtoValueConverters = new AdaptersRepositoryImpl(); private Registry dslRegistry = new DefaultDSLRegistry(); private DTOEventListener onDtoAssembly; private DTOEventListener onEntityAssembly; private DTOEventListener onDtoAssembled; private DTOEventListener onDtoFailed; private DTOEventListener onEntityAssembled; private DTOEventListener onEntityFailed; private final Map isClassAnnotatedCache = new ConcurrentHashMap(); public void setBeanFactory(final ExtensibleBeanFactory beanFactory) { this.beanFactory = beanFactory; this.dslRegistry = new DefaultDSLRegistry(beanFactory); } public void setAdaptersRegistrar(final DTOAdaptersRegistrar adaptersRegistrar) { this.adaptersRegistrar = adaptersRegistrar; } public void setDslRegistrar(final DTODSLRegistrar dslRegistrar) { this.dslRegistrar = dslRegistrar; } public void afterPropertiesSet() throws Exception { this.registerCoreAdapters(); this.registerDSLMappings(); } /** * Extension hook to register mappings via DSL registry immediately after * bean construction. */ protected void registerDSLMappings() { if (this.dslRegistrar != null) { this.dslRegistrar.registerMappings(this, this.dslRegistry); } } /** * Extension hook to register converters, retrievers and matchers immediately after * bean construction. */ protected void registerCoreAdapters() { if (this.adaptersRegistrar != null) { this.adaptersRegistrar.registerAdapters(this); } } /** {@inheritDoc} */ public T assembleDto(final T dto, final Object entity, final String context) { return assembleDto(null, dto, entity, context); } /** {@inheritDoc} */ public T assembleDtoByKey(final String dtoKey, final Object entity, final String context) { final Object dto = this.beanFactory.get(dtoKey); if (dto == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoKey); } return (T) assembleDto(null, dto, entity, context); } /** {@inheritDoc} */ public T assembleDto(final String dtoFilter, final T dto, final Object entity, final String context) { final Class dtoClassFilter; if (dtoFilter == null) { dtoClassFilter = dto.getClass(); } else { dtoClassFilter = this.beanFactory.getClazz(dtoFilter); if (dtoClassFilter == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoFilter); } } try { if (this.onDtoAssembly != null) { this.onDtoAssembly.onEvent(context, dto, entity); } if (isAnnotatedClass(dtoClassFilter)) { DTOAssembler.newAssembler(dtoClassFilter, entity.getClass()) .assembleDto(dto, entity, this.dtoValueConverters.getAll(), this.beanFactory); } else { DTOAssembler.newAssembler(dtoClassFilter, entity.getClass(), dslRegistry) .assembleDto(dto, entity, this.dtoValueConverters.getAll(), this.beanFactory); } if (this.onDtoAssembled != null) { this.onDtoAssembled.onEvent(context, dto, entity); } return dto; } catch (final RuntimeException re) { if (this.onDtoFailed != null) { this.onDtoFailed.onEvent(context, dto, entity, re); LOG.error("Exception skipped by event listener", re); return null; } throw re; // re-throw } } /** {@inheritDoc} */ public T assembleDtoByKey(final String dtoFilter, final String dtoKey, final Object entity, final String context) { final Object dto = this.beanFactory.get(dtoKey); if (dto == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoKey); } return (T) assembleDto(dtoFilter, dto, entity, context); } /** {@inheritDoc} */ public void assembleDtos(final String keyDto, final Collection dtos, final Collection entities, final String context) { assembleDtos(null, keyDto, dtos, entities, context); } /** {@inheritDoc} */ public void assembleDtos(final String dtoFilter, final String keyDto, final Collection dtos, final Collection entities, final String context) { if (!CollectionUtils.isEmpty(entities)) { final Class dtoClassFilter; if (dtoFilter == null) { dtoClassFilter = this.beanFactory.getClazz(keyDto); if (dtoClassFilter == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + keyDto); } } else { dtoClassFilter = this.beanFactory.getClazz(dtoFilter); if (dtoClassFilter == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoFilter); } } final Class entityClass = entities.iterator().next().getClass(); final Assembler asm; if (isAnnotatedClass(dtoClassFilter)) { asm = DTOAssembler.newAssembler(dtoClassFilter, entityClass); } else { asm = DTOAssembler.newAssembler(dtoClassFilter, entityClass, dslRegistry); } for (final Object entity : entities) { final Object dto = this.beanFactory.get(keyDto); if (dto == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + keyDto); } try { if (this.onDtoAssembly != null) { this.onDtoAssembly.onEvent(context, dto, entity); } asm.assembleDto(dto, entity, this.dtoValueConverters.getAll(), this.beanFactory); dtos.add((T) dto); if (this.onDtoAssembled != null) { this.onDtoAssembled.onEvent(context, dto, entity); } } catch (final RuntimeException re) { if (this.onDtoFailed != null) { this.onDtoFailed.onEvent(context, dto, entity, re); LOG.error("Exception skipped by event listener", re); continue; } throw re; // re-throw } } } } /** {@inheritDoc} */ public T assembleEntity(final Object dto, final T entity, final String context) { return assembleEntity(null, dto, entity, context); } /** {@inheritDoc} */ public T assembleEntityByKey(final Object dto, final String entityKey, final String context) { final Object entity = this.beanFactory.get(entityKey); if (entity == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey); } return (T) assembleEntity(null, dto, entity, context); } /** {@inheritDoc} */ public T assembleEntityByKey(final String dtoFilter, final Object dto, final String entityKey, final String context) { final Object entity = this.beanFactory.get(entityKey); if (entity == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey); } return (T) assembleEntity(dtoFilter, dto, entity, context); } /** {@inheritDoc} */ public T assembleEntity(final String dtoFilter, final Object dto, final T entity, final String context) { final Class dtoClassFilter; if (dtoFilter == null) { dtoClassFilter = dto.getClass(); } else { dtoClassFilter = this.beanFactory.getClazz(dtoFilter); if (dtoClassFilter == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoFilter); } } try { if (this.onEntityAssembly != null) { this.onEntityAssembly.onEvent(context, dto, entity); } if (isAnnotatedClass(dtoClassFilter)) { DTOAssembler.newAssembler(dtoClassFilter, entity.getClass()) .assembleEntity(dto, entity, this.dtoValueConverters.getAll(), this.beanFactory); } else { DTOAssembler.newAssembler(dtoClassFilter, entity.getClass(), dslRegistry) .assembleEntity(dto, entity, this.dtoValueConverters.getAll(), this.beanFactory); } if (this.onEntityAssembled != null) { this.onEntityAssembled.onEvent(context, dto, entity); } return entity; } catch (final RuntimeException re) { if (this.onEntityFailed != null) { this.onEntityFailed.onEvent(context, dto, entity, re); LOG.error("Exception skipped by event listener", re); return null; } throw re; // re-throw } } /** {@inheritDoc} */ public void assembleEntities(final String entityKey, final Collection dtos, final Collection entities, final String context) { assembleEntities(null, entityKey, dtos, entities, context); } /** {@inheritDoc} */ public void assembleEntities(final String dtoFilter, final String entityKey, final Collection dtos, final Collection entities, final String context) { if (!CollectionUtils.isEmpty(dtos)) { final Class dtoClassFilter; if (dtoFilter == null) { dtoClassFilter = dtos.iterator().next().getClass(); } else { dtoClassFilter = this.beanFactory.getClazz(dtoFilter); if (dtoClassFilter == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoFilter); } } final Class entityClass = this.beanFactory.getClazz(entityKey); if (entityClass == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey); } final Assembler asm; if (isAnnotatedClass(dtoClassFilter)) { asm = DTOAssembler.newAssembler(dtoClassFilter, entityClass); } else { asm = DTOAssembler.newAssembler(dtoClassFilter, entityClass, dslRegistry); } for (final Object dto : dtos) { final Object entity = this.beanFactory.get(entityKey); if (entity == null) { throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey); } try { if (this.onEntityAssembly != null) { this.onEntityAssembly.onEvent(context, dto, entity); } asm.assembleEntity(dto, entity, this.dtoValueConverters.getAll(), this.beanFactory); entities.add((T) entity); if (this.onEntityAssembled != null) { this.onEntityAssembled.onEvent(context, dto, entity); } } catch (final RuntimeException re) { if (this.onEntityFailed != null) { this.onEntityFailed.onEvent(context, dto, entity, re); LOG.error("Exception skipped by event listener", re); continue; } throw re; // re-throw } } } } /** {@inheritDoc} */ public void registerAdapter(final String key, final Object converter) { LOG.debug("Registering [{}] with key [{}]", converter, key); this.dtoValueConverters.registerAdapter(key, converter); } /** * @param onDtoAssembled listener invoked after assembly */ public void setOnDtoAssembled(final DTOEventListener onDtoAssembled) { this.onDtoAssembled = onDtoAssembled; } /** * @param onDtoFailed listener invoked after failed assembly */ public void setOnDtoFailed(final DTOEventListener onDtoFailed) { this.onDtoFailed = onDtoFailed; } /** * @param onEntityAssembled listener invoked after assembly */ public void setOnEntityAssembled(final DTOEventListener onEntityAssembled) { this.onEntityAssembled = onEntityAssembled; } /** * @param onEntityFailed listener */ public void setOnEntityFailed(final DTOEventListener onEntityFailed) { this.onEntityFailed = onEntityFailed; } /** * @param onDtoAssembly listener invoked before assembly */ public void setOnDtoAssembly(final DTOEventListener onDtoAssembly) { this.onDtoAssembly = onDtoAssembly; } /** * @param onEntityAssembly listener invoked before assembly */ public void setOnEntityAssembly(final DTOEventListener onEntityAssembly) { this.onEntityAssembly = onEntityAssembly; } private Boolean isAnnotatedClass(final Class clazz) { final Integer classHash = Integer.valueOf(clazz.hashCode()); Boolean isAnn; if (isClassAnnotatedCache.containsKey(classHash)) { isAnn = isClassAnnotatedCache.get(classHash); } else { isAnn = Boolean.valueOf(clazz.getAnnotation(Dto.class) != null); isClassAnnotatedCache.put(classHash, isAnn); } return isAnn; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy