PL-7378 Refactor filter Param class to make it suitable for overriding it's logic

This commit is contained in:
Maxim Gorbunkov 2016-07-21 15:34:06 +04:00
parent 76155a47e9
commit fba5a73b25
7 changed files with 222 additions and 102 deletions

View File

@ -175,8 +175,15 @@ public class RelatedAction extends AbstractAction {
@SuppressWarnings("ConstantConditions")
Class idType = metaClass.getProperty(primaryKey).getJavaType();
Param param = new Param(paramBuilder.createParamName(condition), idType, "", "", component.getDatasource(),
metaClass.getProperty(primaryKey), true, true);
Param param = Param.Builder.getInstance().setName(paramBuilder.createParamName(condition))
.setJavaClass(idType)
.setEntityWhere("")
.setEntityView("")
.setDataSource(component.getDatasource())
.setProperty(metaClass.getProperty(primaryKey))
.setInExpr(true)
.setRequired(true)
.build();
param.setValue(ids);
condition.setParam(param);

View File

@ -33,25 +33,25 @@ import java.util.Map;
@Component(ConditionParamBuilder.NAME)
public class ConditionParamBuilderImpl implements ConditionParamBuilder{
protected Map<Class, Builder> builders = new HashMap<>();
protected Map<Class, ParameterInstantiationStrategy> strategies = new HashMap<>();
protected Builder defaultBuilder;
protected ParameterInstantiationStrategy defaultParameterInstantiationStrategy;
@PostConstruct
public void initBuilders() {
builders.put(PropertyCondition.class, new PropertyParamBuilder());
builders.put(DynamicAttributesCondition.class, new DynamicPropertyParamBuilder());
defaultBuilder = new DefaultParamBuilder();
public void initCreatingStrategies() {
strategies.put(PropertyCondition.class, new PropertyParameterInstantiationStrategy());
strategies.put(DynamicAttributesCondition.class, new DynamicPropertyParameterInstantiationStrategy());
defaultParameterInstantiationStrategy = new DefaultParameterInstantiationStrategy();
}
@Override
public Param createParam(AbstractCondition condition) {
Builder builder = builders.get(condition.getClass());
if (builder == null) {
builder = defaultBuilder;
ParameterInstantiationStrategy parameterInstantiationStrategy = strategies.get(condition.getClass());
if (parameterInstantiationStrategy == null) {
parameterInstantiationStrategy = defaultParameterInstantiationStrategy;
}
return builder.createParam(condition);
return parameterInstantiationStrategy.createParam(condition);
}
@Override
@ -60,49 +60,71 @@ public class ConditionParamBuilderImpl implements ConditionParamBuilder{
condition.getName().replace('.', '_').replace(" ", "_") + RandomStringUtils.randomNumeric(5);
}
protected interface Builder {
protected interface ParameterInstantiationStrategy {
Param createParam(AbstractCondition condition);
}
protected class DefaultParamBuilder implements Builder {
protected class DefaultParameterInstantiationStrategy implements ParameterInstantiationStrategy {
@Override
public Param createParam(AbstractCondition condition) {
if (condition.getUnary())
return new Param(condition.getParamName(), null, null, null, null, false, condition.getRequired());
Param.Builder builder = getParamBuilder(condition);
return builder.build();
}
return new Param(condition.getParamName(), condition.getParamClass() == null ? condition.getJavaClass() : condition.getParamClass(),
condition.getEntityParamWhere(), condition.getEntityParamView(), condition.getDatasource(), condition.getInExpr(), condition.getRequired());
protected Param.Builder getParamBuilder(AbstractCondition condition) {
Param.Builder builder = Param.Builder.getInstance()
.setName(condition.getParamName())
.setRequired(condition.getRequired());
if (!condition.getUnary()) {
builder.setJavaClass(condition.getParamClass() == null ?
condition.getJavaClass() : condition.getParamClass());
builder.setEntityWhere(condition.getEntityParamWhere());
builder.setEntityView(condition.getEntityParamView());
builder.setDataSource(condition.getDatasource());
builder.setInExpr(condition.getInExpr());
}
return builder;
}
}
protected class PropertyParamBuilder implements Builder {
protected class PropertyParameterInstantiationStrategy extends DefaultParameterInstantiationStrategy {
@Override
public Param createParam(AbstractCondition condition) {
if (condition.getUnary())
return new Param(condition.getParamName(), Boolean.class, null, null, null, false, condition.getRequired());
public Param.Builder getParamBuilder(AbstractCondition condition) {
Param.Builder builder = super.getParamBuilder(condition);
MetaProperty metaProperty = condition.getDatasource().getMetaClass().getProperty(condition.getName());
return new Param(condition.getParamName(), condition.getJavaClass(), condition.getEntityParamWhere(), condition.getEntityParamView(),
condition.getDatasource(), metaProperty, condition.getInExpr(), condition.getRequired());
if (!condition.getUnary())
builder.setJavaClass(condition.getJavaClass())
.setProperty(metaProperty);
return builder;
}
}
protected class DynamicPropertyParamBuilder extends DefaultParamBuilder {
protected class DynamicPropertyParameterInstantiationStrategy extends DefaultParameterInstantiationStrategy {
@Override
public Param createParam(AbstractCondition condition) {
public Param.Builder getParamBuilder(AbstractCondition condition) {
Param.Builder builder;
DynamicAttributesCondition _condition = (DynamicAttributesCondition) condition;
if (_condition.getCategoryAttributeId() != null) {
Class paramJavaClass = _condition.getUnary() ? Boolean.class : _condition.getJavaClass();
MetaPropertyPath metaPropertyPath = DynamicAttributesUtils.getMetaPropertyPath(_condition.getDatasource().getMetaClass(), _condition.getCategoryAttributeId());
return new Param(_condition.getParamName(), paramJavaClass, null, null, _condition.getDatasource(),
metaPropertyPath != null ? metaPropertyPath.getMetaProperty() : null,
_condition.getInExpr(), _condition.getRequired(), _condition.getCategoryAttributeId());
} else {
return super.createParam(condition);
}
MetaPropertyPath metaPropertyPath = DynamicAttributesUtils.getMetaPropertyPath(
_condition.getDatasource().getMetaClass(), _condition.getCategoryAttributeId());
builder = Param.Builder.getInstance()
.setJavaClass(paramJavaClass)
.setEntityWhere(null)
.setEntityView(null)
.setDataSource(_condition.getDatasource())
.setProperty(metaPropertyPath != null ? metaPropertyPath.getMetaProperty() : null)
.setInExpr(_condition.getInExpr())
.setCategoryAttrId(_condition.getCategoryAttributeId())
.setRequired(condition.getRequired());
} else
builder = super.getParamBuilder(condition);
return builder;
}
}
}

View File

@ -48,6 +48,7 @@ import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrBuilder;
import org.dom4j.Element;
import org.springframework.context.annotation.Scope;
import javax.annotation.Nullable;
import javax.persistence.TemporalType;
@ -55,6 +56,8 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@org.springframework.stereotype.Component(Param.NAME)
@Scope("prototype")
public class Param {
public enum Type {
@ -70,6 +73,7 @@ public class Param {
DEFAULT_VALUE
}
public static final String NAME = "cuba_FilterParam";
public static final String NULL = "NULL";
protected String name;
@ -94,29 +98,87 @@ public class Param {
protected List<ParamValueChangeListener> listeners = new ArrayList<>();
public Param(String name, Class javaClass, String entityWhere, String entityView,
Datasource datasource, boolean inExpr, boolean required) {
this(name, javaClass, entityWhere, entityView, datasource, null, inExpr, required);
public static class Builder {
private String name;
private Class javaClass;
private String entityWhere;
private String entityView;
private Datasource dataSource;
private MetaProperty property;
private boolean inExpr;
private boolean required;
private UUID categoryAttrId;
private Builder() {
}
public static Builder getInstance() {
return new Builder();
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setJavaClass(Class javaClass) {
this.javaClass = javaClass;
return this;
}
public Builder setEntityWhere(String entityWhere) {
this.entityWhere = entityWhere;
return this;
}
public Builder setEntityView(String entityView) {
this.entityView = entityView;
return this;
}
public Builder setDataSource(Datasource dataSource) {
this.dataSource = dataSource;
return this;
}
public Builder setProperty(MetaProperty property) {
this.property = property;
return this;
}
public Builder setInExpr(boolean inExpr) {
this.inExpr = inExpr;
return this;
}
public Builder setRequired(boolean required) {
this.required = required;
return this;
}
public Builder setCategoryAttrId(UUID categoryAttrId) {
this.categoryAttrId = categoryAttrId;
return this;
}
public Param build() {
return AppBeans.getPrototype(Param.NAME, this);
}
}
public Param(String name, Class javaClass, String entityWhere, String entityView,
Datasource datasource, MetaProperty property, boolean inExpr, boolean required, UUID categoryAttrId) {
this(name, javaClass, entityWhere, entityView, datasource, property, inExpr, required);
this.categoryAttrId = categoryAttrId;
}
public Param(Builder builder) {
name = builder.name;
setJavaClass(builder.javaClass);
entityWhere = builder.entityWhere;
entityView = (builder.entityView != null) ? builder.entityView : View.MINIMAL;
datasource = builder.dataSource;
property = builder.property;
inExpr = builder.inExpr;
required = builder.required;
categoryAttrId = builder.categoryAttrId;
public Param(String name, Class javaClass, String entityWhere, String entityView, Datasource datasource,
MetaProperty property, boolean inExpr, boolean required) {
this.name = name;
setJavaClass(javaClass);
this.entityWhere = entityWhere;
this.entityView = (entityView != null) ? entityView : View.MINIMAL;
this.datasource = datasource;
this.property = property;
this.inExpr = inExpr;
this.required = required;
if (DynamicAttributesUtils.isDynamicAttribute(property)) {
CategoryAttribute categoryAttribute = DynamicAttributesUtils.getCategoryAttribute(property);
if (DynamicAttributesUtils.isDynamicAttribute(builder.property)) {
CategoryAttribute categoryAttribute = DynamicAttributesUtils.getCategoryAttribute(builder.property);
if (categoryAttribute.getDataType() == PropertyType.ENUMERATION) {
type = Type.RUNTIME_ENUM;
}
@ -190,6 +252,7 @@ public class Param {
}
}
@SuppressWarnings("unchecked")
public void parseValue(String text) {
if (NULL.equals(text)) {
value = null;
@ -242,14 +305,14 @@ public class Param {
try {
value = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(text);
} catch (ParseException exception) {
throw new RuntimeException(e);
throw new RuntimeException("Can not parse date from string " + text, e);
}
}
} else {
try {
value = datatype.parse(text);
} catch (ParseException e) {
throw new RuntimeException(e);
throw new RuntimeException("Parse exception for string " + text, e);
}
}
break;
@ -262,20 +325,18 @@ public class Param {
protected List<Entity> loadEntityList(String[] ids) {
Metadata metadata = AppBeans.get(Metadata.class);
MetaClass metaClass = metadata.getSession().getClass(javaClass);
MetaClass metaClass = metadata.getSession().getClassNN(javaClass);
LoadContext ctx = new LoadContext(javaClass);
LoadContext.Query query = ctx.setQueryString("select e from " + metaClass.getName() + " e where e.id in :ids");
query.setParameter("ids", Arrays.asList(ids));
DataManager dataManager = AppBeans.get(DataManager.class);
List result = dataManager.loadList(ctx);
return result;
return dataManager.loadList(ctx);
}
protected Object loadEntity(String id) {
LoadContext ctx = new LoadContext(javaClass).setId(UUID.fromString(id));
DataService dataService = AppBeans.get(DataService.NAME);
Entity entity = dataService.load(ctx);
return entity;
return dataService.load(ctx);
}
public String formatValue(Object value) {
@ -307,10 +368,9 @@ public class Param {
case ENUM:
return ((Enum) v).name();
case RUNTIME_ENUM:
// return (String) v;
case DATATYPE:
case UNARY:
//noinspection unchecked
Datatype<Object> datatype = Datatypes.getNN(javaClass);
return datatype.format(v);
@ -564,6 +624,7 @@ public class Param {
});
UserSessionSource sessionSource = AppBeans.get(UserSessionSource.NAME);
//noinspection unchecked
field.setValue(datatype.format(_getValue(valueProperty), sessionSource.getLocale()));
return field;
}
@ -637,7 +698,7 @@ public class Param {
protected Component createEntityLookup(final ValueProperty valueProperty) {
Metadata metadata = AppBeans.get(Metadata.NAME);
MetaClass metaClass = metadata.getSession().getClass(javaClass);
MetaClass metaClass = metadata.getSession().getClassNN(javaClass);
ThemeConstants theme = AppBeans.get(ThemeConstantsManager.class).getConstants();
PersistenceManagerService persistenceManager = AppBeans.get(PersistenceManagerService.NAME);
@ -663,41 +724,20 @@ public class Param {
return picker;
}
} else {
CollectionDatasource ds = new DsBuilder(datasource.getDsContext())
.setMetaClass(metaClass)
.setViewName(entityView)
.buildCollectionDatasource();
ds.setRefreshOnComponentValueChange(true);
((DatasourceImplementation) ds).initialized();
if (!StringUtils.isBlank(entityWhere)) {
QueryTransformer transformer = QueryTransformerFactory.createTransformer(
"select e from " + metaClass.getName() + " e");
transformer.addWhere(entityWhere);
String q = transformer.getResult();
ds.setQuery(q);
}
if (WindowParams.DISABLE_AUTO_REFRESH.getBool(datasource.getDsContext().getFrameContext())) {
if (ds instanceof CollectionDatasource.Suspendable)
((CollectionDatasource.Suspendable) ds).refreshIfNotSuspended();
else
ds.refresh();
}
CollectionDatasource<Entity<Object>, Object> optionsDataSource = createOptionsDataSource(metaClass);
if (inExpr) {
final InListParamComponent inListParamComponent = new InListParamComponent(ds);
final InListParamComponent inListParamComponent = new InListParamComponent(optionsDataSource);
initListEdit(inListParamComponent, valueProperty);
return inListParamComponent.getComponent();
} else {
final LookupPickerField lookup = componentsFactory.createComponent(LookupPickerField.class);
lookup.addClearAction();
lookup.setWidth(theme.get("cuba.gui.filter.Param.textComponent.width"));
lookup.setOptionsDatasource(ds);
lookup.setOptionsDatasource(optionsDataSource);
//noinspection unchecked
ds.addCollectionChangeListener(e -> lookup.setValue(null));
optionsDataSource.addCollectionChangeListener(e -> lookup.setValue(null));
lookup.addValueChangeListener(e -> _setValue(e.getValue(), valueProperty));
lookup.setValue(_getValue(valueProperty));
@ -707,6 +747,33 @@ public class Param {
}
}
protected CollectionDatasource<Entity<Object>, Object> createOptionsDataSource(MetaClass metaClass) {
CollectionDatasource<Entity<Object>, Object> ds = new DsBuilder(datasource.getDsContext())
.setMetaClass(metaClass)
.setViewName(entityView)
.buildCollectionDatasource();
ds.setRefreshOnComponentValueChange(true);
((DatasourceImplementation) ds).initialized();
if (!StringUtils.isBlank(entityWhere)) {
QueryTransformer transformer = QueryTransformerFactory.createTransformer(
"select e from " + metaClass.getName() + " e");
transformer.addWhere(entityWhere);
String q = transformer.getResult();
ds.setQuery(q);
}
if (WindowParams.DISABLE_AUTO_REFRESH.getBool(datasource.getDsContext().getFrameContext())) {
if (ds instanceof CollectionDatasource.Suspendable)
((CollectionDatasource.Suspendable) ds).refreshIfNotSuspended();
else
ds.refresh();
}
return ds;
}
protected Component createEnumLookup(final ValueProperty valueProperty) {
if (inExpr) {
final InListParamComponent inListParamComponent = new InListParamComponent(javaClass);

View File

@ -146,7 +146,12 @@ public class DynamicAttributesCondition extends AbstractCondition {
if (operator.isUnary()) {
unary = true;
inExpr = false;
setParam(new Param(paramName, Boolean.class, null, null, null, false, required));
Param param = Param.Builder.getInstance()
.setName(paramName)
.setJavaClass(Boolean.class)
.setInExpr(false)
.setRequired(required).build();
setParam(param);
} else {
unary = false;
inExpr = operator.equals(Op.IN) || operator.equals(Op.NOT_IN);

View File

@ -24,8 +24,8 @@ import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.MessageTools;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.core.global.QueryUtils;
import com.haulmont.cuba.gui.components.filter.ConditionParamBuilder;
import com.haulmont.cuba.core.global.filter.Op;
import com.haulmont.cuba.gui.components.filter.ConditionParamBuilder;
import com.haulmont.cuba.gui.components.filter.Param;
import com.haulmont.cuba.gui.components.filter.descriptor.AbstractConditionDescriptor;
import com.haulmont.cuba.gui.components.filter.operationedit.AbstractOperationEditor;
@ -139,7 +139,13 @@ public class PropertyCondition extends AbstractCondition {
if (operator.isUnary()) {
unary = true;
inExpr = false;
setParam(new Param(paramName, Boolean.class, null, null, null, false, required));
Param param = Param.Builder.getInstance()
.setName(paramName)
.setJavaClass(Boolean.class)
.setInExpr(false)
.setRequired(required)
.build();
setParam(param);
} else {
unary = false;
inExpr = operator.equals(Op.IN) || operator.equals(Op.NOT_IN);

View File

@ -369,9 +369,15 @@ public class CustomConditionFrame extends ConditionFrame<CustomCondition> {
String entityParamView = entityParamViewField.getValue();
condition.setEntityParamView(entityParamView);
Param param = new Param(
paramName, javaClass, entityParamWhere, entityParamView, condition.getDatasource(),
condition.getInExpr(), condition.getRequired());
Param param = Param.Builder.getInstance()
.setName(paramName)
.setJavaClass(javaClass)
.setEntityWhere(entityParamWhere)
.setEntityView(entityParamView)
.setDataSource(condition.getDatasource())
.setInExpr(condition.getInExpr())
.setRequired(condition.getRequired())
.build();
param.setDefaultValue(condition.getParam().getDefaultValue());
@ -510,7 +516,7 @@ public class CustomConditionFrame extends ConditionFrame<CustomCondition> {
int cursorPos = hintRequest.getPosition();
String lastWord = getLastWord(input, cursorPos);
return (":".equals(lastWord)) ?
hintParameterNames(lastWord):
hintParameterNames(lastWord) :
super.requestHint(hintRequest);
}

View File

@ -29,11 +29,11 @@ import com.haulmont.cuba.core.entity.Entity;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.MessageTools;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.core.global.filter.Op;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.components.Label;
import com.haulmont.cuba.gui.components.LookupField;
import com.haulmont.cuba.gui.components.filter.ConditionParamBuilder;
import com.haulmont.cuba.core.global.filter.Op;
import com.haulmont.cuba.gui.components.filter.OpManager;
import com.haulmont.cuba.gui.components.filter.Param;
import com.haulmont.cuba.gui.components.filter.condition.DynamicAttributesCondition;
@ -185,9 +185,16 @@ public class DynamicAttributesConditionFrame extends ConditionFrame<DynamicAttri
condition.setOperator(operationLookup.<Op>getValue());
Class paramJavaClass = op.isUnary() ? Boolean.class : javaClass;
condition.setJavaClass(javaClass);
Param param = new Param(paramName, paramJavaClass, null, null, condition.getDatasource(),
DynamicAttributesUtils.getMetaPropertyPath(null, attribute).getMetaProperty(),
condition.getInExpr(), condition.getRequired(), attribute.getId());
Param param = Param.Builder.getInstance()
.setName(paramName)
.setJavaClass(paramJavaClass)
.setDataSource(condition.getDatasource())
.setProperty(DynamicAttributesUtils.getMetaPropertyPath(null, attribute).getMetaProperty())
.setInExpr(condition.getInExpr())
.setRequired(condition.getRequired())
.setCategoryAttrId(attribute.getId())
.build();
Object defaultValue = condition.getParam().getDefaultValue();
param.setDefaultValue(defaultValue);