Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java Wed Aug 3 16:12:58 2011 @@ -52,6 +52,7 @@ import org.ofbiz.entity.GenericEntityExc import org.ofbiz.entity.GenericModelException; import org.ofbiz.entity.GenericNotImplementedException; import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.condition.EntityCondition; import org.ofbiz.entity.condition.EntityConditionParam; import org.ofbiz.entity.condition.OrderByList; import org.ofbiz.entity.config.DatasourceInfo; @@ -73,7 +74,7 @@ public class SqlJdbcUtil { public static final int CHAR_BUFFER_SIZE = 4096; /** Makes the FROM clause and when necessary the JOIN clause(s) as well */ - public static String makeFromClause(ModelEntity modelEntity, DatasourceInfo datasourceInfo) throws GenericEntityException { + public static String makeFromClause(ModelEntity modelEntity, ModelFieldTypeReader modelFieldTypeReader, DatasourceInfo datasourceInfo) throws GenericEntityException { StringBuilder sql = new StringBuilder(" FROM "); if (modelEntity instanceof ModelViewEntity) { @@ -119,7 +120,7 @@ public class SqlJdbcUtil { if (i == 0) { // this is the first referenced member alias, so keep track of it for future use... - restOfStatement.append(makeViewTable(linkEntity, datasourceInfo)); + restOfStatement.append(makeViewTable(linkEntity, modelFieldTypeReader, datasourceInfo)); //another possible one that some dbs might need, but not sure of any yet: restOfStatement.append(" AS "); restOfStatement.append(" "); restOfStatement.append(viewLink.getEntityAlias()); @@ -140,7 +141,7 @@ public class SqlJdbcUtil { restOfStatement.append(" INNER JOIN "); } - restOfStatement.append(makeViewTable(relLinkEntity, datasourceInfo)); + restOfStatement.append(makeViewTable(relLinkEntity, modelFieldTypeReader, datasourceInfo)); //another possible one that some dbs might need, but not sure of any yet: restOfStatement.append(" AS "); restOfStatement.append(" "); restOfStatement.append(viewLink.getRelEntityAlias()); @@ -165,20 +166,26 @@ public class SqlJdbcUtil { condBuffer.append(viewLink.getEntityAlias()); condBuffer.append("."); - condBuffer.append(filterColName(linkField.getColName())); + condBuffer.append(linkField.getColName()); condBuffer.append(" = "); condBuffer.append(viewLink.getRelEntityAlias()); condBuffer.append("."); - condBuffer.append(filterColName(relLinkField.getColName())); + condBuffer.append(relLinkField.getColName()); } if (condBuffer.length() == 0) { throw new GenericModelException("No view-link/join key-maps found for the " + viewLink.getEntityAlias() + " and the " + viewLink.getRelEntityAlias() + " member-entities of the " + modelViewEntity.getEntityName() + " view-entity."); } - // TODO add expression from entity-condition on view-link - + ModelViewEntity.ViewEntityCondition viewEntityCondition = viewLink.getViewEntityCondition(); + if (viewEntityCondition != null) { + EntityCondition whereCondition = viewEntityCondition.getWhereCondition(modelFieldTypeReader, null); + if (whereCondition != null) { + condBuffer.append(" AND "); + condBuffer.append(whereCondition.makeWhereString(modelEntity, null, datasourceInfo)); + } + } restOfStatement.append(condBuffer.toString()); @@ -198,7 +205,7 @@ public class SqlJdbcUtil { if (!fromEmpty) sql.append(", "); fromEmpty = false; - sql.append(makeViewTable(fromEntity, datasourceInfo)); + sql.append(makeViewTable(fromEntity, modelFieldTypeReader, datasourceInfo)); sql.append(" "); sql.append(aliasName); } @@ -213,7 +220,7 @@ public class SqlJdbcUtil { String aliasName = meIter.next(); ModelEntity fromEntity = modelViewEntity.getMemberModelEntity(aliasName); - sql.append(makeViewTable(fromEntity, datasourceInfo)); + sql.append(makeViewTable(fromEntity, modelFieldTypeReader, datasourceInfo)); sql.append(" "); sql.append(aliasName); if (meIter.hasNext()) sql.append(", "); @@ -258,7 +265,7 @@ public class SqlJdbcUtil { ModelField modelField = null; if (item instanceof ModelField) { modelField = (ModelField) item; - sb.append(modelField.getColName()); + sb.append(modelField.getColValue()); name = modelField.getName(); } else { sb.append(item); @@ -347,7 +354,7 @@ public class SqlJdbcUtil { } whereString.append(viewLink.getEntityAlias()); whereString.append("."); - whereString.append(filterColName(linkField.getColName())); + whereString.append(linkField.getColName()); // check to see whether the left or right members are optional, if so: // oracle: use the (+) on the optional side @@ -362,7 +369,7 @@ public class SqlJdbcUtil { whereString.append(viewLink.getRelEntityAlias()); whereString.append("."); - whereString.append(filterColName(relLinkField.getColName())); + whereString.append(relLinkField.getColName()); } } } else { @@ -394,7 +401,7 @@ public class SqlJdbcUtil { return sql.toString(); } - public static String makeViewTable(ModelEntity modelEntity, DatasourceInfo datasourceInfo) throws GenericEntityException { + public static String makeViewTable(ModelEntity modelEntity, ModelFieldTypeReader modelFieldTypeReader, DatasourceInfo datasourceInfo) throws GenericEntityException { if (modelEntity instanceof ModelViewEntity) { StringBuilder sql = new StringBuilder("(SELECT "); Iterator<ModelField> fieldsIter = modelEntity.getFieldsIterator(); @@ -402,16 +409,16 @@ public class SqlJdbcUtil { ModelField curField = fieldsIter.next(); sql.append(curField.getColValue()); sql.append(" AS "); - sql.append(filterColName(curField.getColName())); + sql.append(curField.getColName()); while (fieldsIter.hasNext()) { curField = fieldsIter.next(); sql.append(", "); sql.append(curField.getColValue()); sql.append(" AS "); - sql.append(filterColName(curField.getColName())); + sql.append(curField.getColName()); } } - sql.append(makeFromClause(modelEntity, datasourceInfo)); + sql.append(makeFromClause(modelEntity, modelFieldTypeReader, datasourceInfo)); String viewWhereClause = makeViewWhereClause(modelEntity, datasourceInfo.joinStyle); if (UtilValidate.isNotEmpty(viewWhereClause)) { sql.append(" WHERE "); Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/DynamicViewEntity.java URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/DynamicViewEntity.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/DynamicViewEntity.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/DynamicViewEntity.java Wed Aug 3 16:12:58 2011 @@ -20,6 +20,7 @@ package org.ofbiz.entity.model; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -228,8 +229,16 @@ public class DynamicViewEntity { return this.memberModelMemberEntities.entrySet().iterator(); } + /** + * @deprecated use {@link #addAliasAll(String, String, Collection<String>)} + */ + @Deprecated public void addAliasAll(String entityAlias, String prefix) { - ModelAliasAll aliasAll = new ModelAliasAll(entityAlias, prefix); + addAliasAll(entityAlias, prefix, null); + } + + public void addAliasAll(String entityAlias, String prefix, Collection<String> excludes) { + ModelAliasAll aliasAll = new ModelAliasAll(entityAlias, prefix, false, null, null, excludes); this.aliasAlls.add(aliasAll); } @@ -243,10 +252,14 @@ public class DynamicViewEntity { /** Add an alias, full detail. All parameters can be null except entityAlias and name. */ public void addAlias(String entityAlias, String name, String field, String colAlias, Boolean primKey, Boolean groupBy, String function) { - addAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, null); + addAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, null, null); } public void addAlias(String entityAlias, String name, String field, String colAlias, Boolean primKey, Boolean groupBy, String function, ComplexAliasMember complexAliasMember) { + addAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, null, complexAliasMember); + } + + public void addAlias(String entityAlias, String name, String field, String colAlias, Boolean primKey, Boolean groupBy, String function, String fieldSet, ComplexAliasMember complexAliasMember) { if (entityAlias == null && complexAliasMember == null) { throw new IllegalArgumentException("entityAlias cannot be null if this is not a complex alias in call to DynamicViewEntity.addAlias"); } @@ -254,7 +267,7 @@ public class DynamicViewEntity { throw new IllegalArgumentException("name cannot be null in call to DynamicViewEntity.addAlias"); } - ModelAlias alias = new ModelAlias(entityAlias, name, field, colAlias, primKey, groupBy, function); + ModelAlias alias = new ModelAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, fieldSet); if (complexAliasMember != null) { alias.setComplexAliasMember(complexAliasMember); } @@ -266,7 +279,7 @@ public class DynamicViewEntity { } public void addViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, List<ModelKeyMap> modelKeyMaps) { - ModelViewLink modelViewLink = new ModelViewLink(entityAlias, relEntityAlias, relOptional, modelKeyMaps); + ModelViewLink modelViewLink = new ModelViewLink(entityAlias, relEntityAlias, relOptional, null, modelKeyMaps); this.viewLinks.add(modelViewLink); } Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelField.java URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelField.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelField.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelField.java Wed Aug 3 16:12:58 2011 @@ -55,6 +55,9 @@ public class ModelField extends ModelChi protected boolean isAutoCreatedInternal = false; protected boolean enableAuditLog = false; + /** when any field in the same set is selected in a query, all fields in that set will be selected */ + protected String fieldSet = ""; + /** validators to be called when an update is done */ protected List<String> validators = new ArrayList<String>(); @@ -85,6 +88,7 @@ public class ModelField extends ModelChi this.description = UtilXml.childElementValue(fieldElement, "description"); this.enableAuditLog = UtilXml.checkBoolean(fieldElement.getAttribute("enable-audit-log"), false); this.isNotNull = UtilXml.checkBoolean(fieldElement.getAttribute("not-null"), false); + this.fieldSet = UtilXml.checkEmpty(fieldElement.getAttribute("field-set")).intern(); NodeList validateList = fieldElement.getElementsByTagName("validate"); @@ -184,6 +188,14 @@ public class ModelField extends ModelChi this.isAutoCreatedInternal = isAutoCreatedInternal; } + public String getFieldSet() { + return fieldSet; + } + + public void setFieldSet(String fieldSet) { + this.fieldSet = fieldSet; + } + /** validators to be called when an update is done */ public String getValidator(int index) { return this.validators.get(index); Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelViewEntity.java URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelViewEntity.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelViewEntity.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/model/ModelViewEntity.java Wed Aug 3 16:12:58 2011 @@ -21,6 +21,7 @@ package org.ofbiz.entity.model; import java.io.Serializable; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -92,7 +93,7 @@ public class ModelViewEntity extends Mod /** List of field names to group by */ protected List<String> groupByFields = FastList.newInstance(); - protected Map<String, Map<String, ModelConversion>> conversions = FastMap.newInstance(); + protected Map<String, ModelConversion[]> conversions = FastMap.newInstance(); protected ViewEntityCondition viewEntityCondition = null; @@ -107,7 +108,7 @@ public class ModelViewEntity extends Mod String alias = UtilXml.checkEmpty(memberEntityElement.getAttribute("entity-alias")).intern(); String name = UtilXml.checkEmpty(memberEntityElement.getAttribute("entity-name")).intern(); if (name.length() <= 0 || alias.length() <= 0) { - Debug.logError("[new ModelViewEntity] entity-alias or entity-name missing on member-entity element of the view-entity " + this.entityName, module); + Debug.logError("[new ModelViewEntity]: entity-alias or entity-name missing on member-entity element of the view-entity " + this.entityName, module); } else { ModelMemberEntity modelMemberEntity = new ModelMemberEntity(alias, name); this.addMemberModelMemberEntity(modelMemberEntity); @@ -377,14 +378,14 @@ public class ModelViewEntity extends Mod public ModelEntity getAliasedEntity(String entityAlias, ModelReader modelReader) { ModelMemberEntity modelMemberEntity = this.memberModelMemberEntities.get(entityAlias); if (modelMemberEntity == null) { - Debug.logError("No member entity with alias " + entityAlias + " found in view-entity " + this.getEntityName() + "; this view-entity will NOT be usable...", module); + Debug.logError("[" + this.getEntityName() + "]: No member entity with alias " + entityAlias + " found; this view-entity will NOT be usable...", module); return null; } String aliasedEntityName = modelMemberEntity.getEntityName(); ModelEntity aliasedEntity = modelReader.getModelEntityNoCheck(aliasedEntityName); if (aliasedEntity == null) { - Debug.logError("[ModelViewEntity.populateFields] ERROR: could not find ModelEntity for entity name: " + aliasedEntityName, module); + Debug.logError("[" + this.getEntityName() + "]: [ModelViewEntity.populateFields] ERROR: could not find ModelEntity for entity name: " + aliasedEntityName, module); return null; } @@ -394,7 +395,7 @@ public class ModelViewEntity extends Mod public ModelField getAliasedField(ModelEntity aliasedEntity, String field, ModelReader modelReader) { ModelField aliasedField = aliasedEntity.getField(field); if (aliasedField == null) { - Debug.logError("[ModelViewEntity.populateFields] ERROR: could not find ModelField for entity name: " + aliasedEntity.getEntityName() + " and field: " + field, module); + Debug.logError("[" + this.getEntityName() + "]: [ModelViewEntity.populateFields] ERROR: could not find ModelField for entity name: " + aliasedEntity.getEntityName() + " and field: " + field, module); return null; } return aliasedField; @@ -446,7 +447,7 @@ public class ModelViewEntity extends Mod // show a warning if function is specified and groupBy is true if (UtilValidate.isNotEmpty(alias.function) && alias.groupBy) { - Debug.logWarning("The view-entity alias with name=" + alias.name + " has a function value and is specified as a group-by field; this may be an error, but is not necessarily.", module); + Debug.logWarning("[" + this.getEntityName() + "]: The view-entity alias with name=" + alias.name + " has a function value and is specified as a group-by field; this may be an error, but is not necessarily.", module); } if (alias.isComplexAlias()) { @@ -458,11 +459,12 @@ public class ModelViewEntity extends Mod field.colName = ModelUtil.javaNameToDbName(alias.name); field.type = fieldTypeBuffer.toString(); field.isPk = false; + field.fieldSet = alias.getFieldSet(); } else { ModelEntity aliasedEntity = getAliasedEntity(alias.entityAlias, modelReader); ModelField aliasedField = getAliasedField(aliasedEntity, alias.field, modelReader); if (aliasedField == null) { - Debug.logError("[ModelViewEntity.populateFields (" + this.getEntityName() + ")] ERROR: could not find ModelField for field name \"" + + Debug.logError("[" + this.getEntityName() + "]: [populateFields] ERROR: could not find ModelField for field name \"" + alias.field + "\" on entity with name: " + aliasedEntity.getEntityName(), module); continue; } @@ -478,10 +480,26 @@ public class ModelViewEntity extends Mod field.type = aliasedField.type; field.validators = aliasedField.validators; - field.colName = alias.entityAlias + "." + SqlJdbcUtil.filterColName(aliasedField.colName); + field.colValue = alias.entityAlias + "." + SqlJdbcUtil.filterColName(aliasedField.colName); + field.colName = SqlJdbcUtil.filterColName(field.colValue); if (UtilValidate.isEmpty(field.description)) { field.description = aliasedField.description; } + if (UtilValidate.isEmpty(alias.getFieldSet())) { + String aliasedFieldSet = aliasedField.getFieldSet(); + if (UtilValidate.isNotEmpty(aliasedFieldSet)) { + StringBuilder fieldSetBuffer = new StringBuilder(alias.entityAlias); + fieldSetBuffer.append("_"); + fieldSetBuffer.append(Character.toUpperCase(aliasedFieldSet.charAt(0))); + fieldSetBuffer.append(aliasedFieldSet.substring(1)); + field.fieldSet = fieldSetBuffer.toString().intern(); + Debug.logInfo("[" + this.getEntityName() + "]: copied field set on [" + field.name + "]: " + field.fieldSet, module); + } else { + field.fieldSet = ""; + } + } else { + field.fieldSet = alias.getFieldSet(); + } } this.fields.add(field); @@ -499,7 +517,7 @@ public class ModelViewEntity extends Mod if (UtilValidate.isNotEmpty(alias.function)) { String prefix = functionPrefixMap.get(alias.function); if (prefix == null) { - Debug.logWarning("Specified alias function [" + alias.function + "] not valid; must be: min, max, sum, avg, count or count-distinct; using a column name with no function function", module); + Debug.logWarning("[" + this.getEntityName() + "]: Specified alias function [" + alias.function + "] not valid; must be: min, max, sum, avg, count or count-distinct; using a column name with no function function", module); } else { field.colValue = prefix + field.getColValue() + ")"; } @@ -511,20 +529,26 @@ public class ModelViewEntity extends Mod ModelEntity member = getMemberModelEntity(aliasName); if (member == null) { String errMsg = "No member found for aliasName - " + aliasName; - Debug.logWarning(errMsg, module); - throw new RuntimeException("Cannot create View Entity: " + errMsg); + Debug.logWarning("[" + this.getEntityName() + "]: " + errMsg, module); + throw new RuntimeException("[" + this.getEntityName() + "]: Cannot create View Entity: " + errMsg); } - Map<String, ModelConversion> aliasConversions = conversions.get(member.getEntityName()); - if (aliasConversions == null) { - aliasConversions = FastMap.newInstance(); - conversions.put(member.getEntityName(), aliasConversions); - } - ModelConversion conversion = aliasConversions.get(aliasName); - if (conversion == null) { - conversion = new ModelConversion(aliasName, member); - aliasConversions.put(aliasName, conversion); - } + ModelConversion[] allConversions = conversions.get(member.getEntityName()); + if (allConversions == null) { + ModelConversion conversion = new ModelConversion(aliasName, member); + conversions.put(member.getEntityName(), new ModelConversion[] {conversion}); + return conversion; + } + for (ModelConversion conversion: allConversions) { + if (conversion.aliasName.equals(aliasName)) { + return conversion; + } + } + ModelConversion[] newConversions = new ModelConversion[allConversions.length + 1]; + System.arraycopy(allConversions, 0, newConversions, 0, allConversions.length); + ModelConversion conversion = new ModelConversion(aliasName, member); + newConversions[allConversions.length] = conversion; + conversions.put(member.getEntityName(), newConversions); return conversion; } @@ -535,7 +559,7 @@ public class ModelViewEntity extends Mod ModelViewEntity.ModelAlias alias = it.next(); if (alias.isComplexAlias()) { // TODO: conversion for complex-alias needs to be implemented for cache and in-memory eval stuff to work correctly - Debug.logWarning("Conversion for complex-alias needs to be implemented for cache and in-memory eval stuff to work correctly, will not work for alias: " + alias.getName() + " of view-entity " + this.getEntityName(), module); + Debug.logWarning("[" + this.getEntityName() + "]: Conversion for complex-alias needs to be implemented for cache and in-memory eval stuff to work correctly, will not work for alias: " + alias.getName(), module); } else { ModelConversion conversion = getOrCreateModelConversion(alias.getEntityAlias()); conversion.addConversion(alias.getField(), alias.getName()); @@ -571,15 +595,11 @@ public class ModelViewEntity extends Mod int[] maxIndex = new int[conversions.size()]; ModelConversion[][] allConversions = new ModelConversion[conversions.size()][]; int i = 0; - for (Map<String, ModelConversion> aliasConversions: conversions.values()) { + for (ModelConversion[] aliasConversions: conversions.values()) { currentIndex[i] = 0; - maxIndex[i] = aliasConversions.size(); - allConversions[i] = new ModelConversion[aliasConversions.size()]; - int j = 0; - for (ModelConversion conversion: aliasConversions.values()) { - allConversions[i][j] = conversion; - j++; - } + maxIndex[i] = aliasConversions.length; + allConversions[i] = new ModelConversion[aliasConversions.length]; + System.arraycopy(aliasConversions, 0, allConversions[i], 0, aliasConversions.length); i++; } int ptr = 0; @@ -605,10 +625,10 @@ public class ModelViewEntity extends Mod } public List<Map<String, Object>> convert(String fromEntityName, Map<String, ? extends Object> data) { - Map<String, ModelConversion> conversions = this.conversions.get(fromEntityName); + ModelConversion[] conversions = this.conversions.get(fromEntityName); if (conversions == null) return null; List<Map<String, Object>> values = FastList.newInstance(); - for (ModelConversion conversion: conversions.values()) { + for (ModelConversion conversion: conversions) { conversion.convert(values, data); } return values; @@ -619,26 +639,28 @@ public class ModelViewEntity extends Mod */ private void expandAllAliasAlls(ModelReader modelReader) { for (ModelAliasAll aliasAll: aliasAlls) { + String entityAlias = aliasAll.getEntityAlias(); String prefix = aliasAll.getPrefix(); String function = aliasAll.getFunction(); boolean groupBy = aliasAll.getGroupBy(); + String aliasAllFieldSet = aliasAll.getFieldSet(); - ModelMemberEntity modelMemberEntity = memberModelMemberEntities.get(aliasAll.getEntityAlias()); + ModelMemberEntity modelMemberEntity = memberModelMemberEntities.get(entityAlias); if (modelMemberEntity == null) { - Debug.logError("Member entity referred to in alias-all not found, ignoring: " + aliasAll.getEntityAlias(), module); + Debug.logError("[" + this.getEntityName() + "]: Member entity referred to in alias-all not found, ignoring: " + entityAlias, module); continue; } String aliasedEntityName = modelMemberEntity.getEntityName(); ModelEntity aliasedEntity = modelReader.getModelEntityNoCheck(aliasedEntityName); if (aliasedEntity == null) { - Debug.logError("Entity referred to in member-entity " + aliasAll.getEntityAlias() + " not found, ignoring: " + aliasedEntityName, module); + Debug.logError("[" + this.getEntityName() + "]: Entity referred to in member-entity " + entityAlias + " not found, ignoring: " + aliasedEntityName, module); continue; } List<String> entFieldList = aliasedEntity.getAllFieldNames(); if (entFieldList == null) { - Debug.logError("Entity referred to in member-entity " + aliasAll.getEntityAlias() + " has no fields, ignoring: " + aliasedEntityName, module); + Debug.logError("[" + this.getEntityName() + "]: Entity referred to in member-entity " + entityAlias + " has no fields, ignoring: " + aliasedEntityName, module); continue; } @@ -662,6 +684,27 @@ public class ModelViewEntity extends Mod newAliasBuffer.append(aliasName.substring(1)); aliasName = newAliasBuffer.toString(); } + String fieldSet; + if (UtilValidate.isEmpty(aliasAllFieldSet)) { + String aliasedFieldSet = modelField.getFieldSet(); + if (UtilValidate.isNotEmpty(aliasedFieldSet)) { + StringBuilder fieldSetBuffer = new StringBuilder(entityAlias); + if (UtilValidate.isNotEmpty(prefix)) { + fieldSetBuffer.append(Character.toUpperCase(prefix.charAt(0))); + fieldSetBuffer.append(prefix.substring(1)); + } + fieldSetBuffer.append(Character.toUpperCase(aliasedFieldSet.charAt(0))); + fieldSetBuffer.append(aliasedFieldSet.substring(1)); + fieldSet = fieldSetBuffer.toString(); + } else { + fieldSet = ""; + } + } else { + fieldSet = aliasAllFieldSet; + } + if (UtilValidate.isNotEmpty(fieldSet)) { + Debug.logInfo("[" + this.getEntityName() + "]: set field-set on [" + aliasName + "]: " + fieldSet, module); + } ModelAlias existingAlias = this.getAlias(aliasName); if (existingAlias != null) { @@ -689,7 +732,7 @@ public class ModelViewEntity extends Mod } //already exists, oh well... probably an override, but log just in case - String warnMsg = "Throwing out field alias in view entity " + this.getEntityName() + " because one already exists with the alias name [" + aliasName + "] and field name [" + modelMemberEntity.getEntityAlias() + "(" + aliasedEntity.getEntityName() + ")." + fieldName + "], existing field name is [" + existingAlias.getEntityAlias() + "." + existingAlias.getField() + "]"; + String warnMsg = "[" + this.getEntityName() + "]: Throwing out field alias in view entity because one already exists with the alias name [" + aliasName + "] and field name [" + modelMemberEntity.getEntityAlias() + "(" + aliasedEntity.getEntityName() + ")." + fieldName + "], existing field name is [" + existingAlias.getEntityAlias() + "." + existingAlias.getField() + "]"; if (isInViewLink) { Debug.logVerbose(warnMsg, module); } else { @@ -698,15 +741,8 @@ public class ModelViewEntity extends Mod continue; } - ModelAlias expandedAlias = new ModelAlias(); - expandedAlias.name = aliasName; - expandedAlias.field = fieldName; - expandedAlias.entityAlias = aliasAll.getEntityAlias(); - expandedAlias.isFromAliasAll = true; - expandedAlias.colAlias = ModelUtil.javaNameToDbName(UtilXml.checkEmpty(expandedAlias.name)); - expandedAlias.function = function; - expandedAlias.groupBy = groupBy; - expandedAlias.description = modelField.getDescription(); + ModelAlias expandedAlias = new ModelAlias(aliasAll.getEntityAlias(), aliasName, fieldName, ModelUtil.javaNameToDbName(UtilXml.checkEmpty(aliasName)), null, groupBy, function, fieldSet, true); + expandedAlias.setDescription(modelField.getDescription()); aliases.add(expandedAlias); } @@ -718,9 +754,9 @@ public class ModelViewEntity extends Mod return "ModelViewEntity[" + getEntityName() + "]"; } - public static class ModelMemberEntity implements Serializable { - protected String entityAlias = ""; - protected String entityName = ""; + public static final class ModelMemberEntity implements Serializable { + protected final String entityAlias; + protected final String entityName; public ModelMemberEntity(String entityAlias, String entityName) { this.entityAlias = entityAlias; @@ -736,19 +772,37 @@ public class ModelViewEntity extends Mod } } - public static class ModelAliasAll implements Serializable, Iterable<String> { - protected String entityAlias = ""; - protected String prefix = ""; - protected Set<String> fieldsToExclude = null; - protected boolean groupBy = false; + public static final class ModelAliasAll implements Serializable, Iterable<String> { + protected final String entityAlias; + protected final String prefix; + protected final Set<String> fieldsToExclude; + protected final boolean groupBy; // is specified this alias is a calculated value; can be: min, max, sum, avg, count, count-distinct - protected String function = null; - - protected ModelAliasAll() {} + protected final String function; + protected final String fieldSet; + @Deprecated public ModelAliasAll(String entityAlias, String prefix) { + this(entityAlias, prefix, false, null, null, null); + } + + @Deprecated + public ModelAliasAll(String entityAlias, String prefix, boolean groupBy, String function, Collection<String> excludes) { + this(entityAlias, prefix, groupBy, function, null, excludes); + } + + public ModelAliasAll(String entityAlias, String prefix, boolean groupBy, String function, String fieldSet, Collection<String> excludes) { this.entityAlias = entityAlias; this.prefix = prefix; + this.groupBy = groupBy; + this.function = function; + this.fieldSet = fieldSet; + if (UtilValidate.isNotEmpty(excludes)) { + this.fieldsToExclude = new HashSet<String>(excludes.size()); + this.fieldsToExclude.addAll(excludes); + } else { + this.fieldsToExclude = null; + } } public ModelAliasAll(Element aliasAllElement) { @@ -756,6 +810,7 @@ public class ModelViewEntity extends Mod this.prefix = UtilXml.checkEmpty(aliasAllElement.getAttribute("prefix")).intern(); this.groupBy = "true".equals(UtilXml.checkEmpty(aliasAllElement.getAttribute("group-by"))); this.function = UtilXml.checkEmpty(aliasAllElement.getAttribute("function")); + this.fieldSet = UtilXml.checkEmpty(aliasAllElement.getAttribute("field-set")).intern(); List<? extends Element> excludes = UtilXml.childElementList(aliasAllElement, "exclude"); if (UtilValidate.isNotEmpty(excludes)) { @@ -763,6 +818,8 @@ public class ModelViewEntity extends Mod for (Element excludeElement: excludes) { this.fieldsToExclude.add(excludeElement.getAttribute("field").intern()); } + } else { + this.fieldsToExclude = null; } } @@ -783,6 +840,10 @@ public class ModelViewEntity extends Mod return this.function; } + public String getFieldSet() { + return this.fieldSet; + } + public boolean shouldExclude(String fieldName) { if (this.fieldsToExclude == null) { return false; @@ -792,27 +853,30 @@ public class ModelViewEntity extends Mod } public Iterator<String> iterator() { - return fieldsToExclude.iterator(); + if (this.fieldsToExclude == null) { + return Collections.<String>emptySet().iterator(); + } else { + return fieldsToExclude.iterator(); + } } } - public static class ModelAlias implements Serializable { - protected String entityAlias = ""; - protected String name = ""; - protected String field = ""; - protected String colAlias = ""; + public static final class ModelAlias implements Serializable { + protected final String entityAlias; + protected final String name; + protected final String field; + protected final String colAlias; // this is a Boolean object for a tri-state: null, true or false - protected Boolean isPk = null; - protected boolean groupBy = false; + protected final Boolean isPk; + protected final boolean groupBy; // is specified this alias is a calculated value; can be: min, max, sum, avg, count, count-distinct - protected String function = null; - protected boolean isFromAliasAll = false; - protected ComplexAliasMember complexAliasMember = null; + protected final String function; + protected final String fieldSet; + protected final boolean isFromAliasAll; + protected ComplexAliasMember complexAliasMember; // The description for documentation purposes protected String description = ""; - protected ModelAlias() {} - public ModelAlias(Element aliasElement) { this.entityAlias = UtilXml.checkEmpty(aliasElement.getAttribute("entity-alias")).intern(); this.name = UtilXml.checkEmpty(aliasElement.getAttribute("name")).intern(); @@ -827,6 +891,8 @@ public class ModelViewEntity extends Mod } this.groupBy = "true".equals(UtilXml.checkEmpty(aliasElement.getAttribute("group-by"))); this.function = UtilXml.checkEmpty(aliasElement.getAttribute("function")).intern(); + this.fieldSet = UtilXml.checkEmpty(aliasElement.getAttribute("field-set")).intern(); + this.isFromAliasAll = false; this.description = UtilXml.checkEmpty(UtilXml.childElementValue(aliasElement, "description")).intern(); Element complexAliasElement = UtilXml.firstChildElement(aliasElement, "complex-alias"); @@ -835,7 +901,16 @@ public class ModelViewEntity extends Mod } } + @Deprecated public ModelAlias(String entityAlias, String name, String field, String colAlias, Boolean isPk, Boolean groupBy, String function) { + this(entityAlias, name, field, colAlias, isPk, groupBy, function, null, false); + } + + public ModelAlias(String entityAlias, String name, String field, String colAlias, Boolean isPk, Boolean groupBy, String function, String fieldSet) { + this(entityAlias, name, field, colAlias, isPk, groupBy, function, fieldSet, false); + } + + protected ModelAlias(String entityAlias, String name, String field, String colAlias, Boolean isPk, Boolean groupBy, String function, String fieldSet, boolean isFromAliasAll) { this.entityAlias = entityAlias; this.name = name; this.field = UtilXml.checkEmpty(field, this.name); @@ -847,6 +922,8 @@ public class ModelViewEntity extends Mod this.groupBy = false; } this.function = function; + this.fieldSet = UtilXml.checkEmpty(fieldSet).intern(); + this.isFromAliasAll = isFromAliasAll; } public void setComplexAliasMember(ComplexAliasMember complexAliasMember) { @@ -891,6 +968,10 @@ public class ModelViewEntity extends Mod return this.function; } + public String getFieldSet() { + return fieldSet; + } + public String getDescription() { return this.description; } @@ -908,9 +989,9 @@ public class ModelViewEntity extends Mod public void makeAliasColName(StringBuilder colNameBuffer, StringBuilder fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader); } - public static class ComplexAlias implements ComplexAliasMember { - protected List<ComplexAliasMember> complexAliasMembers = FastList.newInstance(); - protected String operator; + public static final class ComplexAlias implements ComplexAliasMember { + protected final List<ComplexAliasMember> complexAliasMembers = FastList.newInstance(); + protected final String operator; public ComplexAlias(String operator) { this.operator = operator; @@ -960,11 +1041,11 @@ public class ModelViewEntity extends Mod } } - public static class ComplexAliasField implements ComplexAliasMember { - protected String entityAlias = ""; - protected String field = ""; - protected String defaultValue = null; - protected String function = null; + public static final class ComplexAliasField implements ComplexAliasMember { + protected final String entityAlias; + protected final String field; + protected final String defaultValue; + protected final String function; public ComplexAliasField(Element complexAliasFieldElement) { this.entityAlias = complexAliasFieldElement.getAttribute("entity-alias").intern(); @@ -996,7 +1077,7 @@ public class ModelViewEntity extends Mod if (UtilValidate.isNotEmpty(function)) { String prefix = functionPrefixMap.get(function); if (prefix == null) { - Debug.logWarning("Specified alias function [" + function + "] not valid; must be: min, max, sum, avg, count or count-distinct; using a column name with no function function", module); + Debug.logWarning("[" + modelViewEntity.getEntityName() + "]: Specified alias function [" + function + "] not valid; must be: min, max, sum, avg, count or count-distinct; using a column name with no function function", module); } else { colName = prefix + colName + ")"; } @@ -1011,14 +1092,12 @@ public class ModelViewEntity extends Mod } } - public static class ModelViewLink implements Serializable, Iterable<ModelKeyMap> { - protected String entityAlias = ""; - protected String relEntityAlias = ""; - protected boolean relOptional = false; - protected List<ModelKeyMap> keyMaps = FastList.newInstance(); - protected ViewEntityCondition viewEntityCondition = null; - - protected ModelViewLink() {} + public static final class ModelViewLink implements Serializable, Iterable<ModelKeyMap> { + protected final String entityAlias; + protected final String relEntityAlias; + protected final boolean relOptional; + protected final List<ModelKeyMap> keyMaps = FastList.newInstance(); + protected final ViewEntityCondition viewEntityCondition; public ModelViewLink(ModelViewEntity modelViewEntity, Element viewLinkElement) { this.entityAlias = UtilXml.checkEmpty(viewLinkElement.getAttribute("entity-alias")).intern(); @@ -1037,20 +1116,35 @@ public class ModelViewEntity extends Mod Element entityConditionElement = UtilXml.firstChildElement(viewLinkElement, "entity-condition"); if (entityConditionElement != null) { this.viewEntityCondition = new ViewEntityCondition(modelViewEntity, this, entityConditionElement); + } else { + this.viewEntityCondition = null; } } + @Deprecated public ModelViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, ModelKeyMap... keyMaps) { - this(entityAlias, relEntityAlias, relOptional, Arrays.asList(keyMaps)); + this(entityAlias, relEntityAlias, relOptional, null, Arrays.asList(keyMaps)); } + @Deprecated public ModelViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, List<ModelKeyMap> keyMaps) { + this(entityAlias, relEntityAlias, relOptional, null, keyMaps); + } + + public ModelViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, ViewEntityCondition viewEntityCondition, ModelKeyMap... keyMaps) { + this(entityAlias, relEntityAlias, relOptional, viewEntityCondition, Arrays.asList(keyMaps)); + } + + public ModelViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, ViewEntityCondition viewEntityCondition, List<ModelKeyMap> keyMaps) { this.entityAlias = entityAlias; this.relEntityAlias = relEntityAlias; if (relOptional != null) { this.relOptional = relOptional.booleanValue(); + } else { + this.relOptional = false; } this.keyMaps.addAll(keyMaps); + this.viewEntityCondition = viewEntityCondition; } public String getEntityAlias() { @@ -1086,13 +1180,17 @@ public class ModelViewEntity extends Mod newList.addAll(this.keyMaps); return newList; } + + public ViewEntityCondition getViewEntityCondition() { + return this.viewEntityCondition; + } } - public class ModelConversion implements Serializable { - protected String aliasName; - protected ModelEntity fromModelEntity; - protected Map<String, String> fieldMap = FastMap.newInstance(); - protected Set<String> wildcards = new HashSet<String>(); + public final class ModelConversion implements Serializable { + protected final String aliasName; + protected final ModelEntity fromModelEntity; + protected final Map<String, String> fieldMap = FastMap.newInstance(); + protected final Set<String> wildcards = new HashSet<String>(); public ModelConversion(String aliasName, ModelEntity fromModelEntity) { this.aliasName = aliasName; @@ -1151,15 +1249,16 @@ public class ModelViewEntity extends Mod } } - public static class ViewEntityCondition { - protected ModelViewEntity modelViewEntity; - protected ModelViewLink modelViewLink; - protected boolean filterByDate; - protected boolean distinct; - protected List<String> orderByList; - protected ViewCondition whereCondition; - protected ViewCondition havingCondition; + public static final class ViewEntityCondition { + protected final ModelViewEntity modelViewEntity; + protected final ModelViewLink modelViewLink; + protected final boolean filterByDate; + protected final boolean distinct; + protected final List<String> orderByList; + protected final ViewCondition whereCondition; + protected final ViewCondition havingCondition; + // FIXME: add programatic constructor public ViewEntityCondition(ModelViewEntity modelViewEntity, ModelViewLink modelViewLink, Element element) { this.modelViewEntity = modelViewEntity; this.modelViewLink = modelViewLink; @@ -1172,6 +1271,8 @@ public class ModelViewEntity extends Mod for (Element orderByElement: orderByElementList) { orderByList.add(orderByElement.getAttribute("field-name")); } + } else { + orderByList = null; } Element conditionExprElement = UtilXml.firstChildElement(element, "condition-expr"); @@ -1180,11 +1281,15 @@ public class ModelViewEntity extends Mod this.whereCondition = new ViewConditionExpr(this, conditionExprElement); } else if (conditionListElement != null) { this.whereCondition = new ViewConditionList(this, conditionListElement); + } else { + this.whereCondition = null; } Element havingConditionListElement = UtilXml.firstChildElement(element, "having-condition-list"); if (havingConditionListElement != null) { this.havingCondition = new ViewConditionList(this, havingConditionListElement); + } else { + this.havingCondition = null; } } @@ -1213,46 +1318,50 @@ public class ModelViewEntity extends Mod public EntityCondition createCondition(ModelFieldTypeReader modelFieldTypeReader, List<String> entityAliasStack); } - public static class ViewConditionExpr implements ViewCondition { - protected ViewEntityCondition viewEntityCondition; - protected String entityAlias; - protected String fieldName; - protected String operator; - protected String relEntityAlias; - protected String relFieldName; - protected Object value; - protected boolean ignoreCase; + public static final class ViewConditionExpr implements ViewCondition { + protected final ViewEntityCondition viewEntityCondition; + protected final String entityAlias; + protected final String fieldName; + protected final EntityComparisonOperator<?, ?> operator; + protected final String relEntityAlias; + protected final String relFieldName; + protected final Object value; + protected final boolean ignoreCase; + // FIXME: add programatic constructor public ViewConditionExpr(ViewEntityCondition viewEntityCondition, Element conditionExprElement) { this.viewEntityCondition = viewEntityCondition; - this.entityAlias = conditionExprElement.getAttribute("entity-alias"); + String entityAlias = conditionExprElement.getAttribute("entity-alias"); this.fieldName = conditionExprElement.getAttribute("field-name"); - this.operator = UtilFormatOut.checkEmpty(conditionExprElement.getAttribute("operator"), "equals"); - this.relEntityAlias = conditionExprElement.getAttribute("rel-entity-alias"); + String operator = UtilFormatOut.checkEmpty(conditionExprElement.getAttribute("operator"), "equals"); + try { + this.operator = EntityOperator.lookupComparison(operator); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("[" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]: Could not find an entity operator for the name: " + this.operator); + } + String relEntityAlias = conditionExprElement.getAttribute("rel-entity-alias"); this.relFieldName = conditionExprElement.getAttribute("rel-field-name"); this.value = conditionExprElement.getAttribute("value"); this.ignoreCase = "true".equals(conditionExprElement.getAttribute("ignore-case")); // if we are in a view-link, default to the entity-alias and rel-entity-alias there if (this.viewEntityCondition.modelViewLink != null) { - if (UtilValidate.isEmpty(this.entityAlias)) { - this.entityAlias = this.viewEntityCondition.modelViewLink.getEntityAlias(); + if (UtilValidate.isEmpty(entityAlias)) { + entityAlias = this.viewEntityCondition.modelViewLink.getEntityAlias(); } - if (UtilValidate.isEmpty(this.relEntityAlias)) { - this.relEntityAlias = this.viewEntityCondition.modelViewLink.getRelEntityAlias(); + if (UtilValidate.isEmpty(relEntityAlias)) { + relEntityAlias = this.viewEntityCondition.modelViewLink.getRelEntityAlias(); } } + this.entityAlias = entityAlias; + this.relEntityAlias = relEntityAlias; } public EntityCondition createCondition(ModelFieldTypeReader modelFieldTypeReader, List<String> entityAliasStack) { - EntityOperator<?,?,?> operator = EntityOperator.lookup(this.operator); - if (operator == null) { - throw new IllegalArgumentException("Could not find an entity operator for the name: " + this.operator); - } - + Object value = this.value; // If IN or BETWEEN operator, see if value is a literal list and split it - if ((operator.equals(EntityOperator.IN) || operator.equals(EntityOperator.BETWEEN)) + if ((this.operator == EntityOperator.IN || this.operator == EntityOperator.BETWEEN) && value instanceof String) { String delim = null; if (((String)value).indexOf("|") >= 0) { @@ -1265,20 +1374,21 @@ public class ModelViewEntity extends Mod } } - if (this.viewEntityCondition.modelViewEntity.getField(fieldName) == null) { - throw new IllegalArgumentException("Error in Entity Find: could not find field [" + fieldName + "] in entity with name [" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]"); + EntityConditionValue lhs = EntityFieldValue.makeFieldValue(this.fieldName, this.entityAlias, entityAliasStack, this.viewEntityCondition.modelViewEntity); + ModelField lhsField = lhs.getModelField(this.viewEntityCondition.modelViewEntity); + if (lhsField == null) { + throw new IllegalArgumentException("[" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]: Error in Entity Find: could not find field [" + fieldName + "]"); } // don't convert the field to the desired type if this is an IN or BETWEEN operator and we have a Collection - if (!((operator.equals(EntityOperator.IN) || operator.equals(EntityOperator.BETWEEN)) + if (!((this.operator == EntityOperator.IN || this.operator == EntityOperator.BETWEEN) && value instanceof Collection<?>)) { // now to a type conversion for the target fieldName - value = this.viewEntityCondition.modelViewEntity.convertFieldValue(this.viewEntityCondition.modelViewEntity.getField(fieldName), value, modelFieldTypeReader, FastMap.<String, Object>newInstance()); + value = this.viewEntityCondition.modelViewEntity.convertFieldValue(lhsField, value, modelFieldTypeReader, FastMap.<String, Object>newInstance()); } - if (Debug.verboseOn()) Debug.logVerbose("Got value for fieldName [" + fieldName + "]: " + value, module); + if (Debug.verboseOn()) Debug.logVerbose("[" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]: Got value for fieldName [" + fieldName + "]: " + value, module); - EntityConditionValue lhs = EntityFieldValue.makeFieldValue(this.fieldName, this.entityAlias, entityAliasStack, this.viewEntityCondition.modelViewEntity); Object rhs = null; if (value != null) { rhs = value; @@ -1286,41 +1396,46 @@ public class ModelViewEntity extends Mod rhs = EntityFieldValue.makeFieldValue(this.relFieldName, this.relEntityAlias, entityAliasStack, this.viewEntityCondition.modelViewEntity); } - if (operator.equals(EntityOperator.NOT_EQUAL) && value != null) { + if (this.operator == EntityOperator.NOT_EQUAL && value != null) { // since some databases don't consider nulls in != comparisons, explicitly include them // this makes more sense logically, but if anyone ever needs it to not behave this way we should add an "or-null" attribute that is true by default if (ignoreCase) { return EntityCondition.makeCondition( - EntityCondition.makeCondition(EntityFunction.UPPER(lhs), UtilGenerics.<EntityComparisonOperator<?,?>>cast(operator), EntityFunction.UPPER(rhs)), + EntityCondition.makeCondition(EntityFunction.UPPER(lhs), this.operator, EntityFunction.UPPER(rhs)), EntityOperator.OR, EntityCondition.makeCondition(lhs, EntityOperator.EQUALS, null)); } else { return EntityCondition.makeCondition( - EntityCondition.makeCondition(lhs, UtilGenerics.<EntityComparisonOperator<?,?>>cast(operator), rhs), + EntityCondition.makeCondition(lhs, this.operator, rhs), EntityOperator.OR, EntityCondition.makeCondition(lhs, EntityOperator.EQUALS, null)); } - } else if ( value == null && (operator.equals(EntityOperator.EQUALS) || operator.equals(EntityOperator.NOT_EQUAL))) { - return EntityCondition.makeCondition(lhs, UtilGenerics.<EntityComparisonOperator<?,?>>cast(operator), null); + } else if ( value == null && this.relFieldName == null && (this.operator == EntityOperator.EQUALS || this.operator == EntityOperator.NOT_EQUAL)) { + return EntityCondition.makeCondition(lhs, this.operator, null); } else { if (ignoreCase) { // use the stuff to upper case both sides - return EntityCondition.makeCondition(EntityFunction.UPPER(lhs), UtilGenerics.<EntityComparisonOperator<?,?>>cast(operator), EntityFunction.UPPER(rhs)); + return EntityCondition.makeCondition(EntityFunction.UPPER(lhs), this.operator, EntityFunction.UPPER(rhs)); } else { - return EntityCondition.makeCondition(lhs, UtilGenerics.<EntityComparisonOperator<?,?>>cast(operator), rhs); + return EntityCondition.makeCondition(lhs, this.operator, rhs); } } } } - public static class ViewConditionList implements ViewCondition { - protected ViewEntityCondition viewEntityCondition; - List<ViewCondition> conditionList = new LinkedList<ViewCondition>(); - String combine; + public static final class ViewConditionList implements ViewCondition { + protected final ViewEntityCondition viewEntityCondition; + protected final List<ViewCondition> conditionList = new LinkedList<ViewCondition>(); + protected final EntityJoinOperator operator; public ViewConditionList(ViewEntityCondition viewEntityCondition, Element conditionListElement) { this.viewEntityCondition = viewEntityCondition; - this.combine = conditionListElement.getAttribute("combine"); + String combine = conditionListElement.getAttribute("combine"); + try { + this.operator = EntityOperator.lookupJoin(combine); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("[" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]: Could not find an entity operator for the name: " + combine); + } List<? extends Element> subElements = UtilXml.childElementList(conditionListElement); for (Element subElement: subElements) { @@ -1329,11 +1444,23 @@ public class ModelViewEntity extends Mod } else if ("condition-list".equals(subElement.getNodeName())) { conditionList.add(new ViewConditionList(this.viewEntityCondition, subElement)); } else { - throw new IllegalArgumentException("Invalid element with name [" + subElement.getNodeName() + "] found under a condition-list element."); + throw new IllegalArgumentException("[" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]: Invalid element with name [" + subElement.getNodeName() + "] found under a condition-list element."); } } } + public ViewConditionList(ViewEntityCondition viewEntityCondition, String combine, List<ViewCondition> conditionList) { + this.viewEntityCondition = viewEntityCondition; + try { + this.operator = EntityOperator.lookupJoin(combine); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("[" + this.viewEntityCondition.modelViewEntity.getEntityName() + "]: Could not find an entity operator for the name: " + combine); + } + if (UtilValidate.isNotEmpty(conditionList)) { + this.conditionList.addAll(conditionList); + } + } + public EntityCondition createCondition(ModelFieldTypeReader modelFieldTypeReader, List<String> entityAliasStack) { if (this.conditionList.size() == 0) { return null; @@ -1351,12 +1478,7 @@ public class ModelViewEntity extends Mod } } - EntityOperator<?,?,?> operator = EntityOperator.lookup(this.combine); - if (operator == null) { - throw new IllegalArgumentException("Could not find an entity operator for the name: " + operator); - } - - return EntityCondition.makeCondition(entityConditionList, UtilGenerics.<EntityJoinOperator>cast(operator)); + return EntityCondition.makeCondition(entityConditionList, this.operator); } } } Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntityPlanner.java URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntityPlanner.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntityPlanner.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntityPlanner.java Wed Aug 3 16:12:58 2011 @@ -74,25 +74,38 @@ public class EntityPlanner extends Plann public EntitySelectPlan planSelect(SQLSelect selectStatement) { DynamicViewEntity dve = new DynamicViewEntity(); Unioned unioned = selectStatement.getUnioned(); - if (unioned.getOperator() != null || unioned.getNext() != null) { + if (unioned != null) { throw new IllegalArgumentException("union views not yet supported"); } SelectGroup selectGroup = unioned.getGroup(); Table table = selectGroup.getTable(); addMember(dve, table.getTableName()); addJoined(dve, table.getTableName().getAlias(), table.getJoined()); - for (FieldAll fieldAll: selectGroup.getFieldAlls()) { - dve.addAliasAll(fieldAll.getAlias(), null); + if (selectGroup.getFieldAlls() != null) { + for (FieldAll fieldAll: selectGroup.getFieldAlls()) { + List<String> excludes = FastList.newInstance(); + for (String exclude: fieldAll) { + excludes.add(exclude); + } + if (excludes.isEmpty()) { + excludes = null; + } + dve.addAliasAll(fieldAll.getAlias(), null, excludes); + } } - for (Relation relation: selectStatement.getRelations().values()) { - dve.addRelation(relation.getType(), relation.getTitle(), relation.getEntityName(), buildKeyMaps(relation)); + if (selectStatement.getRelations() != null) { + for (Relation relation: selectStatement.getRelations().values()) { + dve.addRelation(relation.getType(), relation.getTitle(), relation.getEntityName(), buildKeyMaps(relation)); + } } List<String> groupBy = selectGroup.getGroupBy(); if (groupBy == null) { groupBy = Collections.emptyList(); } - for (FieldDef fieldDef: selectGroup.getFieldDefs()) { - addFieldDef(dve, groupBy, fieldDef.getAlias(), fieldDef); + if (selectGroup.getFieldDefs() != null) { + for (FieldDef fieldDef: selectGroup.getFieldDefs()) { + addFieldDef(dve, groupBy, fieldDef.getAlias(), fieldDef); + } } List<String> orderBy; if (selectStatement.getOrderBy() == null) { Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntitySelectPlan.java URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntitySelectPlan.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntitySelectPlan.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/sql/EntitySelectPlan.java Wed Aug 3 16:12:58 2011 @@ -60,7 +60,7 @@ public final class EntitySelectPlan exte } public List<GenericValue> getAll(final Delegator delegator, final Map<String, ? extends Object> params) throws GenericEntityException { - return TransactionUtil.doTransaction("sql select", new Callable<List<GenericValue>>() { + return TransactionUtil.doTransaction(new Callable<List<GenericValue>>() { public List<GenericValue> call() throws Exception { EntityListIterator it = null; try { @@ -70,7 +70,7 @@ public final class EntitySelectPlan exte if (it != null) it.close(); } } - }); + }, "sql select", 0, true); } public DynamicViewEntity getDynamicViewEntity() { Modified: ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java URL: http://svn.apache.org/viewvc/ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java?rev=1153560&r1=1153559&r2=1153560&view=diff ============================================================================== --- ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java (original) +++ ofbiz/branches/jackrabbit20100709/framework/entity/src/org/ofbiz/entity/transaction/TransactionUtil.java Wed Aug 3 16:12:58 2011 @@ -75,52 +75,46 @@ public class TransactionUtil implements private static ThreadLocal<Timestamp> transactionStartStamp = new ThreadLocal<Timestamp>(); private static ThreadLocal<Timestamp> transactionLastNowStamp = new ThreadLocal<Timestamp>(); + @Deprecated public static <V> V doNewTransaction(String ifErrorMessage, Callable<V> callable) throws GenericEntityException { - return doNewTransaction(ifErrorMessage, true, callable); + return inTransaction(noTransaction(callable), ifErrorMessage, 0, true).call(); } + @Deprecated public static <V> V doNewTransaction(String ifErrorMessage, boolean printException, Callable<V> callable) throws GenericEntityException { - Transaction tx = TransactionUtil.suspend(); - try { - return doTransaction(ifErrorMessage, printException, callable); - } finally { - TransactionUtil.resume(tx); - } + return inTransaction(noTransaction(callable), ifErrorMessage, 0, printException).call(); } + public static <V> V doNewTransaction(Callable<V> callable, String ifErrorMessage, int timeout, boolean printException) throws GenericEntityException { + return inTransaction(noTransaction(callable), ifErrorMessage, timeout, printException).call(); + } + + @Deprecated public static <V> V doTransaction(String ifErrorMessage, Callable<V> callable) throws GenericEntityException { - return doTransaction(ifErrorMessage, true, callable); + return inTransaction(callable, ifErrorMessage, 0, true).call(); } + @Deprecated public static <V> V doTransaction(String ifErrorMessage, boolean printException, Callable<V> callable) throws GenericEntityException { - boolean tx = TransactionUtil.begin(); - Throwable transactionAbortCause = null; - try { - try { - return callable.call(); - } catch (Throwable t) { - while (t.getCause() != null) { - t = t.getCause(); - } - throw t; - } - } catch (Error e) { - transactionAbortCause = e; - throw e; - } catch (RuntimeException e) { - transactionAbortCause = e; - throw e; - } catch (Throwable t) { - transactionAbortCause = t; - throw new GenericEntityException(t); - } finally { - if (transactionAbortCause == null) { - TransactionUtil.commit(tx); - } else { - if (printException) transactionAbortCause.printStackTrace(); - TransactionUtil.rollback(tx, ifErrorMessage, transactionAbortCause); - } - } + return inTransaction(callable, ifErrorMessage, 0, printException).call(); + } + + public static <V> V doTransaction(Callable<V> callable, String ifErrorMessage, int timeout, boolean printException) throws GenericEntityException { + return inTransaction(callable, ifErrorMessage, timeout, printException).call(); + } + + public static <V> Callable<V> noTransaction(Callable<V> callable) { + return new NoTransaction<V>(callable); + } + + // This syntax is groovy compatible, with the primary(callable) as the first arg. + // You could do: + // use (TransactionUtil) { + // Callable callable = .... + // Object result = callable.noTransaction().inTransaction(ifError, timeout, print).call() + // } + public static <V> InTransaction<V> inTransaction(Callable<V> callable, String ifErrorMessage, int timeout, boolean printException) { + return new InTransaction<V>(callable, ifErrorMessage, timeout, printException); } /** Begins a transaction in the current thread IF transactions are available; only @@ -142,9 +136,13 @@ public class TransactionUtil implements if (ut != null) { try { int currentStatus = ut.getStatus(); - if (Debug.verboseOn()) Debug.logVerbose("[TransactionUtil.begin] current status : " + getTransactionStateString(currentStatus), module); + if (Debug.verboseOn()) { + Debug.logVerbose("[TransactionUtil.begin] current status : " + getTransactionStateString(currentStatus), module); + } if (currentStatus == Status.STATUS_ACTIVE) { - if (Debug.verboseOn()) Debug.logVerbose("[TransactionUtil.begin] active transaction in place, so no transaction begun", module); + if (Debug.verboseOn()) { + Debug.logVerbose("[TransactionUtil.begin] active transaction in place, so no transaction begun", module); + } return false; } else if (currentStatus == Status.STATUS_MARKED_ROLLBACK) { Exception e = getTransactionBeginStack(); @@ -200,12 +198,16 @@ public class TransactionUtil implements // set the timeout for THIS transaction if (timeout > 0) { ut.setTransactionTimeout(timeout); - if (Debug.verboseOn()) Debug.logVerbose("[TransactionUtil.begin] set transaction timeout to : " + timeout + " seconds", module); + if (Debug.verboseOn()) { + Debug.logVerbose("[TransactionUtil.begin] set transaction timeout to : " + timeout + " seconds", module); + } } // begin the transaction ut.begin(); - if (Debug.verboseOn()) Debug.logVerbose("[TransactionUtil.begin] transaction begun", module); + if (Debug.verboseOn()) { + Debug.logVerbose("[TransactionUtil.begin] transaction begun", module); + } // reset the timeout to the default if (timeout > 0) { @@ -372,7 +374,9 @@ public class TransactionUtil implements if (status != STATUS_NO_TRANSACTION) { if (status != STATUS_MARKED_ROLLBACK) { - if (Debug.warningOn()) Debug.logWarning(new Exception(causeMessage), "[TransactionUtil.setRollbackOnly] Calling transaction setRollbackOnly; this stack trace shows where this is happening:", module); + if (Debug.warningOn()) { + Debug.logWarning(new Exception(causeMessage), "[TransactionUtil.setRollbackOnly] Calling transaction setRollbackOnly; this stack trace shows where this is happening:", module); + } ut.setRollbackOnly(); setSetRollbackOnlyCause(causeMessage, causeThrowable); } else { @@ -416,9 +420,11 @@ public class TransactionUtil implements } public static void resume(Transaction parentTx) throws GenericTransactionException { - if (parentTx == null) return; + if (parentTx == null) { + return; + } + TransactionManager txMgr = TransactionFactory.getTransactionManager(); try { - TransactionManager txMgr = TransactionFactory.getTransactionManager(); if (txMgr != null) { setTransactionBeginStack(popTransactionBeginStackSave()); setSetRollbackOnlyCause(popSetRollbackOnlyCauseSave()); @@ -428,12 +434,12 @@ public class TransactionUtil implements } catch (InvalidTransactionException e) { /* NOTE: uncomment this for Weblogic Application Server // this is a work-around for non-standard Weblogic functionality; for more information see: http://www.onjava.com/pub/a/onjava/2005/07/20/transactions.html?page=3 - if (parentTx instanceof weblogic.transaction.ClientTransactionManager) { + if (txMgr instanceof weblogic.transaction.ClientTransactionManager) { // WebLogic 8 and above - ((weblogic.transaction.ClientTransactionManager) parentTx).forceResume(transaction); - } else if (parentTx instanceof weblogic.transaction.TransactionManager) { + ((weblogic.transaction.ClientTransactionManager) txMgr).forceResume(parentTx); + } else if (txMgr instanceof weblogic.transaction.TransactionManager) { // WebLogic 7 - ((weblogic.transaction.TransactionManager) parentTx).forceResume(transaction); + ((weblogic.transaction.TransactionManager) txMgr).forceResume(parentTx); } else { throw new GenericTransactionException("System error, could not resume transaction", e); } @@ -580,10 +586,12 @@ public class TransactionUtil implements clearTransactionStartStampStack(); return num; } + public static boolean suspendedTransactionsHeld() { List<Transaction> tl = suspendedTxStack.get(); return UtilValidate.isNotEmpty(tl); } + public static List<Transaction> getSuspendedTxStack() { List<Transaction> tl = suspendedTxStack.get(); if (tl == null) { @@ -592,6 +600,7 @@ public class TransactionUtil implements } return tl; } + public static List<Exception> getSuspendedTxLocationsStack() { List<Exception> tl = suspendedTxLocationStack.get(); if (tl == null) { @@ -600,6 +609,7 @@ public class TransactionUtil implements } return tl; } + protected static void pushSuspendedTransaction(Transaction t) { List<Transaction> tl = getSuspendedTxStack(); tl.add(0, t); @@ -608,24 +618,30 @@ public class TransactionUtil implements // save the current transaction start stamp pushTransactionStartStamp(t); } + protected static Transaction popSuspendedTransaction() { List<Transaction> tl = suspendedTxStack.get(); if (UtilValidate.isNotEmpty(tl)) { // restore the transaction start stamp popTransactionStartStamp(); List<Exception> stls = suspendedTxLocationStack.get(); - if (UtilValidate.isNotEmpty(stls)) stls.remove(0); + if (UtilValidate.isNotEmpty(stls)) { + stls.remove(0); + } return tl.remove(0); } else { return null; } } + protected static void removeSuspendedTransaction(Transaction t) { List<Transaction> tl = suspendedTxStack.get(); if (UtilValidate.isNotEmpty(tl)) { tl.remove(t); List<Exception> stls = suspendedTxLocationStack.get(); - if (UtilValidate.isNotEmpty(stls)) stls.remove(0); + if (UtilValidate.isNotEmpty(stls)) { + stls.remove(0); + } popTransactionStartStamp(t); } } @@ -650,6 +666,7 @@ public class TransactionUtil implements } ctEl.add(0, e); } + private static Exception popTransactionBeginStackSave() { // do the unofficial all threads Map one first, and don't do a real return Long curThreadId = Thread.currentThread().getId(); @@ -666,6 +683,7 @@ public class TransactionUtil implements return null; } } + public static int getTransactionBeginStackSaveSize() { List<Exception> el = transactionBeginStackSave.get(); if (el != null) { @@ -674,18 +692,21 @@ public class TransactionUtil implements return 0; } } + public static List<Exception> getTransactionBeginStackSave() { List<Exception> el = transactionBeginStackSave.get(); List<Exception> elClone = FastList.newInstance(); elClone.addAll(el); return elClone; } + public static Map<Long, List<Exception>> getAllThreadsTransactionBeginStackSave() { Map<Long, List<Exception>> attbssMap = allThreadsTransactionBeginStackSave; Map<Long, List<Exception>> attbssMapClone = FastMap.newInstance(); attbssMapClone.putAll(attbssMap); return attbssMapClone; } + public static void printAllThreadsTransactionBeginStacks() { if (!Debug.infoOn()) { return; @@ -714,6 +735,7 @@ public class TransactionUtil implements Exception e = new Exception("Tx Stack Placeholder"); setTransactionBeginStack(e); } + private static void setTransactionBeginStack(Exception newExc) { if (transactionBeginStack.get() != null) { Exception e = transactionBeginStack.get(); @@ -725,6 +747,7 @@ public class TransactionUtil implements Long curThreadId = Thread.currentThread().getId(); allThreadsTransactionBeginStack.put(curThreadId, newExc); } + private static Exception clearTransactionBeginStack() { Long curThreadId = Thread.currentThread().getId(); allThreadsTransactionBeginStack.remove(curThreadId); @@ -739,6 +762,7 @@ public class TransactionUtil implements return e; } } + public static Exception getTransactionBeginStack() { Exception e = transactionBeginStack.get(); if (e == null) { @@ -754,14 +778,26 @@ public class TransactionUtil implements private static class RollbackOnlyCause { protected String causeMessage; protected Throwable causeThrowable; + public RollbackOnlyCause(String causeMessage, Throwable causeThrowable) { this.causeMessage = causeMessage; this.causeThrowable = causeThrowable; } - public String getCauseMessage() { return this.causeMessage + (this.causeThrowable == null ? "" : this.causeThrowable.toString()); } - public Throwable getCauseThrowable() { return this.causeThrowable; } - public void logError(String message) { Debug.logError(this.getCauseThrowable(), (message == null ? "" : message) + this.getCauseMessage(), module); } - public boolean isEmpty() { return (UtilValidate.isEmpty(this.getCauseMessage()) && this.getCauseThrowable() == null); } + public String getCauseMessage() { + return this.causeMessage + (this.causeThrowable == null ? "" : this.causeThrowable.toString()); + } + + public Throwable getCauseThrowable() { + return this.causeThrowable; + } + + public void logError(String message) { + Debug.logError(this.getCauseThrowable(), (message == null ? "" : message) + this.getCauseMessage(), module); + } + + public boolean isEmpty() { + return (UtilValidate.isEmpty(this.getCauseMessage()) && this.getCauseThrowable() == null); + } } private static void pushSetRollbackOnlyCauseSave(RollbackOnlyCause e) { @@ -772,6 +808,7 @@ public class TransactionUtil implements } el.add(0, e); } + private static RollbackOnlyCause popSetRollbackOnlyCauseSave() { List<RollbackOnlyCause> el = setRollbackOnlyCauseSave.get(); if (UtilValidate.isNotEmpty(el)) { @@ -785,6 +822,7 @@ public class TransactionUtil implements RollbackOnlyCause roc = new RollbackOnlyCause(causeMessage, causeThrowable); setSetRollbackOnlyCause(roc); } + private static void setSetRollbackOnlyCause(RollbackOnlyCause newRoc) { if (setRollbackOnlyCause.get() != null) { RollbackOnlyCause roc = setRollbackOnlyCause.get(); @@ -794,6 +832,7 @@ public class TransactionUtil implements } setRollbackOnlyCause.set(newRoc); } + private static RollbackOnlyCause clearSetRollbackOnlyCause() { RollbackOnlyCause roc = setRollbackOnlyCause.get(); if (roc == null) { @@ -845,7 +884,6 @@ public class TransactionUtil implements } } - /** * Method called when the suspended stack gets cleaned by {@link #cleanSuspendedTransactions()}. */ @@ -926,4 +964,68 @@ public class TransactionUtil implements public void beforeCompletion() { } } + + public static final class NoTransaction<V> implements Callable<V> { + private final Callable<V> callable; + + protected NoTransaction(Callable<V> callable) { + this.callable = callable; + } + + public V call() throws Exception { + Transaction suspended = TransactionUtil.suspend(); + try { + return callable.call(); + } finally { + TransactionUtil.resume(suspended); + } + } + } + + public static final class InTransaction<V> implements Callable<V> { + private final Callable<V> callable; + private final String ifErrorMessage; + private final int timeout; + private final boolean printException; + + protected InTransaction(Callable<V> callable, String ifErrorMessage, int timeout, boolean printException) { + this.callable = callable; + this.ifErrorMessage = ifErrorMessage; + this.timeout = timeout; + this.printException = printException; + } + + public V call() throws GenericEntityException { + boolean tx = TransactionUtil.begin(timeout); + Throwable transactionAbortCause = null; + try { + try { + return callable.call(); + } catch (Throwable t) { + while (t.getCause() != null) { + t = t.getCause(); + } + throw t; + } + } catch (Error e) { + transactionAbortCause = e; + throw e; + } catch (RuntimeException e) { + transactionAbortCause = e; + throw e; + } catch (Throwable t) { + transactionAbortCause = t; + throw new GenericEntityException(t); + } finally { + if (transactionAbortCause == null) { + TransactionUtil.commit(tx); + } else { + if (printException) { + transactionAbortCause.printStackTrace(); + } + TransactionUtil.rollback(tx, ifErrorMessage, transactionAbortCause); + } + } + } + } } |
Free forum by Nabble | Edit this page |