Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/feature/gui-wrapper…
Browse files Browse the repository at this point in the history
…' into feature/gui-wrapper
  • Loading branch information
skublik committed May 29, 2019
2 parents d3d8938 + 7cbb7cf commit ea294aa
Show file tree
Hide file tree
Showing 44 changed files with 879 additions and 275 deletions.
Expand Up @@ -83,5 +83,8 @@ public class ComponentConstants {

public static final QName UI_FOCUS_TAB_MEMBERS = new QName(NS_COMPONENTS_PREFIX, "focusTabMembers");
public static final String UI_FOCUS_TAB_MEMBERS_URL = QNameUtil.qNameToUri(UI_FOCUS_TAB_MEMBERS);

public static final QName UI_ARCHETYPE_TAB_ARCHETYPE_POLICY = new QName(NS_COMPONENTS_PREFIX, "archetypeTabArchetypePolicy");
public static final String UI_ARCHTYPE_TAB_ARCHETYPE_POLICY_URL = QNameUtil.qNameToUri(UI_ARCHETYPE_TAB_ARCHETYPE_POLICY);

}
Expand Up @@ -203,6 +203,7 @@ public class GuiStyleConstants {
public static final String EVO_ROLE_TOP_HAT_ICON = "fe fe-role-top-hat";
public static final String EVO_ASSIGNMENT_THICKER_ICON = "fe assignment-thicker";
public static final String EVO_CASE_OBJECT_ICON = "fe fe-case-object";
public static final String EVO_ARCHETYPE_TYPE_ICON = "fe fe-archetype_smooth";

public static final String GREEN_COLOR = "color-green";
public static final String YELLOW_COLOR = "color-yellow";
Expand Down
Expand Up @@ -108,6 +108,8 @@
import com.evolveum.midpoint.web.page.admin.PageAdmin;
import com.evolveum.midpoint.web.page.admin.PageAdminFocus;
import com.evolveum.midpoint.web.page.admin.PageAdminObjectList;
import com.evolveum.midpoint.web.page.admin.archetype.PageArchetype;
import com.evolveum.midpoint.web.page.admin.archetype.PageArchetypes;
import com.evolveum.midpoint.web.page.admin.cases.*;
import com.evolveum.midpoint.web.page.admin.certification.PageCertCampaigns;
import com.evolveum.midpoint.web.page.admin.certification.PageCertDecisions;
Expand Down Expand Up @@ -1679,6 +1681,11 @@ protected List<SideBarMenuItem> createMenuItems() {
AuthorizationConstants.AUTZ_GUI_ALL_DEPRECATED_URL)) {
items.add(createServicesItems());
}

if (WebComponentUtil.isAuthorized(AuthorizationConstants.AUTZ_UI_ARCHETYPES_URL,
AuthorizationConstants.AUTZ_UI_ARCHETYPES_ALL_URL, AuthorizationConstants.AUTZ_GUI_ALL_URL)) {
items.add(createArchetypesItems());
}

if (WebComponentUtil.isAuthorized(AuthorizationConstants.AUTZ_UI_RESOURCES_URL,
AuthorizationConstants.AUTZ_UI_RESOURCES_ALL_URL, AuthorizationConstants.AUTZ_GUI_ALL_URL,
Expand Down Expand Up @@ -2248,6 +2255,33 @@ && getPageParameters().get(PARAMETER_OBJECT_COLLECTION_NAME).toString() != null)

return item;
}

private MainMenuItem createArchetypesItems() {
MainMenuItem item = new MainMenuItem(GuiStyleConstants.EVO_ARCHETYPE_TYPE_ICON,
createStringResource("PageAdmin.menu.top.archetypes"), null);

MenuItem menu = new MenuItem(createStringResource("PageAdmin.menu.top.archetypes.list"),
GuiStyleConstants.EVO_ARCHETYPE_TYPE_ICON, PageArchetypes.class){
private static final long serialVersionUID = 1L;

@Override
public boolean isMenuActive(WebPage page) {
if (getPageParameters() != null && getPageParameters().get(PARAMETER_OBJECT_COLLECTION_NAME) != null
&& getPageParameters().get(PARAMETER_OBJECT_COLLECTION_NAME).toString() != null){
return false;
} else {
return super.isMenuActive(page);
}
}
};
item.getItems().add(menu);
addCollectionsMenuItems(item.getItems(), ArchetypeType.COMPLEX_TYPE, PageArchetypes.class);

createFocusPageNewEditMenu(item.getItems(), "PageAdmin.menu.top.archetypes.new", "PageAdmin.menu.top.archetypes.edit",
PageArchetype.class, true);

return item;
}

private void addCollectionsMenuItems(List<MenuItem> menu, QName type, Class<? extends PageAdminObjectList> redirectToPage) {
List<CompiledObjectCollectionView> objectViews = getCompiledUserProfile().findAllApplicableObjectCollectionViews(type);
Expand Down
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 ea294aa

Please sign in to comment.