/* * 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.assembler.DSLUtils; import com.inspiresoftware.lib.dto.geda.dsl.*; import com.inspiresoftware.lib.dto.geda.exception.AnnotationDuplicateBindingException; 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:56 PM */ public class DtoEntityContextByClass extends DSLUtils implements DtoEntityContext { private final Class dtoClass; private final Class entityClass; private final ExtensibleBeanFactory beanFactory; private final DtoEntityContextAppender self = new DtoEntityContextAppender() { /** {@inheritDoc} */ public DtoEntityContext and() { return DtoEntityContextByClass.this; } }; private final Map<Integer, Object> fields = new ConcurrentHashMap<Integer, Object>(); public DtoEntityContextByClass(final Class dtoClass, final Class entityClass, final ExtensibleBeanFactory beanFactory) { this.dtoClass = dtoClass; this.entityClass = entityClass; this.beanFactory = beanFactory; } /** {@inheritDoc} */ public Class getDtoClass() { return dtoClass; } /** {@inheritDoc} */ public Class getEntityClass() { return entityClass; } /** {@inheritDoc} */ public DtoEntityContext alias(final String beanKey, final Class representative) { if (beanFactory == null) { throw new GeDARuntimeException("Alias for " + beanKey + " cannot be registered. Bean factory must be specified. Use constructor DefaultDSLRegistry(BeanFactory)"); } if (entityClass.isInterface()) { throw new GeDARuntimeException("No alias for " + beanKey + " as it is mapped to entity interface"); } if (representative == null) { this.beanFactory.registerEntity(beanKey, entityClass.getCanonicalName(), entityClass.getCanonicalName()); } else if (representative.isInterface() && representative.isAssignableFrom(entityClass)) { this.beanFactory.registerEntity(beanKey, entityClass.getCanonicalName(), representative.getCanonicalName()); } else { throw new GeDARuntimeException("Alias for " + beanKey + " has invalid interface for given entity class"); } return this; } /** {@inheritDoc} */ public DtoFieldContext withField(final String fieldName) { final int hash = fieldName.hashCode(); if (fields.containsKey(hash)) { final Object field = fields.get(hash); if (field instanceof DtoFieldContext) { return (DtoFieldContext) field; } throw new AnnotationDuplicateBindingException(dtoClass.getCanonicalName(), fieldName); } final DtoFieldContext field = new DtoFieldContextImpl(this, fieldName); fields.put(hash, field); return field; } /** {@inheritDoc} */ public DtoEntityContextAppender withFieldsSameAsIn(final String beanKey, final String... excluding) { if (beanFactory == null) { throw new GeDARuntimeException("Bean for key " + beanKey + " cannot be looked up. Bean factory must be specified. Use constructor DefaultDSLRegistry(BeanFactory)"); } final Class clazz = beanFactory.getClazz(beanKey); if (clazz == null) { throw new GeDARuntimeException("Bean for key " + beanKey + " is not in the bean factory"); } return withFieldsSameAsIn(clazz, excluding); } /** {@inheritDoc} */ public DtoEntityContextAppender withFieldsSameAsIn(final Class clazz, final String... excluding) { final Map<String, String> dtoFields = scanFieldNamesOnClass(getDtoClass()); if (excluding != null && excluding.length > 0) { for (final String exclude : excluding) { dtoFields.remove(exclude); } } final Map<String, String> entityFields; if (clazz.isInterface()) { entityFields = scanGetterNamesOnClass(clazz); } else { entityFields = scanFieldNamesOnClass(clazz); } for (final Map.Entry<String, String> dtoField : dtoFields.entrySet()) { final String entityFieldType = entityFields.get(dtoField.getKey()); if (entityFieldType != null && entityFieldType.equals(dtoField.getValue())) { // same name, same type - just map it with all defaults withField(dtoField.getKey()); } } return self; } /** {@inheritDoc} */ public DtoCollectionContext withCollection(final String fieldName) { final int hash = fieldName.hashCode(); if (fields.containsKey(hash)) { final Object field = fields.get(hash); if (field instanceof DtoCollectionContext) { return (DtoCollectionContext) field; } throw new AnnotationDuplicateBindingException(dtoClass.getCanonicalName(), fieldName); } final DtoCollectionContext field = new DtoCollectionContextImpl(this, fieldName); fields.put(hash, field); return field; } /** {@inheritDoc} */ public DtoMapContext withMap(final String fieldName) { final int hash = fieldName.hashCode(); if (fields.containsKey(hash)) { final Object field = fields.get(hash); if (field instanceof DtoMapContext) { return (DtoMapContext) field; } throw new AnnotationDuplicateBindingException(dtoClass.getCanonicalName(), fieldName); } final DtoMapContext field = new DtoMapContextImpl(this, fieldName); fields.put(hash, field); return field; } /** {@inheritDoc} */ public Object has(final String fieldName) { final int hash = fieldName.hashCode(); if (fields.containsKey(hash)) { return fields.get(hash); } return null; } }