Skip to content

Commit

Permalink
Merge branch 'feature/gui-wrapper' of https://github.com/Evolveum/mid…
Browse files Browse the repository at this point in the history
…point into feature/gui-wrapper
  • Loading branch information
KaterynaHonchar committed May 29, 2019
2 parents c2d3ca5 + 38d601b commit 919d440
Show file tree
Hide file tree
Showing 19 changed files with 275 additions and 161 deletions.
Expand Up @@ -80,7 +80,7 @@ public interface ItemWrapper<V extends PrismValue, I extends Item<V, ID>, ID ext

<O extends ObjectType> ItemStatus findObjectStatus();

<OW extends PrismObjectWrapper<O>, O extends ObjectType> OW findObjectWrapper(ItemWrapper parent);
<OW extends PrismObjectWrapper<O>, O extends ObjectType> OW findObjectWrapper();


}
Expand Up @@ -37,6 +37,8 @@ public interface PrismObjectWrapper<O extends ObjectType> extends PrismContainer

PrismObject<O> getObjectOld();

PrismObject<O> getObjectApplyDelta() throws SchemaException;

String getOid();

PrismObjectValueWrapper<O> getValue();
Expand Down
Expand Up @@ -19,6 +19,7 @@

import org.springframework.stereotype.Component;

import com.evolveum.midpoint.gui.api.prism.ItemStatus;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType;
Expand All @@ -40,8 +41,8 @@ public boolean match(ItemDefinition<?> def) {
}

@Override
protected boolean canCreateNewWrapper(ItemDefinition<?> def) {
protected boolean canCreateNewWrapper(ItemDefinition<?> def, ItemStatus status, WrapperContext context) {
return false;
}

}
Expand Up @@ -15,6 +15,7 @@
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.web.component.message.FeedbackAlerts;

public abstract class ItemPanelContext<T, IW extends ItemWrapper> implements Serializable {

Expand All @@ -25,7 +26,7 @@ public abstract class ItemPanelContext<T, IW extends ItemWrapper> implements Ser
private IModel<IW> itemWrapper;
private ItemRealValueModel<T> realValueModel;

private FeedbackPanel feedbackPanel;
private FeedbackAlerts feedbackPanel;

private Form<?> form;

Expand Down Expand Up @@ -88,7 +89,7 @@ public ItemRealValueModel<T> getRealValueModel() {
}


public FeedbackPanel getFeedbackPanel() {
public FeedbackAlerts getFeedbackPanel() {
return feedbackPanel;
}

Expand All @@ -107,7 +108,7 @@ public void setParentComponent(Component parentComponent) {



public void setFeedbackPanel(FeedbackPanel feedbackPanel) {
public void setFeedbackPanel(FeedbackAlerts feedbackPanel) {
this.feedbackPanel = feedbackPanel;
}

Expand Down
Expand Up @@ -36,6 +36,7 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.component.prism.ContainerStatus;
import com.evolveum.midpoint.web.component.prism.ValueStatus;
import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType;

Expand All @@ -56,21 +57,29 @@ public IW createWrapper(PrismContainerValueWrapper<?> parent, ItemDefinition<?>
ItemName name = def.getName();

I childItem = (I) parent.getNewValue().findItem(name);
ItemStatus status = ItemStatus.NOT_CHANGED;
if (childItem == null) {
if (!context.isForceCreate() && !canCreateNewWrapper(def)) {
LOGGER.trace("Skipping reating wrapper for non-existent item. It is not supported for {}", def);
return null;
}
ItemStatus status = getStatus(childItem);

if (!canCreateNewWrapper(def, status, context)) {
LOGGER.trace("Skipping creating wrapper for non-existent item. It is not supported for {}", def);
return null;
}

if (childItem == null) {
childItem = (I) parent.getNewValue().findOrCreateItem(name);
status = ItemStatus.ADDED;

}

return createWrapper(parent, childItem, status, context);
}

private ItemStatus getStatus(I childItem) {
if (childItem == null) {
return ItemStatus.ADDED;
}

return ItemStatus.NOT_CHANGED;

}


public IW createWrapper(Item childItem, ItemStatus status, WrapperContext context) throws SchemaException {
return createWrapper(null, (I) childItem, status, context);
Expand All @@ -83,7 +92,9 @@ private IW createWrapper(PrismContainerValueWrapper<?> parent, I childItem, Item
List<VW> valueWrappers = createValuesWrapper(itemWrapper, (I) childItem, context);
itemWrapper.getValues().addAll((Collection) valueWrappers);
itemWrapper.setShowEmpty(context.isShowEmpty(), false);
itemWrapper.setReadOnly(context.isReadOnly());

boolean readOnly = determineReadOnly(itemWrapper, context);
itemWrapper.setReadOnly(readOnly);

setupWrapper(itemWrapper);

Expand Down Expand Up @@ -118,9 +129,63 @@ protected <ID extends ItemDefinition<I>> List<VW> createValuesWrapper(IW itemWra

}

protected boolean canCreateNewWrapper(ItemDefinition<?> def) {
protected boolean canCreateNewWrapper(ItemDefinition<?> def, ItemStatus status, WrapperContext context) {
if (def.isOperational()) {
LOGGER.trace("Skipping creating wrapper for {}, because it is operational.", def.getName());
return false;
}

if (SearchFilterType.COMPLEX_TYPE.equals(def.getTypeName())) {
LOGGER.trace("Skipping creating wrapper for search filter: {}", def.getName());
return false;
}

if (def.isExperimental() && !WebModelServiceUtils.isEnableExperimentalFeature(modelInteractionService, context.getTask(), context.getResult())) {
LOGGER.trace("Skipping creating wrapper for {}, because experimental GUI features are turned off.", def);
return false;
}


if (ItemStatus.ADDED == status && def.isDeprecated()) {
LOGGER.trace("Skipping creating wrapeer for {}, because item is deprecated and doesn't contain any value.", def);
return false;
}

if (ItemStatus.ADDED == context.getObjectStatus() && !def.canAdd()) {
LOGGER.trace("Skipping creating wrapper for {}, becasue ADD operation is not supported");
return false;
}

if (ItemStatus.NOT_CHANGED == context.getObjectStatus()) {
if (!def.canRead()) {
LOGGER.trace("Skipping creating wrapper for {}, because read operation is not supported");
return false;
}

}

return true;
}

private boolean determineReadOnly(IW itemWrapper, WrapperContext context) {

Boolean readOnly = context.getReadOnly();
if (readOnly != null) {
LOGGER.trace("Setting {} as readonly because context said so.", itemWrapper);
return readOnly.booleanValue();
}

ItemStatus objectStatus = context.getObjectStatus();

if (ItemStatus.NOT_CHANGED == objectStatus) {
if (itemWrapper.canRead() && !itemWrapper.canModify()) {
LOGGER.trace("Setting {} as readonly because authZ said so");
return true;
}
}

return false;
}

protected boolean canCreateValueWrapper(PV pcv) {
return true;
Expand Down
Expand Up @@ -67,13 +67,15 @@ public class PrismObjectWrapperFactoryImpl<O extends ObjectType> extends PrismCo
private static final transient Trace LOGGER = TraceManager.getTrace(PrismObjectWrapperFactoryImpl.class);

@Autowired private GuiComponentRegistry registry;
@Autowired private ModelInteractionService modelInteractionService;
@Autowired private ModelService modelService;
@Autowired protected ModelInteractionService modelInteractionService;

public PrismObjectWrapper<O> createObjectWrapper(PrismObject<O> object, ItemStatus status, WrapperContext context) throws SchemaException {
applySecurityConstraints(object, context);

PrismObjectWrapperImpl<O> objectWrapper = new PrismObjectWrapperImpl<>(object, status);
if (context.getObjectStatus() == null) {
context.setObjectStatus(status);
}

PrismObjectWrapper<O> objectWrapper = createObjectWrapper(object, status);
context.setShowEmpty(ItemStatus.ADDED == status ? true : false);
PrismContainerValueWrapper<O> valueWrapper = createValueWrapper(objectWrapper, object.getValue(), ItemStatus.ADDED == status ? ValueStatus.ADDED : ValueStatus.NOT_CHANGED, context);
objectWrapper.getValues().add(valueWrapper);
Expand All @@ -88,6 +90,10 @@ public PrismObjectValueWrapper<O> createContainerValueWrapper(PrismContainerWrap
return new PrismObjectValueWrapperImpl<O>((PrismObjectWrapper<O>) objectWrapper, (PrismObjectValue<O>) objectValue, status);
}

public PrismObjectWrapper<O> createObjectWrapper(PrismObject<O> object, ItemStatus status) {
return new PrismObjectWrapperImpl<O>(object, status);
}

/**
*
* @param object
Expand All @@ -98,69 +104,20 @@ public PrismObjectValueWrapper<O> createContainerValueWrapper(PrismContainerWrap
* apply security constraint to the object, update wrapper context with additional information, e.g. shadow related attributes, ...
*/
protected void applySecurityConstraints(PrismObject<O> object, WrapperContext context) {
Class<O> objectClass = object.getCompileTimeClass();

AuthorizationPhaseType phase = context.getAuthzPhase();
Task task = context.getTask();
OperationResult result = context.getResult();
if (!ShadowType.class.isAssignableFrom(objectClass)) {
try {
PrismObjectDefinition<O> objectDef = modelInteractionService.getEditObjectDefinition(object, phase, task, result);
object.applyDefinition(objectDef, true);
} catch (SchemaException | ConfigurationException | ObjectNotFoundException | ExpressionEvaluationException
| CommunicationException | SecurityViolationException e) {
// TODO Auto-generated catch block
//TODO error handling
}
return;
}


try {
ShadowType shadow = (ShadowType) object.asObjectable();
ResourceShadowDiscriminator discr = new ResourceShadowDiscriminator(resolveOid(shadow.getResourceRef()),
shadow.getKind(), shadow.getIntent(), shadow.getTag(), false);
context.setDiscriminator(discr);
PrismObjectDefinition<ShadowType> shadowDefinition = modelInteractionService.getEditShadowDefinition(discr, phase, task, result);
object.applyDefinition((PrismContainerDefinition<O>) shadowDefinition);

PrismObject<ResourceType> resource = resolveResource(shadow.getResourceRef(), task, result);
context.setResource(resource.asObjectable());
RefinedObjectClassDefinition objectClassDefinitionForEditing =
modelInteractionService.getEditObjectClassDefinition(shadow.asPrismObject(), resource, phase, task, result);
if (objectClassDefinitionForEditing != null) {
object.findOrCreateContainer(ShadowType.F_ATTRIBUTES).applyDefinition(
(PrismContainerDefinition) objectClassDefinitionForEditing.toResourceAttributeContainerDefinition());
}

} catch (SchemaException | ConfigurationException | ObjectNotFoundException | ExpressionEvaluationException
| CommunicationException | SecurityViolationException e) {
// TODO Auto-generated catch block
// TODO error handling
}

}

}


private String resolveOid(ObjectReferenceType ref) throws SchemaException {
if (ref == null) {
throw new SchemaException("Cannot resolve oid from null reference");
}

return ref.getOid();
}

private PrismObject<ResourceType> resolveResource(ObjectReferenceType ref, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
if (ref == null) {
throw new SchemaException("Cannot resolve oid from null reference");
}

return modelService.getObject(ResourceType.class, ref.getOid(), null, task, result);

}



@Override
public boolean match(ItemDefinition<?> def) {
Expand Down
Expand Up @@ -83,16 +83,16 @@ public PrismReferenceValueWrapperImpl<R> createValueWrapper(PrismReferenceWrappe
return refValue;
}

@Override
protected boolean canCreateNewWrapper(ItemDefinition<?> def) {
//TODO compare full path instead of def.getName(). The issue is, that another complex type can have targetRef or target specified and then
// it won't be created either in that case.
if (AssignmentType.F_TARGET.equivalent(def.getName()) || AssignmentType.F_TARGET_REF.equivalent(def.getName())) {
return false;
}

return true;
}
// @Override
// protected boolean canCreateNewWrapper(ItemDefinition<?> def) {
// //TODO compare full path instead of def.getName(). The issue is, that another complex type can have targetRef or target specified and then
// // it won't be created either in that case.
// if (AssignmentType.F_TARGET.equivalent(def.getName()) || AssignmentType.F_TARGET_REF.equivalent(def.getName())) {
// return false;
// }
//
// return true;
// }

@Override
protected void setupWrapper(PrismReferenceWrapper<R> wrapper) {
Expand Down

0 comments on commit 919d440

Please sign in to comment.