/* * 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.dsl.impl; import com.inspiresoftware.lib.dto.geda.adapter.ExtensibleBeanFactory; import com.inspiresoftware.lib.dto.geda.dsl.DtoContext; import com.inspiresoftware.lib.dto.geda.dsl.DtoEntityContext; import com.inspiresoftware.lib.dto.geda.exception.BeanFactoryUnableToLocateRepresentationException; import com.inspiresoftware.lib.dto.geda.exception.GeDARuntimeException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * User: denispavlov * Date: 12-09-20 * Time: 1:30 PM */ public class DtoContextByClass implements DtoContext { private final Class dtoClass; private final ExtensibleBeanFactory beanFactory; private final Map<Integer, DtoEntityContext> contexts = new ConcurrentHashMap<Integer, DtoEntityContext>(); public DtoContextByClass(final Class dtoClass, final ExtensibleBeanFactory beanFactory) { this.dtoClass = dtoClass; this.beanFactory = beanFactory; } /** {@inheritDoc} */ public Class getDtoClass() { return dtoClass; } /** {@inheritDoc} */ public DtoContext alias(final String beanKey) { if (beanFactory == null) { throw new GeDARuntimeException("Alias for " + beanKey + " cannot be registered. Bean factory must be specified. Use constructor DefaultDSLRegistry(BeanFactory)"); } this.beanFactory.registerDto(beanKey, dtoClass.getCanonicalName()); return this; } /** {@inheritDoc} */ public DtoEntityContext forEntity(final Class entityClass) { if (entityClass == null) { throw new GeDARuntimeException("entityClass must not be null"); } final int hash = entityClass.hashCode(); if (contexts.containsKey(hash)) { return contexts.get(hash); } final DtoEntityContext ctx = new DtoEntityContextByClass(dtoClass, entityClass, beanFactory); contexts.put(hash, ctx); return ctx; } /** {@inheritDoc} */ public DtoEntityContext forEntity(final Object entityInstance) { if (entityInstance == null) { throw new GeDARuntimeException("entityInstance must not be null"); } return forEntity(entityInstance.getClass()); } /** {@inheritDoc} */ public DtoEntityContext forEntity(final String beanKey) { if (beanFactory == null) { throw new GeDARuntimeException("Bean factory must be specified. Use constructor DefaultDSLRegistry(BeanFactory)"); } final Class representative = beanFactory.getClazz(beanKey); if (representative == null) { throw new BeanFactoryUnableToLocateRepresentationException(beanFactory.toString(), "top level", beanKey, false); } return forEntity(representative); } /** {@inheritDoc} */ public DtoEntityContext forEntityGeneric() { return forEntity(Object.class); } /** {@inheritDoc} */ public DtoEntityContext has(final Class entityClass) { if (entityClass == null) { throw new GeDARuntimeException("entityClass must not be null"); } int hash = entityClass.hashCode(); if (contexts.containsKey(hash)) { return contexts.get(hash); } // try immediate interfaces for (Class iFace : entityClass.getInterfaces()) { hash = iFace.hashCode(); if (contexts.containsKey(hash)) { return contexts.get(hash); } } // try superclass for proxies and wrappers if (entityClass.getSuperclass() != null) { hash = entityClass.getSuperclass().hashCode(); if (contexts.containsKey(hash)) { return contexts.get(hash); } } // try generic context (if one was provided) hash = Object.class.hashCode(); if (contexts.containsKey(hash)) { return contexts.get(hash); } // no context for this entity return null; } /** {@inheritDoc} */ public DtoEntityContext useContextFor(final DtoEntityContext ctx, final Class entityClass) { if (!contexts.containsValue(ctx)) { throw new IllegalArgumentException("This dto does not have a mapping for context with entity: " + ctx.getEntityClass()); } int hash = entityClass.hashCode(); contexts.put(hash, ctx); return ctx; } /** {@inheritDoc} */ public DtoEntityContext useContextFor(final DtoEntityContext ctx, final String beanKey) { if (!contexts.containsValue(ctx)) { throw new IllegalArgumentException("This dto does not have a mapping for context with entity: " + ctx.getEntityClass()); } if (beanFactory == null) { throw new GeDARuntimeException("Bean factory must be specified. Use constructor DefaultDSLRegistry(BeanFactory)"); } final Class representative = beanFactory.getClazz(beanKey); if (representative == null) { throw new BeanFactoryUnableToLocateRepresentationException(beanFactory.toString(), "top level", beanKey, false); } return useContextFor(ctx, representative); } }