Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.entity.condition.EntityCondition;
import org.apache.ofbiz.entity.finder.EntityFinderUtil.Condition;
import org.apache.ofbiz.entity.finder.EntityFinderUtil.ConditionDate;
import org.apache.ofbiz.entity.finder.EntityFinderUtil.ConditionExpr;
import org.apache.ofbiz.entity.finder.EntityFinderUtil.ConditionList;
import org.apache.ofbiz.entity.finder.EntityFinderUtil.ConditionObject;
Expand All @@ -47,15 +48,15 @@ public ByConditionFinder(Element element) {
// NOTE: the whereCondition can be null, ie (condition-expr | condition-list) is optional; if left out, means find all,
// or with no condition in essense
// process condition-expr | condition-list
Element conditionExprElement = UtilXml.firstChildElement(element, "condition-expr");
Element conditionListElement = UtilXml.firstChildElement(element, "condition-list");
Element conditionObjectElement = UtilXml.firstChildElement(element, "condition-object");
if (conditionExprElement != null) {
this.whereCondition = new ConditionExpr(conditionExprElement);
} else if (conditionListElement != null) {
this.whereCondition = new ConditionList(conditionListElement);
} else if (conditionObjectElement != null) {
this.whereCondition = new ConditionObject(conditionObjectElement);
Element conditionElement = UtilXml.firstChildElement(element);
if (conditionElement != null) {
this.whereCondition = switch (UtilXml.getTagNameIgnorePrefix(conditionElement)) {
case "condition-expr" -> new ConditionExpr(conditionElement);
case "condition-date" -> new ConditionDate(conditionElement);
case "condition-list" -> new ConditionList(conditionElement);
case "condition-object" -> new ConditionObject(conditionElement);
default -> null;
};
}

Element havingConditionListElement = UtilXml.firstChildElement(element, "having-condition-list");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
*******************************************************************************/
package org.apache.ofbiz.entity.finder;

import java.sql.Timestamp;
import java.util.Locale;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.UtilDateTime;
import static org.apache.ofbiz.base.util.UtilGenerics.cast;

import java.io.Serializable;
Expand All @@ -35,10 +39,12 @@
import org.apache.ofbiz.base.util.ObjectType;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor;
import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
import org.apache.ofbiz.entity.GenericEntity;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.condition.EntityComparisonOperator;
Expand All @@ -47,6 +53,7 @@
import org.apache.ofbiz.entity.condition.EntityJoinOperator;
import org.apache.ofbiz.entity.condition.EntityOperator;
import org.apache.ofbiz.entity.model.ModelEntity;
import org.apache.ofbiz.entity.model.ModelField;
import org.apache.ofbiz.entity.model.ModelFieldTypeReader;
import org.apache.ofbiz.entity.util.EntityListIterator;
import org.w3c.dom.Element;
Expand Down Expand Up @@ -286,6 +293,9 @@ public ConditionList(Element conditionListElement) {
case "condition-expr":
conditionList.add(new ConditionExpr(subElement));
break;
case "condition-date":
conditionList.add(new ConditionDate(subElement));
break;
case "condition-list":
conditionList.add(new ConditionList(subElement));
break;
Expand Down Expand Up @@ -341,6 +351,86 @@ public EntityCondition createCondition(Map<String, ? extends Object> context, Mo
}
}

@SuppressWarnings("serial")
public static final class ConditionDate implements Condition {
private final FlexibleMapAccessor<Object> dateField;
private final List<FlexibleStringExpander> compareDateFields;
private final FlexibleStringExpander ignoreExdr;
private final boolean ignoreIfNull;
private final boolean ignoreIfEmpty;

public ConditionDate(Element conditionDateElement) {
String fieldDateName = conditionDateElement.getAttribute("from-field");
this.dateField = !fieldDateName.isEmpty()
? FlexibleMapAccessor.getInstance(fieldDateName)
: null;
List<FlexibleStringExpander> collectedCompareDateFields = UtilXml.childElementList(conditionDateElement).stream()
.map(e -> FlexibleStringExpander.getInstance(e.getAttribute("field-name")))
.toList();
compareDateFields = !(collectedCompareDateFields.isEmpty() || collectedCompareDateFields.size() % 2 != 0)
? collectedCompareDateFields
: List.of(FlexibleStringExpander.getInstance("fromDate"),
FlexibleStringExpander.getInstance("thruDate"));
this.ignoreIfNull = "true".equals(conditionDateElement.getAttribute("ignore-if-null"));
this.ignoreIfEmpty = "true".equals(conditionDateElement.getAttribute("ignore-if-empty"));
this.ignoreExdr = FlexibleStringExpander.getInstance(conditionDateElement.getAttribute("ignore"));
}

@Override
public EntityCondition createCondition(Map<String, ? extends Object> context, ModelEntity modelEntity, ModelFieldTypeReader
modelFieldTypeReader) {
if ("true".equals(this.ignoreExdr.expandString(context))) {
return null;
}
Timestamp dateFieldValue = null;
ModelField dateFieldFromEntity = null;
if (this.dateField != null) {
dateFieldFromEntity = modelEntity.getField(dateField.getOriginalName());
if (dateFieldFromEntity == null) {
Object valueFound = dateField.get(context);
if (valueFound != null) {
try {
dateFieldValue = (Timestamp) ObjectType.simpleTypeOrObjectConvert(
valueFound, "java.sql.Timestamp", "", (Locale) context.get("locale"));
} catch (GeneralException e) {
Debug.logWarning("Failed to convert value " + valueFound, MODULE);
}
}
}
}
if (this.ignoreIfNull && dateFieldValue == null) {
return null;
}
if (this.ignoreIfEmpty && ObjectType.isEmpty(dateFieldValue)) {
return null;
}
if (UtilValidate.isEmpty(dateFieldValue)) {
dateFieldValue = UtilDateTime.nowTimestamp();
}
List<EntityCondition> conditionDates = UtilMisc.toList();
for (int i = 0; i < compareDateFields.size() / 2; i++) {
String fromDateField = compareDateFields.get(i).expandString(context);
String thruDateField = compareDateFields.get(i + 1).expandString(context);
if (dateFieldFromEntity != null) {
ModelField fromDateModelField = modelEntity.getField(fromDateField);
ModelField thruDateModelField = modelEntity.getField(thruDateField);
conditionDates.add(EntityCondition.makeConditionWhere(
fromDateModelField.getColName() + " <= " + dateFieldFromEntity.getColName()));
conditionDates.add(EntityCondition.makeCondition(EntityOperator.OR,
EntityCondition.makeConditionWhere(thruDateModelField.getColName() + " >= " + dateFieldFromEntity.getColName()),
EntityCondition.makeCondition(thruDateField, EntityOperator.EQUALS, GenericEntity.NULL_FIELD)));
} else {
conditionDates.add(EntityCondition.makeCondition(fromDateField, EntityOperator.LESS_THAN_EQUAL_TO, dateFieldValue));
conditionDates.add(EntityCondition.makeCondition(EntityOperator.OR,
EntityCondition.makeCondition(thruDateField, EntityOperator.GREATER_THAN_EQUAL_TO, dateFieldValue),
EntityCondition.makeCondition(thruDateField, EntityOperator.EQUALS, GenericEntity.NULL_FIELD)));
}
}

return EntityCondition.makeCondition(conditionDates);
}
}

public interface OutputHandler extends Serializable {
void handleOutput(EntityListIterator eli, Map<String, Object> context, FlexibleMapAccessor<Object> listAcsr);
void handleOutput(List<GenericValue> results, Map<String, Object> context, FlexibleMapAccessor<Object> listAcsr);
Expand Down
31 changes: 31 additions & 0 deletions framework/widget/dtd/widget-common.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ under the License.
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="condition-expr" />
<xs:element ref="condition-date" />
<xs:element ref="condition-list" />
<xs:element ref="condition-object" />
</xs:choice>
Expand All @@ -375,6 +376,7 @@ under the License.
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="condition-expr" />
<xs:element ref="condition-date" />
<xs:element ref="condition-list" />
<xs:element ref="condition-object" />
</xs:choice>
Expand Down Expand Up @@ -422,6 +424,35 @@ under the License.
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="condition-date">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element ref="date-field" />
</xs:choice>
<xs:attribute type="xs:string" name="from-field">
<xs:annotation>
<xs:documentation>
field in context that contains the date to use for filter
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ignore-if-null" type="xs:boolean" default="false"/>
<xs:attribute name="ignore-if-empty" type="xs:boolean" default="false"/>
<xs:attribute name="ignore" type="xs:boolean" default="false">
<xs:annotation>
<xs:documentation>
Ignore the condition if flag is true.
Defaults to false.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="date-field">
<xs:complexType>
<xs:attribute name="field-name" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="condition-object">
<xs:complexType>
<xs:attribute type="xs:string" name="field" use="required" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,30 +86,19 @@ public abstract class AbstractModelAction implements Serializable, ModelAction {
* @return A new <code>ModelAction</code> instance
*/
public static ModelAction newInstance(ModelWidget modelWidget, Element actionElement) {
String nodeName = UtilXml.getNodeNameIgnorePrefix(actionElement);
if ("set".equals(nodeName)) {
return new SetField(modelWidget, actionElement);
} else if ("property-map".equals(nodeName)) {
return new PropertyMap(modelWidget, actionElement);
} else if ("property-to-field".equals(nodeName)) {
return new PropertyToField(modelWidget, actionElement);
} else if ("script".equals(nodeName)) {
return new Script(modelWidget, actionElement);
} else if ("service".equals(nodeName)) {
return new Service(modelWidget, actionElement);
} else if ("entity-one".equals(nodeName)) {
return new EntityOne(modelWidget, actionElement);
} else if ("entity-and".equals(nodeName)) {
return new EntityAnd(modelWidget, actionElement);
} else if ("entity-condition".equals(nodeName)) {
return new EntityCondition(modelWidget, actionElement);
} else if ("get-related-one".equals(nodeName)) {
return new GetRelatedOne(modelWidget, actionElement);
} else if ("get-related".equals(nodeName)) {
return new GetRelated(modelWidget, actionElement);
} else {
throw new IllegalArgumentException("Action element not supported with name: " + actionElement.getNodeName());
}
return switch (UtilXml.getNodeNameIgnorePrefix(actionElement)) {
case "set" -> new SetField(modelWidget, actionElement);
case "property-map" -> new PropertyMap(modelWidget, actionElement);
case "property-to-field" -> new PropertyToField(modelWidget, actionElement);
case "script" -> new Script(modelWidget, actionElement);
case "service" -> new Service(modelWidget, actionElement);
case "entity-one" -> new EntityOne(modelWidget, actionElement);
case "entity-and" -> new EntityAnd(modelWidget, actionElement);
case "entity-condition" -> new EntityCondition(modelWidget, actionElement);
case "get-related-one" -> new GetRelatedOne(modelWidget, actionElement);
case "get-related" -> new GetRelated(modelWidget, actionElement);
default -> throw new IllegalArgumentException("Action element not supported with name: " + actionElement.getNodeName());
};
}

public static List<ModelAction> readSubActions(ModelWidget modelWidget, Element parentElement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ public static List<ModelAction> readSubActions(ModelForm modelForm, Element pare
List<ModelAction> actions = new ArrayList<>(actionElementList.size());
for (Element actionElement : UtilXml.childElementList(parentElement)) {
String nodeName = actionElement.getLocalName();
if ("service".equals(nodeName)) {
switch (nodeName) {
case "service":
actions.add(new Service(modelForm, actionElement));
} else if ("entity-and".equals(nodeName) || "entity-condition".equals(nodeName)
|| "get-related".equals(nodeName)) {
break;
case "entity-and":
case "entity-condition":
case "get-related":
if (!actionElement.hasAttribute("list")) {
String listName = modelForm.getListName();
if (UtilValidate.isEmpty(listName)) {
Expand All @@ -61,9 +64,11 @@ public static List<ModelAction> readSubActions(ModelForm modelForm, Element pare
actionElement.setAttribute("list", listName);
}
actions.add(AbstractModelAction.newInstance(modelForm, actionElement));
} else if ("call-parent-actions".equals(nodeName)) {
break;
case "call-parent-actions":
actions.add(new CallParentActions(modelForm, actionElement));
} else {
break;
default:
actions.add(AbstractModelAction.newInstance(modelForm, actionElement));
}
}
Expand Down
Loading