use of io.jmix.core.metamodel.model.MetaPropertyPath in project jmix by jmix-framework.
the class DynAttrPropertyConditionGenerator method generateWhere.
@Override
public String generateWhere(ConditionGenerationContext context) {
PropertyCondition condition = (PropertyCondition) context.getCondition();
if (condition == null) {
return "";
}
String[] properties = condition.getProperty().split("\\.");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < properties.length; i++) {
String property = properties[i];
if (DynAttrUtils.isDynamicAttributeProperty(property)) {
String propertyPath = sb.toString();
String dynAttrPropertyPath = i == 0 ? property : propertyPath.substring(1) + "." + property;
String entityName = context.getEntityName();
MetaClass entityMetaClass = metadata.findClass(entityName);
if (entityMetaClass != null) {
MetaPropertyPath mpp = metadataTools.resolveMetaPropertyPathOrNull(entityMetaClass, dynAttrPropertyPath);
if (mpp != null && mpp.getMetaProperty() instanceof DynAttrMetaProperty) {
return generateWhere(propertyPath, context, (DynAttrMetaProperty) mpp.getMetaProperty());
}
}
}
sb.append(".");
sb.append(property);
}
return "";
}
use of io.jmix.core.metamodel.model.MetaPropertyPath in project jmix by jmix-framework.
the class DynAttrMetaPropertyPathResolver method resolveMetaPropertyPath.
@Override
public MetaPropertyPath resolveMetaPropertyPath(MetaClass metaClass, String propertyPath) {
String[] properties = propertyPath.split("\\.");
MetaProperty[] metaProperties = new MetaProperty[properties.length];
MetaProperty currentProperty;
MetaClass currentClass = metaClass;
for (int i = 0; i < properties.length; i++) {
if (currentClass == null) {
return null;
}
currentProperty = currentClass.findProperty(properties[i]);
if (currentProperty == null) {
if (!DynAttrUtils.isDynamicAttributeProperty(properties[i])) {
return null;
}
AttributeDefinition attribute = dynAttrMetadata.getAttributeByCode(currentClass, DynAttrUtils.getAttributeCodeFromProperty(properties[i])).orElse(null);
if (attribute == null) {
return null;
}
currentProperty = attribute.getMetaProperty();
}
Range range = currentProperty.getRange();
currentClass = range.isClass() ? range.asClass() : null;
metaProperties[i] = currentProperty;
}
return new MetaPropertyPath(metaClass, metaProperties);
}
use of io.jmix.core.metamodel.model.MetaPropertyPath in project jmix by jmix-framework.
the class ContainerValueSource method setApplicationContext.
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
MetaClass metaClass = container.getEntityMetaClass();
MetadataTools metadataTools = applicationContext.getBean(MetadataTools.class);
this.metaPropertyPath = metadataTools.resolveMetaPropertyPath(metaClass, property);
this.container.addItemChangeListener(this::containerItemChanged);
this.container.addItemPropertyChangeListener(this::containerItemPropertyChanged);
@SuppressWarnings("unchecked") InstanceContainer<?> parentCont = container;
for (int i = 1; i < this.metaPropertyPath.length(); i++) {
MetaPropertyPath intermediatePath = new MetaPropertyPath(this.metaPropertyPath.getMetaClass(), Arrays.copyOf(this.metaPropertyPath.getMetaProperties(), i));
String pathToTarget = Joiner.on('.').join(Arrays.copyOfRange(this.metaPropertyPath.getPath(), i, this.metaPropertyPath.length()));
DataComponents dataComponents = applicationContext.getBean(DataComponents.class);
@SuppressWarnings("unchecked") InstanceContainer<Object> propertyCont = dataComponents.createInstanceContainer(intermediatePath.getRangeJavaClass());
parentCont.addItemChangeListener(event -> {
if (event.getItem() != null) {
setState(BindingState.ACTIVE);
} else {
setState(BindingState.INACTIVE);
}
propertyCont.setItem(event.getItem() != null ? EntityValues.getValueEx(event.getItem(), intermediatePath.getMetaProperty().getName()) : null);
});
parentCont.addItemPropertyChangeListener(event -> {
if (Objects.equals(event.getProperty(), intermediatePath.getMetaProperty().getName())) {
Object entity = event.getValue();
Object prevEntity = event.getPrevValue();
propertyCont.setItem(entity);
V prevValue = prevEntity != null ? EntityValues.getValueEx(prevEntity, pathToTarget) : null;
V value = entity != null ? EntityValues.getValueEx(entity, pathToTarget) : null;
events.publish(ValueChangeEvent.class, new ValueChangeEvent<>(this, prevValue, value));
}
});
if (i == this.metaPropertyPath.length() - 1) {
propertyCont.addItemPropertyChangeListener(event -> {
if (Objects.equals(event.getProperty(), this.metaPropertyPath.getMetaProperty().getName())) {
events.publish(ValueChangeEvent.class, new ValueChangeEvent<>(this, (V) event.getPrevValue(), (V) event.getValue()));
}
});
}
parentCont = propertyCont;
}
}
use of io.jmix.core.metamodel.model.MetaPropertyPath in project jmix by jmix-framework.
the class ContainerValueSource method canUpdateMasterRefs.
protected boolean canUpdateMasterRefs() {
MetaPropertyPath mpp = getEntityMetaClass().getPropertyPath(metaPropertyPath.toPathString());
if (mpp == null) {
return false;
}
if (!mpp.getMetaProperty().getRange().getCardinality().isMany()) {
return false;
}
MetaProperty inverseProperty = mpp.getMetaProperty().getInverse();
return inverseProperty != null && inverseProperty.getType() == MetaProperty.Type.ASSOCIATION && !inverseProperty.getRange().getCardinality().isMany();
}
use of io.jmix.core.metamodel.model.MetaPropertyPath in project jmix by jmix-framework.
the class ValueBinder method bind.
public <V> ValueBinding<V> bind(HasValue<V> component, ValueSource<V> valueSource) {
if (valueSource instanceof ApplicationContextAware) {
((ApplicationContextAware) valueSource).setApplicationContext(applicationContext);
}
ValueBindingImpl<V> binding = new ValueBindingImpl<>(component, valueSource);
if (component instanceof Component.Editable) {
((Component.Editable) component).setEditable(!valueSource.isReadOnly());
}
if (valueSource instanceof EntityValueSource) {
EntityValueSource entityValueSource = (EntityValueSource) valueSource;
MetaPropertyPath metaPropertyPath = entityValueSource.getMetaPropertyPath();
if (component instanceof Field) {
initRequired((Field) component, metaPropertyPath);
initBeanValidator((Field<?>) component, metaPropertyPath);
}
if (entityValueSource.isDataModelSecurityEnabled()) {
UiEntityAttributeContext attributeContext = new UiEntityAttributeContext(metaPropertyPath);
accessManager.applyRegisteredConstraints(attributeContext);
if (component instanceof Component.Editable) {
MetaClass metaClass = entityValueSource.getEntityMetaClass();
boolean permittedIfEmbedded = true;
if (entityValueSource instanceof ContainerValueSource) {
InstanceContainer<?> container = ((ContainerValueSource<?, ?>) entityValueSource).getContainer();
if (container instanceof Nested && metaClass != null && metadataTools.isJpaEmbeddable(metaClass)) {
String embeddedProperty = ((Nested) container).getProperty();
MetaClass masterMetaClass = ((Nested) container).getMaster().getEntityMetaClass();
UiEntityAttributeContext embeddedAttributeContext = new UiEntityAttributeContext(masterMetaClass, embeddedProperty);
accessManager.applyRegisteredConstraints(embeddedAttributeContext);
permittedIfEmbedded = embeddedAttributeContext.canModify();
}
if (permittedIfEmbedded && metaPropertyPath.length() > 1) {
for (MetaProperty property : metaPropertyPath.getMetaProperties()) {
if (metadataTools.isEmbedded(property)) {
UiEntityAttributeContext childAttributeContext = new UiEntityAttributeContext(property.getDomain(), property.getName());
accessManager.applyRegisteredConstraints(childAttributeContext);
if (!childAttributeContext.canModify()) {
permittedIfEmbedded = false;
break;
}
}
}
}
}
if (!attributeContext.canModify() || !permittedIfEmbedded) {
((Component.Editable) component).setEditable(false);
}
}
if (!attributeContext.canView()) {
component.setVisible(false);
}
}
}
binding.bind();
return binding;
}
Aggregations