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

com.enterprisemath.dao.object.BigEntityObjectCRUDDao Maven / Gradle / Ivy

package com.enterprisemath.dao.object;

import com.enterprisemath.dao.big.BigEntity;
import com.enterprisemath.dao.big.BigEntityDao;
import com.enterprisemath.dao.big.BigEntityIterator;
import com.enterprisemath.dao.big.BigEntityUpdate;
import com.enterprisemath.dao.big.DeleteOptions;
import com.enterprisemath.dao.big.InsertOptions;
import com.enterprisemath.dao.big.SelectOptions;
import com.enterprisemath.dao.big.UpdateOptions;
import com.enterprisemath.dao.filter.Criterium;
import com.enterprisemath.dao.filter.Filter;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * Implementation of data access layer through big entity.
 * Price for the generic block of code is performance and requirements for the code structures used within this implementation.
 * Requirements are following:
 * 
    *
  • Object has to have string property called key which is a unique identifier.
  • *
  • Filter columns must match the ones queried within a big entity.
  • *
* * @author radek.hecl */ public class BigEntityObjectCRUDDao implements ObjectCRUDDao { /** * Builder object. */ public static class Builder { /** * Data access layer for big entity. */ private BigEntityDao bigEntityDao; /** * Field filters. */ private List fieldFilters = new ArrayList(); /** * Sets big entity dao. * * @param bigEntityDao big entity dao * @return this instance */ public Builder setBigEntityDao(BigEntityDao bigEntityDao) { this.bigEntityDao = bigEntityDao; return this; } /** * Sets field filters. * * @param fieldFilters field filters * @return this instance */ public Builder setFieldFilters(List fieldFilters) { this.fieldFilters = DomainUtils.softCopyList(fieldFilters); return this; } /** * Adds field filter. * * @param fieldFilter field filter * @return this instance */ public Builder addFieldFilter(FieldFilter fieldFilter) { this.fieldFilters.add(fieldFilter); return this; } /** * Builds the result object. * * @return created object */ public BigEntityObjectCRUDDao build() { return new BigEntityObjectCRUDDao(this); } } /** * Data access layer for big entity. */ private BigEntityDao bigEntityDao; /** * Field filters. */ private List fieldFilters = new ArrayList(); /** * Creates new instance. * * @param builder builder object */ public BigEntityObjectCRUDDao(Builder builder) { bigEntityDao = builder.bigEntityDao; fieldFilters = DomainUtils.softCopyUnmodifiableList(builder.fieldFilters); guardInvariants(); } /** * Guards this object to be consistent. Throws exception if this is not the case. */ private void guardInvariants() { ValidationUtils.guardNotNull(bigEntityDao, "bigEntityDao cannot be null"); ValidationUtils.guardNotNullCollection(fieldFilters, "fieldFilters cannot be null"); } @Override public void insert(T object) { insert(object, Collections.emptyMap()); } @Override public void insert(T object, Map extra) { String type = BigEntityObjectCRUDDaoUtils.getType(object.getClass()); Map map = BigEntityObjectCRUDDaoUtils.getObjectFieldsAsMap(object); if (extra.containsKey("code")) { ValidationUtils.guardEquals(map.get("code"), extra.get("code"), "identification codes must be equal"); } map.putAll(extra); BigEntity ent = BigEntityObjectCRUDDaoUtils.encodeMapAsBigEntity(object.getClass(), map, fieldFilters); bigEntityDao.insertBigEntity(type, ent, InsertOptions.createDefault()); } @Override public void insert(T object, Object extraFirst, Object... extraOthers) { List extras = new ArrayList(); extras.add(extraFirst); extras.addAll(Arrays.asList(extraOthers)); String type = BigEntityObjectCRUDDaoUtils.getType(object.getClass()); Map map = BigEntityObjectCRUDDaoUtils.getObjectFieldsAsMap(object); for (Object extra : extras) { Map extraMap = BigEntityObjectCRUDDaoUtils.getObjectFieldsAsMap(extra); if (extraMap.containsKey("code")) { ValidationUtils.guardEquals(map.get("code"), extraMap.get("code"), "identification codes must be equal"); } map.putAll(extraMap); } BigEntity ent = BigEntityObjectCRUDDaoUtils.encodeMapAsBigEntity(object.getClass(), map, fieldFilters); bigEntityDao.insertBigEntity(type, ent, InsertOptions.createDefault()); } @Override public T selectSingle(Class clazz, F column, Object value) { Filter filter = new Filter.Builder(). addEqualCriterium(column, value). setFrom(0). setLimit(2). build(); List res = selectList(clazz, filter); if (res.isEmpty()) { throw new IllegalArgumentException("criterium doesn't match any record: " + column + " = " + value); } if (res.size() > 1) { throw new IllegalArgumentException("criterium matches more than one record: " + column + " = " + value); } return res.get(0); } @Override public T selectSingle(Class clazz, F column, Object value, T def) { Filter filter = new Filter.Builder(). addEqualCriterium(column, value). setFrom(0). setLimit(2). build(); List res = selectList(clazz, filter); if (res.isEmpty()) { return def; } if (res.size() > 1) { throw new IllegalArgumentException("criterium matches more than one record: " + column + " = " + value); } return res.get(0); } @Override public List selectList(Class clazz, Filter filter) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); Map> classFieldDefs = BigEntityObjectCRUDDaoUtils.getClassFieldDefinitions(clazz); Set entityFields = new HashSet(); for (String key : classFieldDefs.keySet()) { if (key.equals("code")) { continue; } entityFields.add(BigEntityObjectCRUDDaoUtils.encodeFieldName(key)); } Filter strFilter = BigEntityObjectCRUDDaoUtils.transformFilter(filter); BigEntityIterator iterator = bigEntityDao.selectBigEntities(type, strFilter, entityFields, SelectOptions.createDefault()); List res = new ArrayList(); while (iterator.isNextAvailable()) { Map fields = BigEntityObjectCRUDDaoUtils.decodeBigEntityAsMap( clazz, classFieldDefs, iterator.getNext(), fieldFilters); T obj = BigEntityObjectCRUDDaoUtils.buildObjectFromMap(clazz, fields); res.add(obj); } return res; } @Override public Map selectExtra(Class clazz, String code, Map> fields) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); Set entityFields = new HashSet(); for (String key : fields.keySet()) { if (key.equals("code")) { continue; } entityFields.add(BigEntityObjectCRUDDaoUtils.encodeFieldName(key)); } Filter filter = new Filter.Builder(). addEqualCriterium("code", code). setFrom(0). setLimit(1). build(); BigEntityIterator iterator = bigEntityDao.selectBigEntities(type, filter, entityFields, SelectOptions.createDefault()); return BigEntityObjectCRUDDaoUtils.decodeBigEntityAsMap(clazz, fields, iterator.getNext(), fieldFilters); } @Override public E selectExtra(Class clazz, String code, Class extraClazz) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); Map> classFieldDefs = BigEntityObjectCRUDDaoUtils.getClassFieldDefinitions(extraClazz); Set entityFields = new HashSet(); for (String key : classFieldDefs.keySet()) { if (key.equals("code")) { continue; } entityFields.add(BigEntityObjectCRUDDaoUtils.encodeFieldName(key)); } Filter filter = new Filter.Builder(). addEqualCriterium("code", code). setFrom(0). setLimit(1). build(); BigEntityIterator iterator = bigEntityDao.selectBigEntities(type, filter, entityFields, SelectOptions.createDefault()); Map map = BigEntityObjectCRUDDaoUtils.decodeBigEntityAsMap(clazz, classFieldDefs, iterator.getNext(), fieldFilters); return BigEntityObjectCRUDDaoUtils.buildObjectFromMap(extraClazz, map); } @Override public void update(T object) { String type = BigEntityObjectCRUDDaoUtils.getType(object.getClass()); Map map = BigEntityObjectCRUDDaoUtils.getObjectFieldsAsMap(object); BigEntityUpdate update = BigEntityObjectCRUDDaoUtils.encodeMapAsBigEntityUpdate(object.getClass(), map, fieldFilters); bigEntityDao.updateBigEntity(type, (String) map.get("code"), update, UpdateOptions.createDefault()); } @Override public void update(Class clazz, String code, Map fields) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); if (fields.containsKey("code")) { ValidationUtils.guardEquals(code, fields.get(code), "code from fields must be equal to the parameter"); } BigEntityUpdate update = BigEntityObjectCRUDDaoUtils.encodeMapAsBigEntityUpdate(clazz, fields, fieldFilters); bigEntityDao.updateBigEntity(type, code, update, UpdateOptions.createDefault()); } @Override public void update(Class clazz, String code, E update) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); Map map = BigEntityObjectCRUDDaoUtils.getObjectFieldsAsMap(update); if (map.containsKey("code")) { ValidationUtils.guardEquals(code, map.get("code"), "code from fields must be equal to the parameter"); } BigEntityUpdate updt = BigEntityObjectCRUDDaoUtils.encodeMapAsBigEntityUpdate(clazz, map, fieldFilters); bigEntityDao.updateBigEntity(type, code, updt, UpdateOptions.createDefault()); } @Override public void delete(Class clazz, String code) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); bigEntityDao.deleteBigEntity(type, code, DeleteOptions.createDefault()); } @Override public void deleteAll(Class clazz, Set> criteria) { String type = BigEntityObjectCRUDDaoUtils.getType(clazz); Set fields = Collections.emptySet(); Filter strFilter = BigEntityObjectCRUDDaoUtils.transformFilter(new Filter.Builder(). setCriteria(criteria). build()); BigEntityIterator iterator = bigEntityDao.selectBigEntities(type, strFilter, fields, SelectOptions.createDefault()); Set codes = new HashSet(); while (iterator.isNextAvailable()) { codes.add(iterator.getNext().getCode()); } for (String code : codes) { bigEntityDao.deleteBigEntity(type, code, DeleteOptions.createDefault()); } } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } /** * Creates default instance. * Default instance encodes string collections and maps into JSON texts. * * @param bigEntityDao data access layer for big entities * @return this instance */ public static BigEntityObjectCRUDDao create(BigEntityDao bigEntityDao) { return new BigEntityObjectCRUDDao.Builder(). setBigEntityDao(bigEntityDao). addFieldFilter(StringCollectionJSONFieldFilter.create()). addFieldFilter(StringMapJSONFieldFilter.create()). addFieldFilter(EnumStringFieldFilter.create()). build(); } /** * Creates default instance. * Default instance encodes string collections and maps into JSON texts. * * @param bigEntityDao data access layer for big entities * @param fieldFilters field filters * @return this instance */ public static BigEntityObjectCRUDDao create(BigEntityDao bigEntityDao, List fieldFilters) { return new BigEntityObjectCRUDDao.Builder(). setBigEntityDao(bigEntityDao). setFieldFilters(fieldFilters). build(); } }