Package com.inspiresoftware.lib.dto.geda.osgi.impl

Source Code of com.inspiresoftware.lib.dto.geda.osgi.impl.DTOSupportDSLServiceImpl

/*
* 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.osgi.impl;

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.assembler.Assembler;
import com.inspiresoftware.lib.dto.geda.assembler.DTOAssembler;
import com.inspiresoftware.lib.dto.geda.assembler.extension.DisposableContainer;
import com.inspiresoftware.lib.dto.geda.assembler.extension.MethodSynthesizer;
import com.inspiresoftware.lib.dto.geda.assembler.extension.impl.OSGiJavassistMethodSynthesizer;
import com.inspiresoftware.lib.dto.geda.dsl.Registries;
import com.inspiresoftware.lib.dto.geda.dsl.Registry;
import com.inspiresoftware.lib.dto.geda.event.DTOEventListener;
import com.inspiresoftware.lib.dto.geda.osgi.DTOSupportDSLService;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
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])
*
* <p/>
* User: denispavlov
* Date: Sep 27, 2011
* Time: 5:33:05 PM
*/
public class DTOSupportDSLServiceImpl implements DTOSupportDSLService, DisposableContainer {

    private final AdaptersRepository adaptersRepository = new AdaptersRepositoryImpl();
    private final Map<String, Registry> registryRepository = new ConcurrentHashMap<String, Registry>();

    private final MethodSynthesizer osgiJavassisstSynthesizer;
    private final Reference<ClassLoader> classLoader;

    private DTOEventListener onDtoAssembly;
    private DTOEventListener onEntityAssembly;

    private DTOEventListener onDtoAssembled;
    private DTOEventListener onDtoFailed;
    private DTOEventListener onEntityAssembled;
    private DTOEventListener onEntityFailed;

    public DTOSupportDSLServiceImpl(final ClassLoader classLoader) {

        this.classLoader = new SoftReference<ClassLoader>(classLoader);
        osgiJavassisstSynthesizer = new OSGiJavassistMethodSynthesizer(classLoader);

    }

    /** {@inheritDoc} */
    public <T> T assembleDto(final T dto, final Object entity, final Registry registry, final String context) {
        return assembleDto(null, dto, entity, registry, context);
    }

    /** {@inheritDoc} */
    public <T> T assembleDtoByKey(final String dtoKey,
                                  final Object entity,
                                  final Registry registry,
                                  final String context) {
        final Object dto = Registries.beanFactory(registry).get(dtoKey);
        if (dto == null) {
            throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoKey);
        }
        return (T) assembleDto(null, dto, entity, registry, context);
    }

    /** {@inheritDoc} */
    public <T> T assembleDto(final String dtoFilter,
                             final T dto,
                             final Object entity,
                             final Registry registry,
                             final String context) {
        final BeanFactory beanFactory = Registries.beanFactory(registry);
        final Class dtoClassFilter;
        if (dtoFilter == null) {
            dtoClassFilter = dto.getClass();
        } else {
            dtoClassFilter = 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);
            }

            DTOAssembler.newCustomAssembler(dtoClassFilter, entity.getClass(), classLoader.get(), registry, osgiJavassisstSynthesizer)
                    .assembleDto(dto, entity, this.adaptersRepository.getAll(), 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);

                return null;
            }
            throw re; // re-throw
        }
    }

    /** {@inheritDoc} */
    public <T> T assembleDtoByKey(final String dtoFilter,
                                  final String dtoKey,
                                  final Object entity,
                                  final Registry registry,
                                  final String context) {
        final Object dto = Registries.beanFactory(registry).get(dtoKey);
        if (dto == null) {
            throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoKey);
        }
        return (T) assembleDto(dtoFilter, dto, entity, registry, context);
    }

    /** {@inheritDoc} */
    public <T> void assembleDtos(final String keyDto,
                                 final Collection<T> dtos,
                                 final Collection entities,
                                 final Registry registry,
                                 final String context) {
        assembleDtos(null, keyDto, dtos, entities, registry, context);
    }

    /** {@inheritDoc} */
    public <T> void assembleDtos(final String dtoFilter,
                                 final String keyDto,
                                 final Collection<T> dtos,
                                 final Collection entities,
                                 final Registry registry,
                                 final String context) {
        if (entities != null && !entities.isEmpty()) {
            final BeanFactory beanFactory = Registries.beanFactory(registry);
            final Class dtoClassFilter;
            if (dtoFilter == null) {
                dtoClassFilter = beanFactory.getClazz(keyDto);
                if (dtoClassFilter == null) {
                    throw new IllegalArgumentException("DTO factory has no class specified for key: " + keyDto);
                }
            } else {
                dtoClassFilter = 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 = DTOAssembler.newCustomAssembler(dtoClassFilter, entityClass, classLoader.get(), registry, osgiJavassisstSynthesizer);

            for (final Object entity : entities) {
                final Object dto = 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.adaptersRepository.getAll(), 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);

                        continue;
                    }
                    throw re; // re-throw
                }
            }
        }
    }

    /** {@inheritDoc} */
    public <T> T assembleEntity(final Object dto,
                                final T entity,
                                final Registry registry,
                                final String context) {
        return assembleEntity(null, dto, entity, registry, context);
    }

    /** {@inheritDoc} */
    public <T> T assembleEntityByKey(final Object dto,
                                     final String entityKey,
                                     final Registry registry,
                                     final String context) {
        final Object entity = Registries.beanFactory(registry).get(entityKey);
        if (entity == null) {
            throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey);
        }
        return (T) assembleEntity(null, dto, entity, registry, context);
    }

    /** {@inheritDoc} */
    public <T> T assembleEntityByKey(final String dtoFilter,
                                     final Object dto,
                                     final String entityKey,
                                     final Registry registry,
                                     final String context) {
        final Object entity = Registries.beanFactory(registry).get(entityKey);
        if (entity == null) {
            throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey);
        }
        return (T) assembleEntity(dtoFilter, dto, entity, registry, context);
    }


    /** {@inheritDoc} */
    public <T> T assembleEntity(final String dtoFilter,
                                final Object dto,
                                final T entity,
                                final Registry registry,
                                final String context) {

        final BeanFactory beanFactory = Registries.beanFactory(registry);
        final Class dtoClassFilter;
        if (dtoFilter == null) {
            dtoClassFilter = dto.getClass();
        } else {
            dtoClassFilter = 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);
            }

            DTOAssembler.newCustomAssembler(dtoClassFilter, entity.getClass(), classLoader.get(), registry, osgiJavassisstSynthesizer)
                    .assembleEntity(dto, entity, this.adaptersRepository.getAll(), 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);

                return null;
            }
            throw re; // re-throw
        }
    }

    /** {@inheritDoc} */
    public <T> void assembleEntities(final String entityKey,
                                     final Collection dtos,
                                     final Collection<T> entities,
                                     final Registry registry,
                                     final String context) {
        assembleEntities(null, entityKey, dtos, entities, registry, context);


    }

    /** {@inheritDoc} */
    public <T> void assembleEntities(final String dtoFilter,
                                     final String entityKey,
                                     final Collection dtos,
                                     final Collection<T> entities,
                                     final Registry registry,
                                     final String context) {
        if (dtos != null && !dtos.isEmpty()) {
            final BeanFactory beanFactory = Registries.beanFactory(registry);
            final Class dtoClassFilter;
            if (dtoFilter == null) {
                dtoClassFilter = dtos.iterator().next().getClass();
            } else {
                dtoClassFilter = beanFactory.getClazz(dtoFilter);
                if (dtoClassFilter == null) {
                    throw new IllegalArgumentException("DTO factory has no class specified for key: " + dtoFilter);
                }
            }
            final Class entityClass =  beanFactory.getClazz(entityKey);
            if (entityClass == null) {
                throw new IllegalArgumentException("DTO factory has no class specified for key: " + entityKey);
            }

            final Assembler asm = DTOAssembler.newCustomAssembler(dtoClassFilter, entityClass, classLoader.get(), registry, osgiJavassisstSynthesizer);

            for (final Object dto : dtos) {
                final Object entity = 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.adaptersRepository.getAll(), 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);

                        continue;
                    }
                    throw re; // re-throw
                }
            }
        }
    }

    /** {@inheritDoc} */
    public void registerAdapter(final String key, final Object adapter) {

        this.adaptersRepository.registerAdapter(key, adapter);

    }

    /** {@inheritDoc} */
    public void addListener(final String dtoEvent, final DTOEventListener eventListener) {
        if ("OnDtoAssembled".equals(dtoEvent)) {
            this.setOnDtoAssembled(eventListener);
        } else if ("OnDtoFailed".equals(dtoEvent)) {
            this.setOnDtoFailed(eventListener);
        } else if ("OnDtoAssembly".equals(dtoEvent)) {
            this.setOnDtoAssembly(eventListener);
        } else if ("OnEntityAssembled".equals(dtoEvent)) {
            this.setOnEntityAssembled(eventListener);
        } else if ("OnEntityFailed".equals(dtoEvent)) {
            this.setOnEntityFailed(eventListener);
        } else if ("OnEntityAssembly".equals(dtoEvent)) {
            this.setOnEntityAssembly(eventListener);
        }
    }

    /** {@inheritDoc} */
    public void removeListener(final DTOEventListener eventListener) {
        if (eventListener == null) {
            return;
        }
        if (eventListener.equals(this.onDtoAssembled)) {
            this.setOnDtoAssembled(null);
        } else if (eventListener.equals(this.onDtoFailed)) {
            this.setOnDtoFailed(null);
        } else if (eventListener.equals(this.onDtoAssembly)) {
            this.setOnDtoAssembly(null);
        } else if (eventListener.equals(this.onEntityAssembled)) {
            this.setOnEntityAssembled(null);
        } else if (eventListener.equals(this.onEntityFailed)) {
            this.setOnEntityFailed(null);
        } else if (eventListener.equals(this.onEntityAssembly)) {
            this.setOnEntityAssembly(null);
        }
    }

    /**
     * @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;
    }

    /** {@inheritDoc} */
    public Registry getRegistry(final String namespace) {
        if (registryRepository.containsKey(namespace)) {
            return registryRepository.get(namespace);
        }
        return null;
    }

    /** {@inheritDoc} */
    public Registry createRegistry(final String namespace, final ExtensibleBeanFactory beanFactory) {
        if (registryRepository.containsKey(namespace)) {
            throw new IllegalArgumentException("DSL namespace [" + namespace + "] already used");
        }
        final Registry registry = Registries.registry(beanFactory);
        registryRepository.put(namespace, registry);
        return registry;
    }


    /** {@inheritDoc} */
    public void releaseResources() {

        osgiJavassisstSynthesizer.releaseResources();
        adaptersRepository.releaseResources();

        onDtoAssembly = null;
        onEntityAssembly = null;
        onDtoAssembled = null;
        onDtoFailed = null;
        onEntityAssembled = null;
        onEntityFailed = null;

        DTOAssembler.disposeOfDtoAssemblersBy(classLoader.get());

        classLoader.clear();

    }


}
TOP

Related Classes of com.inspiresoftware.lib.dto.geda.osgi.impl.DTOSupportDSLServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.