diff --git a/build-system/pom.xml b/build-system/pom.xml index 52fcd7aa4c3..c908222b81d 100644 --- a/build-system/pom.xml +++ b/build-system/pom.xml @@ -84,7 +84,8 @@ 6.1.1 10.11.1.1 1.8.0 - 2.3.3 + 2.8.3 + 1.15 2.19.1 @@ -902,6 +903,11 @@ jackson-annotations ${jackson.version} + + org.yaml + snakeyaml + ${snakeyaml.version} + com.fasterxml.jackson.core jackson-databind @@ -931,6 +937,15 @@ org.apache.maven maven-plugin-api 2.0 + org.apache.maven diff --git a/dist/midpoint-api/pom.xml b/dist/midpoint-api/pom.xml index cb7541e5059..450bc73fdb1 100644 --- a/dist/midpoint-api/pom.xml +++ b/dist/midpoint-api/pom.xml @@ -66,6 +66,12 @@ 3.5-SNAPSHOT compile + + + + + + com.evolveum.midpoint.infra util diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java index 29fbb2d7587..9ee7a4cfa6b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/result/OpResult.java @@ -17,7 +17,6 @@ package com.evolveum.midpoint.gui.api.component.result; import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.Visitable; import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.schema.result.OperationResult; @@ -142,7 +141,7 @@ public static OpResult getOpResult(PageBase page, OperationResult result){ try { OperationResultType resultType = result.createOperationResultType(); ObjectFactory of = new ObjectFactory(); - opResult.xml = page.getPrismContext().serializeAtomicValue(of.createOperationResult(resultType), PrismContext.LANG_XML); + opResult.xml = page.getPrismContext().xmlSerializer().serialize(of.createOperationResult(resultType)); } catch (SchemaException|RuntimeException ex) { String m = "Can't create xml: " + ex; // error(m); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java index 8a96cf361a2..5188387349c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java @@ -33,6 +33,7 @@ import com.evolveum.midpoint.web.page.admin.configuration.*; import com.evolveum.midpoint.web.page.admin.reports.*; import com.evolveum.midpoint.web.page.self.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.wicket.AttributeModifier; @@ -159,10 +160,6 @@ import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.web.util.validation.MidpointFormValidatorRegistry; import com.evolveum.midpoint.wf.api.WorkflowManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AdminGuiConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RichHyperlinkType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; /** * @author lazyman @@ -870,8 +867,20 @@ public RestartResponseException getRestartResponseException(Class void validateObject(String xmlObject, final Holder

objectHolder, - boolean validateSchema, OperationResult result) { + protected void validateObject(String lexicalRepresentation, final Holder> objectHolder, + String language, boolean validateSchema, OperationResult result) { + + if (language == null || PrismContext.LANG_JSON.equals(language) || PrismContext.LANG_YAML.equals(language)) { + PrismObject object; + try { + object = getPrismContext().parserFor(lexicalRepresentation).language(language).parse(); + objectHolder.setValue(object); + } catch (RuntimeException | SchemaException e) { + result.recordFatalError("Couldn't parse object: " + e.getMessage(), e); + } + return; + } + EventHandler handler = new EventHandler() { @Override @@ -883,7 +892,7 @@ public EventResult preMarshall(Element objectElement, Node postValidationTree, @Override public EventResult postMarshall(PrismObject object, Element objectElement, OperationResult objectResult) { - objectHolder.setValue((P) object); + objectHolder.setValue((PrismObject) object); return EventResult.cont(); } @@ -894,7 +903,7 @@ public void handleGlobalError(OperationResult currentResult) { Validator validator = new Validator(getPrismContext(), handler); validator.setVerbose(true); validator.setValidateSchema(validateSchema); - validator.validateObject(xmlObject, result); + validator.validateObject(lexicalRepresentation, result); result.computeStatus(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/AceEditor.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/AceEditor.java index 97ded86034a..11d504bcb4f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/AceEditor.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/AceEditor.java @@ -16,16 +16,32 @@ package com.evolveum.midpoint.web.component; +import com.evolveum.midpoint.prism.PrismContext; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.OnDomReadyHeaderItem; import org.apache.wicket.markup.html.form.TextArea; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; public class AceEditor extends TextArea { public static final String MODE_XML = "ace/mode/xml"; + public static final String MODE_JSON = "ace/mode/json"; + public static final String MODE_YAML = "ace/mode/yaml"; + + public static final Map MODES = new HashMap<>(); + + static { + MODES.put(null, MODE_XML); + MODES.put(PrismContext.LANG_XML, MODE_XML); + MODES.put(PrismContext.LANG_JSON, MODE_JSON); + MODES.put(PrismContext.LANG_YAML, MODE_YAML); + } private IModel readonly = new Model(false); @@ -88,7 +104,11 @@ public void setMode(String mode) { this.mode = mode; } - public void setReadonly(boolean readonly) { + public void setModeForDataLanguage(@Nullable String dataLanguage) { + setMode(MODES.get(dataLanguage)); + } + + public void setReadonly(boolean readonly) { this.readonly.setObject(readonly); } @@ -102,4 +122,5 @@ public void refreshReadonly(AjaxRequestTarget target) { target.appendJavaScript(sb.toString()); } + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java index 966bdf7fae3..3d55fb0f2c5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java @@ -22,6 +22,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.apache.commons.lang.Validate; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; @@ -217,7 +218,7 @@ private List prepareAssignmentAttributes(AssignmentType assignme try { PrismContext prismContext = pageBase.getPrismContext(); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.PRESENTATION, prismContext); RefinedObjectClassDefinition objectClassDefinition = refinedSchema .getRefinedDefinition(ShadowKindType.ACCOUNT, construction.getIntent()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java index 8afafa44bb3..93c807c913c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.gui.api.GuiStyleConstants; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.component.objecttypeselect.ObjectTypeSelectPanel; @@ -32,6 +33,7 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; @@ -536,13 +538,9 @@ private WebMarkupContainer createTenantContainer() { @Override protected ObjectQuery getChooseQuery() { - ObjectQuery query = new ObjectQuery(); - - ObjectFilter filter = EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, - getPageBase().getPrismContext(), null, true); - query.setFilter(filter); - - return query; + return QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()) + .item(OrgType.F_TENANT).eq(true) + .build(); } @Override @@ -581,16 +579,10 @@ private WebMarkupContainer createOrgContainer() { @Override protected ObjectQuery getChooseQuery() { - ObjectQuery query = new ObjectQuery(); - - ObjectFilter filter = OrFilter.createOr( - EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, - getPageBase().getPrismContext(), null, false), - EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, - getPageBase().getPrismContext(), null, null)); - query.setFilter(filter); - - return query; + return QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()) + .item(OrgType.F_TENANT).eq(false) + .or().item(OrgType.F_TENANT).isNull() + .build(); } @Override @@ -740,7 +732,7 @@ private List loadAttributes() { } PrismContext prismContext = getPageBase().getPrismContext(); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.PRESENTATION, prismContext); RefinedObjectClassDefinition objectClassDefinition = refinedSchema .getRefinedDefinition(ShadowKindType.ACCOUNT, construction.getIntent()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/MultipleAssignmentSelectorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/MultipleAssignmentSelectorPanel.java index aae0570f210..b996df81cae 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/MultipleAssignmentSelectorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/MultipleAssignmentSelectorPanel.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.util.logging.LoggingUtils; @@ -242,10 +243,10 @@ private IModel getFilterModel(final boolean isRequestableFilter){ return new IModel() { @Override public ObjectFilter getObject() { - ItemPath path = new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - ObjectFilter archivedRolesFilter = EqualFilter.createEqual(path, RoleType.class, - getPageBase().getPrismContext(), null, ActivationStatusType.ARCHIVED); - ObjectFilter filter = null; + ObjectFilter archivedRolesFilter = QueryBuilder.queryFor(RoleType.class, getPageBase().getPrismContext()) + .item(RoleType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.ARCHIVED) + .buildFilter(); + ObjectFilter filter; if (isRequestableFilter) { ObjectFilter assignableRolesFilter = getAssignableRolesFilter(); if (assignableRolesFilter instanceof NotFilter) { @@ -336,8 +337,9 @@ protected void editValuePerformed(AjaxRequestTarget target, IModel rowM supportedTypes.add(getPageBase().getPrismContext().getSchemaRegistry() .findObjectDefinitionByCompileTimeClass(OrgType.class).getTypeName()); - ObjectFilter filter = EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, - getPageBase().getPrismContext(), null, true); + ObjectFilter filter = QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()) + .item(OrgType.F_TENANT).eq(true) + .buildFilter(); ObjectBrowserPanel tenantPanel = new ObjectBrowserPanel(getPageBase().getMainPopupBodyId(), OrgType.class, supportedTypes, false, getPageBase(), filter) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/dialog/DeleteAllPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/dialog/DeleteAllPanel.java index bf22f562128..d45c091c722 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/dialog/DeleteAllPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/dialog/DeleteAllPanel.java @@ -7,6 +7,7 @@ import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; @@ -283,8 +284,10 @@ private void countShadows(boolean isAccountShadow){ options.add(SelectorOptions.create(ItemPath.EMPTY_PATH, opt)); try { - ObjectFilter filter = EqualFilter.createEqual(ShadowType.F_KIND, ShadowType.class, getPagebase().getPrismContext(), null, ShadowKindType.ACCOUNT); - if(isAccountShadow){ + ObjectFilter filter = QueryBuilder.queryFor(ShadowType.class, getPagebase().getPrismContext()) + .item(ShadowType.F_KIND).eq(ShadowKindType.ACCOUNT) + .buildFilter(); + if (isAccountShadow) { ObjectQuery query = ObjectQuery.createObjectQuery(filter); dto.setAccountShadowCount(getPagebase().getModelService().countObjects(ShadowType.class, query, options, task, result)); dto.setObjectsToDelete(dto.getObjectsToDelete() + dto.getAccountShadowCount()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RefinedObjectTypeChoicePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RefinedObjectTypeChoicePanel.java index 5fabc4cfac4..4f50c613999 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RefinedObjectTypeChoicePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RefinedObjectTypeChoicePanel.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.apache.commons.lang.StringUtils; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.model.IModel; @@ -48,7 +49,7 @@ private static IModel> cr public List getObject() { RefinedResourceSchema refinedSchema; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceModel.getObject()); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceModel.getObject()); } catch (SchemaException e) { throw new IllegalArgumentException(e.getMessage(),e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/SearchFilterPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/SearchFilterPanel.java index 04d4abbb5a4..4ee67bf54e2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/SearchFilterPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/SearchFilterPanel.java @@ -71,7 +71,7 @@ private String loadFilterClause(PrismContext prismContext) { T filter = getModelObject(); if (filter.containsFilterClause()) { RootXNode clause = filter.getFilterClauseAsRootXNode(); - String xml = prismContext.serializeXNodeToString(clause, PrismContext.LANG_XML); + String xml = prismContext.xmlSerializer().serialize(clause); return WebXmlUtil.stripNamespaceDeclarations(xml); } else { return null; @@ -127,7 +127,7 @@ private void updateFilterClause(PrismContext context) throws SchemaException { final String clauseString = clauseStringModel.getObject(); if (StringUtils.isNotEmpty(clauseString)) { LOGGER.trace("Filter Clause to serialize: {}", clauseString); - RootXNode filterClauseNode = (RootXNode) context.parseToXNode(clauseString, PrismContext.LANG_XML); + RootXNode filterClauseNode = (RootXNode) context.parserFor(clauseString).xml().parseToXNode(); getModelObject().setFilterClauseXNode(filterClauseNode); } else { if (getModelObject() != null) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/dto/ExpressionTypeDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/dto/ExpressionTypeDto.java index 27b9d3a6c98..5aef16a72d7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/dto/ExpressionTypeDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/dto/ExpressionTypeDto.java @@ -63,12 +63,12 @@ public ExpressionTypeDto(@Nullable ExpressionType expression, @NotNull PrismCont private void loadExpression(PrismContext context) { try { if (expressionObject.getExpressionEvaluator().size() == 1) { - expression = context.serializeAtomicValue(expressionObject.getExpressionEvaluator().get(0), PrismContext.LANG_XML); + expression = context.xmlSerializer().serialize(expressionObject.getExpressionEvaluator().get(0)); } else { StringBuilder sb = new StringBuilder(); for (JAXBElement element: expressionObject.getExpressionEvaluator()) { - String subElement = context.serializeAtomicValue(element, PrismContext.LANG_XML); + String subElement = context.xmlSerializer().serialize(element); sb.append(subElement).append("\n"); } expression = sb.toString(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java index 27c764097a2..db6877da57d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java @@ -23,6 +23,8 @@ import com.evolveum.midpoint.gui.api.util.FocusTabVisibleBehavior; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; @@ -92,25 +94,19 @@ protected void onInitialize() { } private ObjectQuery createTaskQuery(String oid, PageBase page) { - List filters = new ArrayList(); - if (oid == null) { oid = "non-existent"; // TODO !!!!!!!!!!!!!!!!!!!! } - try { - filters.add(RefFilter.createReferenceEqual(TaskType.F_OBJECT_REF, TaskType.class, - page.getPrismContext(), oid)); - filters.add(NotFilter.createNot(EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, - TaskType.class, page.getPrismContext(), null, TaskExecutionStatusType.CLOSED))); - filters.add(EqualFilter.createEqual(TaskType.F_PARENT, TaskType.class, page.getPrismContext(), null)); - } catch (SchemaException e) { - throw new SystemException("Unexpected SchemaException when creating task filter", e); - } - - return new ObjectQuery().createObjectQuery(AndFilter.createAnd(filters)); + return QueryBuilder.queryFor(TaskType.class, page.getPrismContext()) + .item(TaskType.F_OBJECT_REF).ref(oid) + .and() + .block() + .not().item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.CLOSED) + .endBlock() + .and().item(TaskType.F_PARENT).isNull() + .build(); } - @Override protected List createTabs(final PageAdminObjectDetails parentPage) { List tabs = new ArrayList<>(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java index 88bf2e5fc3b..494b771559e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java @@ -21,6 +21,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.web.component.prism.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; @@ -216,7 +217,7 @@ private void addSelectedAccountPerformed(AjaxRequestTarget target, List createProperties(ContainerWrapper cWrapper, OperationR // hack... we want to create a definition for Name // PrismPropertyDefinition def = ((PrismContainerValue) // pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition(); - PrismPropertyDefinition def = new PrismPropertyDefinition(ObjectType.F_NAME, + PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl(ObjectType.F_NAME, DOMUtil.XSD_STRING, pcv.getPrismContext()); if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { @@ -260,13 +261,13 @@ private List createProperties(ContainerWrapper cWrapper, OperationR RefinedResourceSchema refinedSchema; CompositeRefinedObjectClassDefinition rOcDef; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); rOcDef = refinedSchema.determineCompositeObjectClassDefinition(objectWrapper.getObject()); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } // Make sure even empty associations have their wrappers so they can be displayed and edited - for (RefinedAssociationDefinition assocDef : rOcDef.getAssociations()) { + for (RefinedAssociationDefinition assocDef : rOcDef.getAssociationDefinitions()) { QName name = assocDef.getName(); if (!assocMap.containsKey(name)) { PrismContainer fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext); @@ -278,7 +279,7 @@ private List createProperties(ContainerWrapper cWrapper, OperationR } for (Map.Entry> assocEntry : assocMap.entrySet()) { - RefinedAssociationDefinition assocRDef = rOcDef.findAssociation(assocEntry.getKey()); + RefinedAssociationDefinition assocRDef = rOcDef.findAssociationDefinition(assocEntry.getKey()); AssociationWrapper assocWrapper = new AssociationWrapper(cWrapper, assocEntry.getValue(), cWrapper.isReadonly(), ValueStatus.NOT_CHANGED, assocRDef); properties.add(assocWrapper); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java index 9cb03f32f0f..2bfd7aebb6e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java @@ -207,7 +207,7 @@ private List> c ContainerStatus status = container == null ? ContainerStatus.ADDING : ContainerStatus.MODIFYING; List> list = new ArrayList<>(); if (container == null) { - PrismContainerDefinition definition = getDefinition(object, objectDefinitionForEditing).findContainerDefinition(name); + PrismContainerDefinition definition = getDefinition(object, objectDefinitionForEditing).findContainerDefinition(name); container = definition.instantiate(); } @@ -254,7 +254,7 @@ private void addContainerWrapper LOGGER.trace("ObjectWrapper.createContainerWrapper processing definition: {}", def); - PrismContainerDefinition containerDef = (PrismContainerDefinition) def; + PrismContainerDefinition containerDef = (PrismContainerDefinition) def; //todo this oWrapper.isShowAssignments() value is not set when initialization occurs (only default is there) [lazyman] if (!oWrapper.isShowAssignments() && AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName())) { continue; @@ -330,8 +330,8 @@ private void addResourceContainerWrapper( // brutal hack - the definition has (errorneously) set maxOccurs = // unbounded. But there can be only one configuration container. // See MID-2317 and related issues - PrismContainerDefinition definitionFixed = definition.clone(); - definitionFixed.setMaxOccurs(1); + PrismContainerDefinition definitionFixed = definition.clone(); + ((PrismContainerDefinitionImpl) definitionFixed).setMaxOccurs(1); if (container == null) { container = definitionFixed.instantiate(); @@ -351,7 +351,7 @@ private void addShadowContainers( PrismContainer attributesContainer = object.findContainer(ShadowType.F_ATTRIBUTES); ContainerStatus status = attributesContainer != null ? cStatus : ContainerStatus.ADDING; if (attributesContainer == null) { - PrismContainerDefinition definition = object.getDefinition().findContainerDefinition( + PrismContainerDefinition definition = object.getDefinition().findContainerDefinition( ShadowType.F_ATTRIBUTES); attributesContainer = definition.instantiate(); } @@ -402,7 +402,7 @@ private void addReportContainers( if (container == null) { PrismSchema schema = ReportTypeUtil.parseReportConfigurationSchema( (PrismObject) object, object.getPrismContext()); - PrismContainerDefinition definition = ReportTypeUtil.findReportConfigurationDefinition(schema); + PrismContainerDefinition definition = ReportTypeUtil.findReportConfigurationDefinition(schema); if (definition == null) { return; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index ed3d5beead0..750f54411d3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -16,10 +16,7 @@ package com.evolveum.midpoint.web.component.prism; -import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel; import com.evolveum.midpoint.gui.api.component.password.PasswordPanel; import com.evolveum.midpoint.gui.api.page.PageBase; @@ -29,6 +26,7 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -42,7 +40,6 @@ import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.LockoutStatusPanel; @@ -570,7 +567,7 @@ public Object getObject() { } PrismContext prismContext = ((PageBase) getPage()).getPrismContext(); try { - return prismContext.serializeAnyData(ppv.getValue(), name, PrismContext.LANG_XML); + return prismContext.xmlSerializer().serializeAnyData(ppv.getValue(), name); } catch (SchemaException e) { throw new SystemException("Couldn't serialize property value of type: " + valueType + ": " + e.getMessage(), e); } @@ -705,7 +702,7 @@ public void checkInputValue(AutoCompleteTextField input, AjaxRequestTarget targe RefinedResourceSchema refinedSchema; CompositeRefinedObjectClassDefinition rOcDef; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); rOcDef = refinedSchema.determineCompositeObjectClassDefinition(shadowType.asPrismObject()); } catch (SchemaException e) { throw new SystemException(e.getMessage(),e); @@ -714,7 +711,7 @@ public void checkInputValue(AutoCompleteTextField input, AjaxRequestTarget targe RefinedObjectClassDefinition assocTargetDef = assocDef.getAssociationTarget(); ObjectQuery query = getAssociationsSearchQuery(prismContext, resource, - assocTargetDef.getTypeName(), assocTargetDef.getKind(), assocTargetDef.getIntent()); + assocTargetDef.getTypeName(), assocTargetDef.getKind()); List values = item.getValues(); return new AssociationValueChoicePanel(id, valueWrapperModel, values, false, ShadowType.class, @@ -873,21 +870,12 @@ private void removeValue(AjaxRequestTarget target) { target.add(parent.getParent()); } - private ObjectQuery getAssociationsSearchQuery(PrismContext prismContext, PrismObject resource, QName objectClass, ShadowKindType kind, - String intent) { - try { - ObjectFilter andFilter = AndFilter.createAnd( - EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, objectClass), - EqualFilter.createEqual(ShadowType.F_KIND, ShadowType.class, prismContext, kind), -// EqualFilter.createEqual(ShadowType.F_INTENT, ShadowType.class, prismContext, intent), - RefFilter.createReferenceEqual(new ItemPath(ShadowType.F_RESOURCE_REF), ShadowType.class, prismContext, resource.getOid())); - ObjectQuery query = ObjectQuery.createObjectQuery(andFilter); - return query; - } catch (SchemaException ex) { - LoggingUtils.logUnexpectedException(LOGGER, "Unable to create associations search query", ex); - return null; - } - + private ObjectQuery getAssociationsSearchQuery(PrismContext prismContext, PrismObject resource, QName objectClass, ShadowKindType kind) { + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_OBJECT_CLASS).eq(objectClass) + .and().item(ShadowType.F_KIND).eq(kind) + .and().item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) + .build(); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/Search.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/Search.java index eafe34d8ec1..a009e2d9df4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/Search.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/Search.java @@ -17,12 +17,11 @@ package com.evolveum.midpoint.web.component.search; import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; -import com.evolveum.midpoint.prism.match.StringIgnoreCaseMatchingRule; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugDumpable; @@ -185,8 +184,9 @@ private ObjectFilter createFilterForSearchValue(SearchItem item, DisplayableValu ItemPath path = item.getPath(); if (definition instanceof PrismReferenceDefinition) { - PrismReferenceValue value = (PrismReferenceValue) searchValue.getValue(); - return RefFilter.createReferenceEqual(path, (PrismReferenceDefinition) definition, value); + return QueryBuilder.queryFor(ObjectType.class, ctx) + .item(path, definition).ref((PrismReferenceValue) searchValue.getValue()) + .buildFilter(); } PrismPropertyDefinition propDef = (PrismPropertyDefinition) definition; @@ -196,7 +196,8 @@ private ObjectFilter createFilterForSearchValue(SearchItem item, DisplayableValu //or if it's boolean value DisplayableValue displayableValue = (DisplayableValue) searchValue.getValue(); Object value = displayableValue.getValue(); - return EqualFilter.createEqual(path, propDef, value); + return QueryBuilder.queryFor(ObjectType.class, ctx) + .item(path, propDef).eq(value).buildFilter(); } else if (DOMUtil.XSD_INT.equals(propDef.getTypeName()) || DOMUtil.XSD_INTEGER.equals(propDef.getTypeName()) || DOMUtil.XSD_LONG.equals(propDef.getTypeName()) @@ -208,16 +209,19 @@ private ObjectFilter createFilterForSearchValue(SearchItem item, DisplayableValu return null; } Object value = Long.parseLong((String) searchValue.getValue()); - return EqualFilter.createEqual(path, propDef, value); + return QueryBuilder.queryFor(ObjectType.class, ctx) + .item(path, propDef).eq(value).buildFilter(); } else if (DOMUtil.XSD_STRING.equals(propDef.getTypeName())) { String text = (String) searchValue.getValue(); - return SubstringFilter.createSubstring(path, propDef, StringIgnoreCaseMatchingRule.NAME, text); + return QueryBuilder.queryFor(ObjectType.class, ctx) + .item(path, propDef).contains(text).matchingCaseIgnore().buildFilter(); } else if (SchemaConstants.T_POLY_STRING_TYPE.equals(propDef.getTypeName())) { //we're looking for string value, therefore substring filter should be used String text = (String) searchValue.getValue(); PolyStringNormalizer normalizer = ctx.getDefaultPolyStringNormalizer(); String value = normalizer.normalize(text); - return SubstringFilter.createSubstring(path, propDef, PolyStringNormMatchingRule.NAME, value); + return QueryBuilder.queryFor(ObjectType.class, ctx) + .item(path, propDef).contains(text).matchingNorm().buildFilter(); } //we don't know how to create filter from search item, should not happen, ha ha ha :) @@ -268,7 +272,7 @@ private ObjectFilter createAdvancedObjectFilter(PrismContext ctx) throws SchemaE return null; } - SearchFilterType search = ctx.parseAtomicValue(advancedQuery, SearchFilterType.COMPLEX_TYPE); + SearchFilterType search = ctx.parserFor(advancedQuery).type(SearchFilterType.COMPLEX_TYPE).parseRealValue(); return QueryConvertor.parseFilter(search, type, ctx); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/WizardStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/WizardStep.java index 2e7755b9025..100dfbf0998 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/WizardStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/WizardStep.java @@ -21,6 +21,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.web.page.admin.resources.PageResourceWizard; import org.apache.commons.lang.StringUtils; @@ -117,7 +118,7 @@ protected String createComponentPath(String... components) { protected List loadResourceObjectClassList(IModel> model, Trace LOGGER, String message){ List list = new ArrayList<>(); try { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(model.getObject(), getPageBase().getPrismContext()); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(model.getObject(), getPageBase().getPrismContext()); if (schema != null) { for (Definition def: schema.getDefinitions()) { list.add(def.getTypeName()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/CapabilityStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/CapabilityStep.java index d8c8594b89b..b46d5dec941 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/CapabilityStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/CapabilityStep.java @@ -17,6 +17,7 @@ package com.evolveum.midpoint.web.component.wizard.resource; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.model.NonEmptyLoadableModel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; @@ -307,7 +308,7 @@ protected List load() { PrismObject resourcePrism = resourceModel.getObject(); try { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resourcePrism, getPageBase().getPrismContext()); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resourcePrism, getPageBase().getPrismContext()); if (schema != null) { ObjectClassComplexTypeDefinition def = schema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT); for (ResourceAttributeDefinition attribute : def.getAttributeDefinitions()) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java index 5a6369c4d2e..ec97b330fec 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java @@ -22,10 +22,7 @@ import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.model.api.ModelService; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.schema.PrismSchema; @@ -129,12 +126,12 @@ private List createConfigContainerWrappers() throws SchemaExce PrismContainerDefinition definition = ConnectorTypeUtil.findConfigurationContainerDefinition(connectorType, schema); // Fixing (errorneously) set maxOccurs = unbounded. See MID-2317 and related issues. PrismContainerDefinition definitionFixed = definition.clone(); - definitionFixed.setMaxOccurs(1); + ((PrismContainerDefinitionImpl) definitionFixed).setMaxOccurs(1); configuration = definitionFixed.instantiate(); } List containerDefinitions = getSortedConfigContainerDefinitions(configuration); - for (PrismContainerDefinition containerDef : containerDefinitions) { + for (PrismContainerDefinition containerDef : containerDefinitions) { ItemPath containerPath = new ItemPath(ResourceType.F_CONNECTOR_CONFIGURATION, containerDef.getName()); PrismContainer container = configuration.findContainer(containerDef.getName()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/SchemaStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/SchemaStep.java index 788da337266..d4cd5ce49e7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/SchemaStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/SchemaStep.java @@ -21,7 +21,6 @@ import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.util.ResourceUtils; import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.result.OperationResult; @@ -114,7 +113,7 @@ public String getObject() { PageBase page = (PageBase) SchemaStep.this.getPage(); try { - return page.getPrismContext().serializeContainerValueToString(xmlSchema.getValue(), SchemaConstantsGenerated.C_SCHEMA, PrismContext.LANG_XML); + return page.getPrismContext().xmlSerializer().serialize(xmlSchema.getValue(), SchemaConstantsGenerated.C_SCHEMA); } catch (SchemaException|RuntimeException ex) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't serialize resource schema", ex); return WebComponentUtil.exceptionToString("Couldn't serialize resource schema", ex); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/SchemaListPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/SchemaListPanel.java index 62cdbb06cb4..1ec3ff2f1ff 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/SchemaListPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/SchemaListPanel.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.model.NonEmptyLoadableModel; import com.evolveum.midpoint.prism.PrismObject; @@ -358,7 +359,7 @@ private RefinedResourceSchema loadResourceSchema() { return null; } - return RefinedResourceSchema.getRefinedSchema(resource, getPageBase().getPrismContext()); + return RefinedResourceSchemaImpl.getRefinedSchema(resource, getPageBase().getPrismContext()); } catch (SchemaException|RuntimeException ex) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse resource schema.", ex); getSession().error(getString("SchemaListPanel.message.couldntParseSchema") + " " + ex.getMessage()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAssociationEditor.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAssociationEditor.java index d614e2ae8a1..ac9167b1d89 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAssociationEditor.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAssociationEditor.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; import com.evolveum.midpoint.schema.processor.ResourceSchema; +import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.LoggingUtils; @@ -462,7 +463,7 @@ private ResourceSchema loadResourceSchema() { } try { - return ResourceSchema.parse(xsdSchema, resource.toString(), getPageBase().getPrismContext()); + return ResourceSchemaImpl.parse(xsdSchema, resource.toString(), getPageBase().getPrismContext()); } catch (SchemaException|RuntimeException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse resource schema.", e); getSession().error(getString("ResourceAssociationEditor.message.cantParseSchema") + " " + e.getMessage()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAttributeEditor.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAttributeEditor.java index 8582ee92542..76c0e67d4fe 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAttributeEditor.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/component/schemahandling/ResourceAttributeEditor.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; import com.evolveum.midpoint.schema.processor.ResourceSchema; +import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.LoggingUtils; @@ -491,7 +492,7 @@ private ResourceSchema loadResourceSchema() { } try { - return ResourceSchema.parse(xsdSchema, resource.toString(), getPageBase().getPrismContext()); + return ResourceSchemaImpl.parse(xsdSchema, resource.toString(), getPageBase().getPrismContext()); } catch (SchemaException|RuntimeException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse resource schema.", e); getSession().error(getString("ResourceAttributeEditor.message.cantParseSchema") + " " + e.getMessage()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/IterationSpecificationTypeDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/IterationSpecificationTypeDto.java index b83ff1089a4..a548ab0c1b3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/IterationSpecificationTypeDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/dto/IterationSpecificationTypeDto.java @@ -88,11 +88,11 @@ private void loadExpression(String expression, ExpressionUtil.ExpressionEvaluato try{ if(expressionType.getExpressionEvaluator().size() == 1){ - expression = prismContext.serializeAtomicValue(expressionType.getExpressionEvaluator().get(0), PrismContext.LANG_XML); + expression = prismContext.xmlSerializer().serialize(expressionType.getExpressionEvaluator().get(0)); } else { StringBuilder sb = new StringBuilder(); for(JAXBElement element: expressionType.getExpressionEvaluator()){ - String subElement = prismContext.serializeAtomicValue(element, PrismContext.LANG_XML); + String subElement = prismContext.xmlSerializer().serialize(element); sb.append(subElement).append("\n"); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java index 19821258eaf..c1691c1c06d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; @@ -135,21 +136,13 @@ public CertCampaignListItemDto createDataObjectWrapper( private ObjectQuery createQuery() { // TODO filtering based on e.g. campaign state/stage (not started, // active, finished) - ObjectQuery query = new ObjectQuery(); - if (definitionOid != null) { - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(definitionOid, - ObjectTypes.ACCESS_CERTIFICATION_DEFINITION); - ObjectFilter filter; - try { - filter = RefFilter.createReferenceEqual( - new ItemPath(AccessCertificationCampaignType.F_DEFINITION_REF), - AccessCertificationCampaignType.class, getPrismContext(), ref.asReferenceValue()); - } catch (SchemaException e) { - throw new SystemException("Unexpected schema exception: " + e.getMessage(), e); - } - query = ObjectQuery.createObjectQuery(filter); + if (definitionOid == null) { + return new ObjectQuery(); + } else { + return QueryBuilder.queryFor(AccessCertificationCampaignType.class, getPrismContext()) + .item(AccessCertificationCampaignType.F_DEFINITION_REF).ref(definitionOid) + .build(); } - return query; } // endregion diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertDefinitionDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertDefinitionDto.java index fd843fd93c8..715dcecefa9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertDefinitionDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertDefinitionDto.java @@ -21,7 +21,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil; @@ -312,8 +312,6 @@ public void updateScopeDefinition(PrismContext prismContext) { scopeTypeObj.setIncludeOrgs(definitionScopeDto.isIncludeOrgs()); scopeTypeObj.setIncludeServices(definitionScopeDto.isIncludeServices()); scopeTypeObj.setEnabledItemsOnly(definitionScopeDto.isEnabledItemsOnly()); - // needed because of prism implementation limitation (because the scopeDefinition is declared as AccessCertificationScopeType) - scopeTypeObj.asPrismContainerValue().setConcreteType(AccessCertificationAssignmentReviewScopeType.COMPLEX_TYPE); } definition.setScopeDefinition(scopeTypeObj); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/DefinitionScopeDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/DefinitionScopeDto.java index 93b29b3c285..b25c0da46fd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/DefinitionScopeDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/DefinitionScopeDto.java @@ -44,7 +44,7 @@ public void loadSearchFilter(SearchFilterType searchFilterType, PrismContext pri try { RootXNode clause = searchFilterType.getFilterClauseAsRootXNode(); - searchFilterText = prismContext.serializeXNodeToString(clause, PrismContext.LANG_XML); + searchFilterText = prismContext.xmlSerializer().serialize(clause); } catch (SchemaException e) { throw new SystemException("Cannot serialize search filter " + searchFilterType + ": " + e.getMessage(), e); } @@ -58,7 +58,7 @@ public SearchFilterType getParsedSearchFilter(PrismContext context) { SearchFilterType rv = new SearchFilterType(); RootXNode filterClauseNode; try { - filterClauseNode = (RootXNode) context.parseToXNode(searchFilterText, PrismContext.LANG_XML); + filterClauseNode = (RootXNode) context.parserFor(searchFilterText).xml().parseToXNode(); } catch (SchemaException e) { throw new SystemException("Cannot parse search filter " + searchFilterText + ": " + e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java index f84a16e3d55..047eb8a9a2d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java @@ -31,6 +31,10 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.util.exception.CommonException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.wicket.AttributeModifier; @@ -63,21 +67,16 @@ import org.apache.wicket.validation.IValidator; import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.Definition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.RefFilter; -import com.evolveum.midpoint.prism.query.SubstringFilter; import com.evolveum.midpoint.schema.AbstractSummarizingResultHandler; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResultHandler; @@ -535,14 +534,12 @@ protected Integer load() { Task task = createSimpleTask(OPERATION_GET_TOTALS); OperationResult result = new OperationResult(OPERATION_GET_TOTALS); try { - EqualFilter situationFilter = EqualFilter.createEqual(ShadowType.F_SYNCHRONIZATION_SITUATION, ShadowType.class, - getPrismContext(), null, situation); - - AndFilter andFilter = AndFilter.createAnd(filter, situationFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(andFilter); - + ObjectFilter situationFilter = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_SYNCHRONIZATION_SITUATION).eq(situation) + .buildFilter(); + ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(filter, situationFilter)); return getModelService().countObjects(ShadowType.class, query, options, task, result); - } catch (Exception ex) { + } catch (CommonException|RuntimeException ex) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't count shadows", ex); } @@ -700,7 +697,7 @@ private void showShadowResult(AjaxRequestTarget target, IModel r try { - xml = getPrismContext().serializeAtomicValue(result, ShadowType.F_RESULT, PrismContext.LANG_XML); + xml = getPrismContext().xmlSerializer().serializeRealValue(result, ShadowType.F_RESULT); aceEditor.updateModel(new Model(xml)); } catch (SchemaException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse result", e); @@ -721,23 +718,19 @@ private ObjectFilter createResourceQueryFilter() { if (dto == null) { return null; } - OperationResult result = new OperationResult(OPERATION_LOAD_ACCOUNTS); String oid = dto.getOid(); - try { - return RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - getPrismContext(), oid); - } catch (Exception ex) { - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't create query", ex); - error("Couldn't create query, reason: " + ex.getMessage()); - } finally { - result.recomputeStatus(); - } + return QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_RESOURCE_REF).ref(oid) + .buildFilter(); + } - if (!WebComponentUtil.isSuccessOrHandledError(result)) { - showResult(result); + private ObjectQuery appendResourceQueryFilter(S_AtomicFilterEntry q) { + ResourceItemDto dto = resourceModel.getObject(); + if (dto == null) { + return q.all().build(); // TODO ok? + } else { + return q.item(ShadowType.F_RESOURCE_REF).ref(dto.getOid()).build(); } - - return null; } private List loadResources() { @@ -809,7 +802,7 @@ private void loadResourceObjectClass(){ resourcePrism = getModelService().getObject(ResourceType.class, oid, null, createSimpleTask(OPERATION_GET_INTENTS), result); - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resourcePrism, getPrismContext()); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resourcePrism, getPrismContext()); schema.getObjectClassDefinitions(); for(Definition def: schema.getDefinitions()){ @@ -997,69 +990,41 @@ private void searchPerformed(AjaxRequestTarget target){ target.add(getAccountsContainer()); } - private ObjectQuery createObjectQuery(){ + private ObjectQuery createObjectQuery() { AccountDetailsSearchDto dto = searchModel.getObject(); - ObjectQuery query = new ObjectQuery(); - List filters = new ArrayList<>(); String searchText = dto.getText(); ShadowKindType kind = dto.getKind(); String intent = dto.getIntent(); String objectClass = dto.getObjectClass(); FailedOperationTypeType failedOperatonType = dto.getFailedOperationType(); - if(StringUtils.isNotEmpty(searchText)){ + S_AtomicFilterEntry q = QueryBuilder.queryFor(ShadowType.class, getPrismContext()); + + if (StringUtils.isNotEmpty(searchText)) { PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); String normalized = normalizer.normalize(searchText); - - ObjectFilter substring = SubstringFilter.createSubstring(ShadowType.F_NAME, ShadowType.class, getPrismContext(), - PolyStringNormMatchingRule.NAME, normalized); - filters.add(substring); + q = q.item(ShadowType.F_NAME).contains(normalized).matchingNorm().and(); } - - if(kind != null){ - ObjectFilter kindFilter = EqualFilter.createEqual(ShadowType.F_KIND, ShadowType.class, getPrismContext(), - null, kind); - filters.add(kindFilter); + if (kind != null) { + q = q.item(ShadowType.F_KIND).eq(kind).and(); } - - if(StringUtils.isNotEmpty(intent)){ - ObjectFilter intentFilter = EqualFilter.createEqual(ShadowType.F_INTENT, ShadowType.class, getPrismContext(), - null, intent); - filters.add(intentFilter); + if (StringUtils.isNotEmpty(intent)) { + q = q.item(ShadowType.F_INTENT).eq(kind).and(); } - if (failedOperatonType != null){ - ObjectFilter failedOperationFilter = EqualFilter.createEqual(ShadowType.F_FAILED_OPERATION_TYPE, ShadowType.class, getPrismContext(), - null, failedOperatonType); - filters.add(failedOperationFilter); + q = q.item(ShadowType.F_FAILED_OPERATION_TYPE).eq(failedOperatonType).and(); } - - if(StringUtils.isNotEmpty(objectClass)){ + if (StringUtils.isNotEmpty(objectClass)) { QName objClass = new QName(objectClass); - - for(QName q: dto.getObjectClassList()){ - if(objectClass.equals(q.getLocalPart())){ - objClass = q; + for (QName qn: dto.getObjectClassList()) { + if (objectClass.equals(qn.getLocalPart())){ + objClass = qn; } } - - ObjectFilter objectClassFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, getPrismContext(), - null, objClass); - filters.add(objectClassFilter); - } - - AndFilter searchFilter; - if(!filters.isEmpty()){ - searchFilter = AndFilter.createAnd(filters); - - ObjectFilter resourceFilter = createResourceQueryFilter(); - query.setFilter(resourceFilter != null ? AndFilter.createAnd(searchFilter, resourceFilter) : searchFilter); - } else { - query.setFilter(createResourceQueryFilter()); + q = q.item(ShadowType.F_OBJECT_CLASS).eq(objClass).and(); } - - return query; + return appendResourceQueryFilter(q); } private void clearSearchPerformed(AjaxRequestTarget target){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java index 9ebf7c427c9..f40f867b33d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java @@ -110,13 +110,13 @@ private void startPerformed(AjaxRequestTarget target) { ScriptingExpressionType expression = null; try { - Object parsed = getPrismContext().parseAnyValue(bulkActionDto.getScript(), PrismContext.LANG_XML); + Object parsed = getPrismContext().parserFor(bulkActionDto.getScript()).xml().parseRealValue(); if (parsed == null) { result.recordFatalError("No bulk action object was provided."); } - if (parsed instanceof JAXBElement) { - parsed = ((JAXBElement) parsed).getValue(); - } +// if (parsed instanceof JAXBElement) { +// parsed = ((JAXBElement) parsed).getValue(); +// } if (parsed instanceof ScriptingExpressionType) { expression = (ScriptingExpressionType) parsed; } else { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java index 4418b19dcff..d090ee98bb3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java @@ -23,6 +23,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.web.component.data.BaseSortableDataProvider; import com.evolveum.midpoint.web.component.dialog.*; import com.evolveum.midpoint.web.component.search.Search; import com.evolveum.midpoint.web.component.search.SearchFactory; @@ -533,9 +536,10 @@ private ObjectQuery createQuery(ObjectQuery searchQuery) { List filters = new ArrayList<>(); if (ObjectTypes.SHADOW.equals(dto.getType()) && dto.getResource() != null) { String oid = dto.getResource().getOid(); - RefFilter ref = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - getPrismContext(), oid); - filters.add(ref); + ObjectFilter objectFilter = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_RESOURCE_REF).ref(oid) + .buildFilter(); + filters.add(objectFilter); } if (searchQuery != null && searchQuery.getFilter() != null) { @@ -650,17 +654,18 @@ private ObjectQuery createDeleteAllUsersQuery() { private String deleteAllShadowsConfirmed(OperationResult result, boolean deleteAccountShadows) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { - ObjectFilter kind = EqualFilter.createEqual(ShadowType.F_KIND, ShadowType.class, getPrismContext(), - null, ShadowKindType.ACCOUNT); + ObjectFilter kindFilter = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_KIND).eq(ShadowKindType.ACCOUNT) + .buildFilter(); String taskName; ObjectQuery query; if (deleteAccountShadows) { taskName = "Delete all account shadows"; - query = ObjectQuery.createObjectQuery(kind); + query = ObjectQuery.createObjectQuery(kindFilter); } else { taskName = "Delete all non-account shadows"; - query = ObjectQuery.createObjectQuery(NotFilter.createNot(kind)); + query = ObjectQuery.createObjectQuery(NotFilter.createNot(kindFilter)); } return deleteObjectsAsync(ShadowType.COMPLEX_TYPE, query, true, taskName, result); @@ -825,11 +830,10 @@ private void exportAllShadowsOnResource(AjaxRequestTarget target) { return; } - RefFilter ref = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - getPrismContext(), dto.getResource().getOid()); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(ref); + ObjectQuery objectQuery = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_RESOURCE_REF).ref(dto.getResource().getOid()) + .build(); initDownload(target, dto.getType().getClassDefinition(), objectQuery); - } private Popupable getDeleteConfirmationPanel() { @@ -872,9 +876,9 @@ private void deleteAllShadowsOnResourceConfirmed(AjaxRequestTarget target) { OperationResult result = new OperationResult(OPERATION_DELETE_SHADOWS); String taskOid = null; try { - RefFilter ref = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - getPrismContext(), dto.getResource().getOid()); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(ref); + ObjectQuery objectQuery = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_RESOURCE_REF).ref(dto.getResource().getOid()) + .build(); QName type = ShadowType.COMPLEX_TYPE; @@ -913,19 +917,19 @@ private String deleteObjectsAsync(QName type, ObjectQuery objectQuery, boolean r QueryType query = QueryJaxbConvertor.createQueryType(objectQuery, getPrismContext()); - PrismPropertyDefinition queryDef = new PrismPropertyDefinition( + PrismPropertyDefinition queryDef = new PrismPropertyDefinitionImpl( SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY, QueryType.COMPLEX_TYPE, getPrismContext()); PrismProperty queryProp = queryDef.instantiate(); queryProp.setRealValue(query); task.setExtensionProperty(queryProp); - PrismPropertyDefinition typeDef = new PrismPropertyDefinition( + PrismPropertyDefinition typeDef = new PrismPropertyDefinitionImpl( SchemaConstants.MODEL_EXTENSION_OBJECT_TYPE, DOMUtil.XSD_QNAME, getPrismContext()); PrismProperty typeProp = typeDef.instantiate(); typeProp.setRealValue(type); task.setExtensionProperty(typeProp); - PrismPropertyDefinition rawDef = new PrismPropertyDefinition( + PrismPropertyDefinition rawDef = new PrismPropertyDefinitionImpl( SchemaConstants.MODEL_EXTENSION_OPTION_RAW, DOMUtil.XSD_BOOLEAN, getPrismContext()); PrismProperty rawProp = rawDef.instantiate(); rawProp.setRealValue(raw); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java index acb861a1567..01e0865d53c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java @@ -40,11 +40,7 @@ import com.evolveum.midpoint.web.component.AceEditor; import com.evolveum.midpoint.web.page.admin.dto.ObjectViewDto; import com.evolveum.midpoint.web.security.MidPointApplication; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.StringUtils; import org.apache.wicket.RestartResponseException; @@ -87,6 +83,7 @@ public class PageDebugView extends PageAdminConfiguration { private final IModel switchToPlainText = new Model<>(false); private TextArea plainTextarea; final Form mainForm = new Form("mainForm"); + private final String dataLanguage; public PageDebugView() { model = new LoadableModel(false) { @@ -96,9 +93,19 @@ protected ObjectViewDto load() { return loadObject(); } }; + dataLanguage = determineDataLanguage(); initLayout(); } + private String determineDataLanguage() { + AdminGuiConfigurationType config = loadAdminGuiConfiguration(); + if (config != null && config.getPreferredDataLanguage() != null) { + return config.getPreferredDataLanguage(); + } else { + return PrismContext.LANG_XML; + } + } + @Override protected IModel createPageTitleModel() { return new AbstractReadOnlyModel() { @@ -156,8 +163,8 @@ private ObjectViewDto loadObject() { PrismObject object = getModelService().getObject(type, objectOid.toString(), options, task, result); PrismContext context = application.getPrismContext(); - String xml = context.serializeObjectToString(object, PrismContext.LANG_XML); - dto = new ObjectViewDto(object.getOid(), WebComponentUtil.getName(object), object, xml); + String lex = context.serializerFor(dataLanguage).serialize(object); + dto = new ObjectViewDto(object.getOid(), WebComponentUtil.getName(object), object, lex); result.recomputeStatus(); } catch (Exception ex) { @@ -169,7 +176,7 @@ private ObjectViewDto loadObject() { throw new RestartResponseException(PageDebugList.class); } - showResult(result, false); + showResult(result, false); if (!WebComponentUtil.isSuccessOrHandledErrorOrWarning(result)) { showResult(result, false); @@ -182,8 +189,6 @@ private ObjectViewDto loadObject() { private void initLayout() { add(mainForm); -// final IModel editable = new Model(false); - mainForm.add(new AjaxCheckBox("encrypt", encrypt) { @Override @@ -216,7 +221,7 @@ protected void onUpdate(AjaxRequestTarget target) { @Override protected void onUpdate(AjaxRequestTarget target) { - if (switchToPlainText.getObject().booleanValue()){ + if (switchToPlainText.getObject()){ editor.setVisible(false); plainTextarea.setVisible(true); } else { @@ -234,6 +239,7 @@ protected void onUpdate(AjaxRequestTarget target) { mainForm.add(plainTextarea); editor = new AceEditor("aceEditor", new PropertyModel(model, ObjectViewDto.F_XML)); + editor.setModeForDataLanguage(dataLanguage); mainForm.add(editor); initButtons(mainForm); @@ -293,11 +299,11 @@ public void savePerformed(AjaxRequestTarget target) { PrismObject oldObject = dto.getObject(); oldObject.revive(getPrismContext()); - Holder> objectHolder = new Holder>(null); + Holder> objectHolder = new Holder<>(null); if (editor.isVisible()) { - validateObject(editor.getModel().getObject(), objectHolder, validateSchema.getObject(), result); + validateObject(editor.getModel().getObject(), objectHolder, dataLanguage, validateSchema.getObject(), result); } else { - validateObject(plainTextarea.getModel().getObject(), objectHolder, validateSchema.getObject(), result); + validateObject(plainTextarea.getModel().getObject(), objectHolder, dataLanguage, validateSchema.getObject(), result); } if (result.isAcceptable()) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageEvaluateMapping.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageEvaluateMapping.java index 73cce6d12c9..17204df97dd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageEvaluateMapping.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageEvaluateMapping.java @@ -183,14 +183,13 @@ private void executeMappingPerformed(AjaxRequestTarget target) { try { MappingEvaluationRequestType request; if (StringUtils.isNotBlank(dto.getRequest())) { - request = getPrismContext().parseAtomicValue(dto.getRequest(), MappingEvaluationRequestType.COMPLEX_TYPE, PrismContext.LANG_XML); + request = getPrismContext().parserFor(dto.getRequest()).xml().parseRealValue(MappingEvaluationRequestType.class); } else { request = new MappingEvaluationRequestType(); } if (StringUtils.isNotBlank(dto.getMapping())) { - request.setMapping((MappingType) getPrismContext() - .parseAtomicValue(dto.getMapping(), MappingType.COMPLEX_TYPE, PrismContext.LANG_XML)); + request.setMapping(getPrismContext().parserFor(dto.getMapping()).xml().parseRealValue(MappingType.class)); } MappingEvaluationResponseType response = getModelDiagnosticService().evaluateMapping(request, task, result); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageRepositoryQuery.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageRepositoryQuery.java index 1e29303882a..bc81c087fe1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageRepositoryQuery.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageRepositoryQuery.java @@ -23,7 +23,7 @@ import com.evolveum.midpoint.model.common.expression.ExpressionUtil; import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; @@ -370,7 +370,7 @@ private void useInObjectListPerformed(AjaxRequestTarget target) { String filterAsString; if (parsedFilter != null) { SearchFilterType filterType = QueryConvertor.createSearchFilterType(parsedFilter, getPrismContext()); - filterAsString = getPrismContext().serializeAtomicValue(filterType, SchemaConstantsGenerated.Q_FILTER, PrismContext.LANG_XML); + filterAsString = getPrismContext().xmlSerializer().serializeRealValue(filterType, SchemaConstantsGenerated.Q_FILTER); // TODO remove extra xmlns from serialized value } else { filterAsString = ""; @@ -507,7 +507,7 @@ private void updateRequestWithMidpointQuery(RepositoryQueryDiagRequest request, if (clazz == null) { throw new SchemaException("Couldn't find compile-time class for object type of " + objectType); } - QueryType queryType = prismContext.parseAtomicValue(queryText, QueryType.COMPLEX_TYPE, PrismContext.LANG_XML); + QueryType queryType = prismContext.parserFor(queryText).xml().parseRealValue(QueryType.class); request.setType(clazz); ObjectQuery objectQuery = QueryJaxbConvertor.createObjectQuery(clazz, queryType, prismContext); ObjectQuery queryWithExprEvaluated = ExpressionUtil.evaluateQueryExpressions(objectQuery, new ExpressionVariables(), diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectSelectionPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectSelectionPanel.java index 53dca4322c7..f4d1cc41928 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectSelectionPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/ObjectSelectionPanel.java @@ -23,8 +23,10 @@ import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.AndFilter; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.SubstringFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.logging.LoggingUtils; @@ -298,10 +300,11 @@ private ObjectQuery createObjectQuery() { PolyStringNormalizer normalizer = prismContext.getDefaultPolyStringNormalizer(); String normalized = normalizer.normalize(dto.getText()); - SubstringFilter filter = SubstringFilter.createSubstring(context.getSearchProperty(), objectType, prismContext, - PolyStringNormMatchingRule.NAME, normalized); + ObjectFilter filter = QueryBuilder.queryFor(objectType, prismContext) + .item(context.getSearchProperty()).contains(normalized).matchingNorm() + .buildFilter(); - if(context.getDataProviderQuery() != null){ + if (context.getDataProviderQuery() != null) { AndFilter and = AndFilter.createAnd(context.getDataProviderQuery().getFilter(), filter); query = ObjectQuery.createObjectQuery(and); } else { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageDashboard.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageDashboard.java index 8524a42c1ef..a956b51a915 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageDashboard.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/home/PageDashboard.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.web.page.admin.home; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.Component; import org.apache.wicket.model.Model; import org.apache.wicket.request.component.IRequestablePage; @@ -44,17 +45,8 @@ import com.evolveum.midpoint.web.page.admin.services.PageServices; import com.evolveum.midpoint.web.page.admin.users.PageOrgTree; import com.evolveum.midpoint.web.page.admin.users.PageUsers; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; + +import static com.evolveum.midpoint.schema.constants.SchemaConstants.C_ACTIVATION; /** * @author lazyman @@ -138,17 +130,19 @@ private InfoBoxPanel createFocusInfoBoxPanel(String id, Cl if (allCount == null) { allCount = 0; } - - EqualFilter filterDisabled = EqualFilter.createEqual(SchemaConstants.PATH_ACTIVATION_EFFECTIVE_STATUS, - type, getPrismContext(), ActivationStatusType.DISABLED); - Integer disabledCount = getModelService().countObjects(type, ObjectQuery.createObjectQuery(filterDisabled), null, task, result); + + ObjectQuery queryDisabled = QueryBuilder.queryFor(type, getPrismContext()) + .item(FocusType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS).eq(ActivationStatusType.DISABLED) + .build(); + Integer disabledCount = getModelService().countObjects(type, queryDisabled, null, task, result); if (disabledCount == null) { disabledCount = 0; } - - EqualFilter filterArchived = EqualFilter.createEqual(SchemaConstants.PATH_ACTIVATION_EFFECTIVE_STATUS, - type, getPrismContext(), ActivationStatusType.ARCHIVED); - Integer archivedCount = getModelService().countObjects(type, ObjectQuery.createObjectQuery(filterArchived), null, task, result); + + ObjectQuery queryArchived = QueryBuilder.queryFor(type, getPrismContext()) + .item(FocusType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS).eq(ActivationStatusType.ARCHIVED) + .build(); + Integer archivedCount = getModelService().countObjects(type, queryArchived, null, task, result); if (archivedCount == null) { archivedCount = 0; } @@ -226,10 +220,9 @@ private Component createTaskInfoBoxPanel(OperationResult result, Task task) { if (totalCount == null) { totalCount = 0; } - - EqualFilter filter = EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, - TaskType.class, getPrismContext(), TaskExecutionStatusType.RUNNABLE); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, getPrismContext()) + .item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.RUNNABLE) + .build(); Integer activeCount = getModelService().countObjects(TaskType.class, query, null, task, result); if (activeCount == null) { activeCount = 0; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageCreatedReports.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageCreatedReports.java index 45f4f05c86f..c13747da09a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageCreatedReports.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageCreatedReports.java @@ -24,6 +24,8 @@ import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.report.api.ReportManager; import com.evolveum.midpoint.schema.result.OperationResult; @@ -466,40 +468,20 @@ private void deleteAllConfirmedPerformed(AjaxRequestTarget target) { private ObjectQuery createQuery() { ReportOutputSearchDto dto = searchModel.getObject(); + S_AtomicFilterEntry q = QueryBuilder.queryFor(ReportOutputType.class, getPrismContext()); - try { - List ands = new ArrayList<>(); - - if (StringUtils.isNotEmpty(dto.getText())) { - PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); - String normalizedString = normalizer.normalize(dto.getText()); - - SubstringFilter substring = SubstringFilter.createSubstring(ReportOutputType.F_NAME, - ReportOutputType.class, getPrismContext(), PolyStringNormMatchingRule.NAME, normalizedString); - ands.add(substring); - } - - String oid = dto.getReportTypeMap().get(dto.getReportType()); - if (StringUtils.isNotEmpty(oid)) { - RefFilter ref = RefFilter.createReferenceEqual(ReportOutputType.F_REPORT_REF, ReportOutputType.class, - getPrismContext(), oid); - ands.add(ref); - } + if (StringUtils.isNotEmpty(dto.getText())) { + PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); + String normalizedString = normalizer.normalize(dto.getText()); + q = q.item(ReportOutputType.F_NAME).containsPoly(normalizedString).matchingNorm().and(); + } - switch (ands.size()) { - case 0: - return null; - case 1: - return ObjectQuery.createObjectQuery(ands.get(0)); - default: - AndFilter and = AndFilter.createAnd(ands); - return ObjectQuery.createObjectQuery(and); - } - } catch (Exception e) { - error(getString("pageCreatedReports.message.queryError") + " " + e.getMessage()); - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't create query filter.", e); - return null; + String oid = dto.getReportTypeMap().get(dto.getReportType()); + if (StringUtils.isNotEmpty(oid)) { + q = q.item(ReportOutputType.F_REPORT_REF).ref(oid).and(); } + + return q.all().build(); } private InputStream createReport(AjaxDownloadBehaviorFromStream ajaxDownloadBehaviorFromStream) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReport.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReport.java index 5334cbd7ff2..366b156e2bb 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReport.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReport.java @@ -216,7 +216,7 @@ public void validate(IValidatable validatable) { OpResult opResult = null; try { - validateObject(value, reportHolder, true, result); + validateObject(value, reportHolder, PrismContext.LANG_XML, true, result); if(!result.isAcceptable()){ result.recordFatalError("Could not validate object", result.getCause()); @@ -261,7 +261,7 @@ public void setObject(String object) { Holder> reportHolder = new Holder<>(null); try { - validateObject(object, reportHolder, true, result); + validateObject(object, reportHolder, PrismContext.LANG_XML, true, result); model.getObject().setObject(reportHolder.getValue()); } catch (Exception e){ LOGGER.error("Could not set object. Validation problem occured." + result.getMessage()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java index 2e1275b36e3..0e04e1c26fc 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageReports.java @@ -21,6 +21,9 @@ import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.task.api.Task; @@ -274,32 +277,17 @@ private ObjectQuery createQuery() { ReportSearchDto dto = searchModel.getObject(); String text = dto.getText(); Boolean parent = !dto.isParent(); - ObjectQuery query = new ObjectQuery(); - List filters = new ArrayList<>(); + S_AtomicFilterEntry q = QueryBuilder.queryFor(ReportType.class, getPrismContext()); if (StringUtils.isNotEmpty(text)) { PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); String normalizedText = normalizer.normalize(text); - - ObjectFilter substring = SubstringFilter.createSubstring(ReportType.F_NAME, ReportType.class, - getPrismContext(), PolyStringNormMatchingRule.NAME, normalizedText); - - filters.add(substring); - } - - if (parent == true) { - EqualFilter parentFilter = EqualFilter.createEqual(ReportType.F_PARENT, ReportType.class, - getPrismContext(), null, parent); - filters.add(parentFilter); + q = q.item(ReportType.F_NAME).eqPoly(normalizedText).matchingNorm().and(); } - - if (!filters.isEmpty()) { - query.setFilter(AndFilter.createAnd(filters)); - } else { - query = null; + if (parent) { + q = q.item(ReportType.F_PARENT).eq(true).and(); } - - return query; + return q.all().build(); } private void clearSearchPerformed(AjaxRequestTarget target) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java index 9cfab157c28..384376ab6be 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/RunReportPopupPanel.java @@ -23,6 +23,8 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; @@ -45,15 +47,7 @@ import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectPaging; @@ -129,7 +123,7 @@ public class RunReportPopupPanel extends BasePanel implements Popupab // public void setReportType(ReportType reportType) { // this.reportType = reportType; -// +// // if (getParametersTable() != null) { // replace(createTablePanel()); // } @@ -137,7 +131,7 @@ public class RunReportPopupPanel extends BasePanel implements Popupab public RunReportPopupPanel(String id, final ReportType reportType) { super(id); - + reportModel = new LoadableModel(false) { @Override @@ -145,7 +139,7 @@ protected ReportDto load() { return new ReportDto(reportType, true); } }; - + initLayout(); } @@ -154,7 +148,7 @@ protected void initLayout() { Form mainForm = new Form(ID_MAIN_FORM); add(mainForm); - + BoxedTablePanel table = createTablePanel(); mainForm.add(table); @@ -175,7 +169,7 @@ protected void onSubmit(AjaxRequestTarget target, Form form) { } private BoxedTablePanel createTablePanel() { - + ISortableDataProvider provider = new ListDataProvider<>(this, new PropertyModel>(reportModel, "jasperReportDto.parameters")); @@ -324,12 +318,10 @@ private List createLookupTableRows(Ja Task task = createSimpleTask(OPERATION_LOAD_RESOURCES); Collection> objects; - SubstringFilter filter = SubstringFilter.createSubstring(new QName(SchemaConstants.NS_C, pLabel), targetType, getPrismContext(), input); - filter.setMatchingRule(new QName(SchemaConstants.NS_MATCHING_RULE, "origIgnoreCase")); - filter.setAnchorStart(true); // =startsWith - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - query.setPaging(ObjectPaging.createPaging(0, AUTO_COMPLETE_BOX_SIZE)); - + ObjectQuery query = QueryBuilder.queryFor(targetType, getPrismContext()) + .item(new QName(SchemaConstants.NS_C, pLabel)).startsWith(input).matchingCaseIgnore() + .maxSize(AUTO_COMPLETE_BOX_SIZE) + .build(); try { objects = getPageBase().getModelService().searchObjects(targetType, query, SelectorOptions.createCollection(GetOperationOptions.createNoFetch()), task, result); @@ -539,20 +531,15 @@ private void runConfirmPerformed(AjaxRequestTarget target, IModel mod } } */ - if (XmlTypeConverter.canConvert(paramClass)) { - typeName = XsdTypeMapper.toXsdType(paramClass); - } else { - - if (AuditEventType.class.isAssignableFrom(paramClass)) { - paramClass = AuditEventTypeType.class; - realValue = AuditEventType.fromAuditEventType((AuditEventType) realValue); - } else if (AuditEventStage.class.isAssignableFrom(paramClass)) { - paramClass = AuditEventStageType.class; - realValue = AuditEventStage.fromAuditEventStage((AuditEventStage) realValue); - } - typeName = getPrismContext().getBeanConverter().determineTypeForClass(paramClass); + if (AuditEventType.class.isAssignableFrom(paramClass)) { + paramClass = AuditEventTypeType.class; + realValue = AuditEventType.fromAuditEventType((AuditEventType) realValue); + } else if (AuditEventStage.class.isAssignableFrom(paramClass)) { + paramClass = AuditEventStageType.class; + realValue = AuditEventStage.fromAuditEventStage((AuditEventStage) realValue); } - PrismPropertyDefinition def = new PrismPropertyDefinition<>(new QName(ReportConstants.NS_EXTENSION, paramDto.getName()), typeName, getPrismContext()); + typeName = getPrismContext().getSchemaRegistry().determineTypeForClass(paramClass); + PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl<>(new QName(ReportConstants.NS_EXTENSION, paramDto.getName()), typeName, getPrismContext()); def.setDynamic(true); def.setRuntimeSchema(true); PrismProperty prop = def.instantiate(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageAdminResources.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageAdminResources.java index 0d3c15b3ac6..6942fa27b27 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageAdminResources.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageAdminResources.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -118,21 +119,14 @@ protected void deleteSyncTokenPerformed(AjaxRequestTarget target, ResourceType r PrismObject oldTask; OperationResult result = new OperationResult(OPERATION_DELETE_SYNC_TOKEN); - ObjectQuery query; + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, getPrismContext()) + .item(TaskType.F_OBJECT_REF).ref(resourceOid) + .and().item(TaskType.F_HANDLER_URI).eq(handlerUri) + .build(); - ObjectFilter refFilter = RefFilter.createReferenceEqual(TaskType.F_OBJECT_REF, TaskType.class, - getPrismContext(), resourceOid); + List> taskList = WebModelServiceUtils.searchObjects(TaskType.class, query, result, this); - ObjectFilter filterHandleUri = EqualFilter.createEqual(TaskType.F_HANDLER_URI, TaskType.class, - getPrismContext(), null, handlerUri); - - query = new ObjectQuery(); - query.setFilter(AndFilter.createAnd(refFilter, filterHandleUri)); - - List> taskList = WebModelServiceUtils.searchObjects(TaskType.class, query, - result, this); - - if(taskList.size() != 1){ + if (taskList.size() != 1) { error(getString("pageResource.message.invalidTaskSearch")); } else { oldTask = taskList.get(0); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageResourceEdit.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageResourceEdit.java index ca74f7f0c5f..c9947013cdf 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageResourceEdit.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/PageResourceEdit.java @@ -25,7 +25,7 @@ import com.evolveum.midpoint.prism.PrismReference; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.schema.SchemaRegistry; @@ -214,7 +214,7 @@ private void savePerformed(AjaxRequestTarget target) { OperationResult result = task.getResult(); try { Holder> objectHolder = new Holder>(null); - validateObject(dto.getXml(), objectHolder, false, result); + validateObject(dto.getXml(), objectHolder, PrismContext.LANG_XML, false, result); if (result.isAcceptable()) { PrismObject newResource = objectHolder.getValue(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java index 3e7819c4eb5..a0b68f1abbf 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java @@ -22,6 +22,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.web.session.SessionStorage; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -185,7 +187,7 @@ public QName getObjectClass() { } public RefinedObjectClassDefinition getDefinitionByKind() throws SchemaException { - RefinedResourceSchema refinedSchema = RefinedResourceSchema + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl .getRefinedSchema(resourceModel.getObject(), getPageBase().getPrismContext()); if (refinedSchema == null) { warn("No schema found in resource. Please check your configuration and try to test connection for the resource."); @@ -196,7 +198,7 @@ public RefinedObjectClassDefinition getDefinitionByKind() throws SchemaException } public RefinedObjectClassDefinition getDefinitionByObjectClass() throws SchemaException { - RefinedResourceSchema refinedSchema = RefinedResourceSchema + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl .getRefinedSchema(resourceModel.getObject(), getPageBase().getPrismContext()); if (refinedSchema == null) { warn("No schema found in resource. Please check your configuration and try to test connection for the resource."); @@ -344,9 +346,9 @@ public boolean isVisible() { List> tasks = WebModelServiceUtils .searchObjects(TaskType.class, - ObjectQuery.createObjectQuery(RefFilter.createReferenceEqual(TaskType.F_OBJECT_REF, - TaskType.class, getPageBase().getPrismContext(), - getResourceModel().getObject().getOid())), + QueryBuilder.queryFor(TaskType.class, getPageBase().getPrismContext()) + .item(TaskType.F_OBJECT_REF).ref(getResourceModel().getObject().getOid()) + .build(), result, getPageBase()); List tasksForKind = getTasksForKind(tasks); @@ -436,7 +438,7 @@ private void newTaskPerformed(String category, AjaxRequestTarget target) { private void runTask(List tasks, AjaxRequestTarget target) { ResourceTasksPanel tasksPanel = new ResourceTasksPanel(getPageBase().getMainPopupBodyId(), false, - new ListModel<>(tasks), getPageBase()); + new ListModel(tasks), getPageBase()); getPageBase().showMainPopup(tasksPanel, target); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentTabPanel.java index c904ce54023..100e7409a5b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentTabPanel.java @@ -22,6 +22,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.web.session.SessionStorage; import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -139,13 +140,13 @@ private void initLayout(final IModel> model, final Pag public Iterator getIterator(String input) { RefinedResourceSchema refinedSchema = null; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(model.getObject(), + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(model.getObject(), parentPage.getPrismContext()); } catch (SchemaException e) { return new ArrayList().iterator(); } - return RefinedResourceSchema.getIntentsForKind(refinedSchema, getKind()).iterator(); + return RefinedResourceSchemaImpl.getIntentsForKind(refinedSchema, getKind()).iterator(); } @@ -180,7 +181,7 @@ public boolean isVisible() { public String getObject() { RefinedObjectClassDefinition ocDef; try { - RefinedResourceSchema refinedSchema = RefinedResourceSchema + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl .getRefinedSchema(model.getObject(), parentPage.getPrismContext()); if (refinedSchema == null) { return "NO SCHEMA DEFINED"; @@ -288,7 +289,7 @@ protected void onBeforeRender() { private List createObjectClassChoices(IModel> model) { RefinedResourceSchema refinedSchema; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(model.getObject(), + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(model.getObject(), parentPage.getPrismContext()); } catch (SchemaException e) { warn("Could not determine defined obejct classes for resource"); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceDetailsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceDetailsTabPanel.java index 2c494b44f80..abd91eb6964 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceDetailsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceDetailsTabPanel.java @@ -21,6 +21,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -181,8 +183,9 @@ private List createResourceConfigList(ResourceType res OperationResult result = new OperationResult(OPERATION_SEARCH_TASKS_FOR_RESOURCE); List> tasks = WebModelServiceUtils.searchObjects(TaskType.class, - ObjectQuery.createObjectQuery(RefFilter.createReferenceEqual(TaskType.F_OBJECT_REF, - TaskType.class, parentPage.getPrismContext(), resource.getOid())), + QueryBuilder.queryFor(TaskType.class, parentPage.getPrismContext()) + .item(TaskType.F_OBJECT_REF).ref(resource.getOid()) + .build(), result, parentPage); List configs = new ArrayList<>(); @@ -321,7 +324,7 @@ private InfoBoxPanel createSchemaStatusInfo(ResourceType resource) { Integer progress = null; RefinedResourceSchema refinedSchema = null; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (refinedSchema != null) { backgroundColor = "bg-purple"; icon = "fa-cubes"; @@ -412,7 +415,7 @@ private List getTaskFor(List> tasks, // is not accessible in admin-gui) if (taskObjectClassValue == null) { ObjectClassComplexTypeDefinition taskObjectClassDef = null; - RefinedResourceSchema schema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema schema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (schema == null) { throw new SchemaException( "No schema defined in resource. Possible configuration problem?"); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceTasksPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceTasksPanel.java index 4185c413375..483f99c1bc2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceTasksPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceTasksPanel.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; @@ -94,9 +95,9 @@ private ListModel createTaskModel(PrismObject object) { OperationResult result = new OperationResult(OPERATION_LOAD_TASKS); List> tasks = WebModelServiceUtils .searchObjects(TaskType.class, - ObjectQuery.createObjectQuery(RefFilter.createReferenceEqual(TaskType.F_OBJECT_REF, - TaskType.class, pageBase.getPrismContext(), - object.getOid())), + QueryBuilder.queryFor(TaskType.class, pageBase.getPrismContext()) + .item(TaskType.F_OBJECT_REF).ref(object.getOid()) + .build(), result, pageBase); List tasksType = new ArrayList(); for (PrismObject task : tasks) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/dto/ResourceDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/dto/ResourceDto.java index bb892e78e2d..afe391561a0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/dto/ResourceDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/dto/ResourceDto.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.List; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.PrismReference; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.web.component.data.column.InlineMenuable; @@ -98,7 +99,7 @@ public ResourceDto(PrismObject resource, PrismContext prismContext this.capabilities = capabilities; try { - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); Collection definitions = resourceSchema.getObjectClassDefinitions(); for (ObjectClassComplexTypeDefinition definition : definitions) { if (!(definition instanceof ObjectClassComplexTypeDefinition)) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleMemberPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleMemberPanel.java index 5e6589d8337..8d57ec31d7a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleMemberPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/RoleMemberPanel.java @@ -22,6 +22,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.markup.html.form.DropDownChoice; @@ -118,46 +121,32 @@ protected void refreshTable(AjaxRequestTarget target) { getMemberTable().refreshTable((Class) WebComponentUtil.qnameToClass(getPrismContext(), type), target); } - private List createTenantList() { - ObjectQuery query; - try { - query = ObjectQuery.createObjectQuery( - EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, getPrismContext(), true)); - List> orgs = WebModelServiceUtils.searchObjects(OrgType.class, query, - new OperationResult("Tenant search"), getPageBase()); - List orgTypes = new ArrayList<>(); - for (PrismObject org : orgs) { - orgTypes.add(org.asObjectable()); - } - - return orgTypes; - } catch (SchemaException e) { - error(getString("pageUsers.message.queryError") + " " + e.getMessage()); - return null; + ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()) + .item(OrgType.F_TENANT).eq(true) + .build(); + List> orgs = WebModelServiceUtils.searchObjects(OrgType.class, query, + new OperationResult("Tenant search"), getPageBase()); + List orgTypes = new ArrayList<>(); + for (PrismObject org : orgs) { + orgTypes.add(org.asObjectable()); } + return orgTypes; } private List createProjectList() { - ObjectQuery query; - try { - query = ObjectQuery.createObjectQuery(OrFilter.createOr( - EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, getPrismContext(), true), - EqualFilter.createEqual(OrgType.F_TENANT, OrgType.class, getPrismContext(), null))); - List> orgs = WebModelServiceUtils.searchObjects(OrgType.class, query, - new OperationResult("Tenant search"), getPageBase()); - List orgTypes = new ArrayList<>(); - for (PrismObject org : orgs) { - orgTypes.add(org.asObjectable()); - } - - return orgTypes; - } catch (SchemaException e) { - error(getString("pageUsers.message.queryError") + " " + e.getMessage()); - return null; + ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()) + .item(OrgType.F_TENANT).eq(true) + .or().item(OrgType.F_TENANT).isNull() + .build(); + List> orgs = WebModelServiceUtils.searchObjects(OrgType.class, query, + new OperationResult("Tenant search"), getPageBase()); + List orgTypes = new ArrayList<>(); + for (PrismObject org : orgs) { + orgTypes.add(org.asObjectable()); } - + return orgTypes; } private MainObjectListPanel getMemberTable() { @@ -196,7 +185,9 @@ private ObjectQuery getActionQuery(QueryScope scope) { } private ObjectQuery createAllMemberQuery() { - return ObjectQuery.createObjectQuery(RefFilter.createReferenceEqual(FocusType.F_ROLE_MEMBERSHIP_REF, FocusType.class, getModelObject())); + return QueryBuilder.queryFor(FocusType.class, getPrismContext()) + .item(FocusType.F_ROLE_MEMBERSHIP_REF).ref(getModelObject().getOid()) + .build(); } private ObjectQuery createRecomputeQuery() { @@ -311,46 +302,31 @@ private ObjectQuery createDirectMemberQuery() { String oid = getModelObject().getOid(); - List filters = new ArrayList<>(); - try { - filters.add(RefFilter.createReferenceEqual( - new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, - getPrismContext(), createReference().asReferenceValue())); - - DropDownChoice tenantChoice = (DropDownChoice) get(createComponentPath(ID_TENANT)); - OrgType tenant = tenantChoice.getModelObject(); - - if (tenant != null) { - filters.add(RefFilter.createReferenceEqual( - new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_TENANT_REF), UserType.class, - getPrismContext(), createReference(tenant).asReferenceValue())); - } - - DropDownChoice projectChoice = (DropDownChoice) get(createComponentPath(ID_PROJECT)); - OrgType project = projectChoice.getModelObject(); - - if (project != null) { - filters.add(RefFilter.createReferenceEqual( - new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_ORG_REF), UserType.class, - getPrismContext(), createReference(project).asReferenceValue())); - } - - query = ObjectQuery.createObjectQuery(AndFilter.createAnd(filters)); + S_AtomicFilterExit q = QueryBuilder.queryFor(FocusType.class, getPrismContext()) + .item(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(createReference().asReferenceValue()); + DropDownChoice tenantChoice = (DropDownChoice) get(createComponentPath(ID_TENANT)); + OrgType tenant = tenantChoice.getModelObject(); + if (tenant != null) { + q = q.and().item(FocusType.F_ASSIGNMENT, AssignmentType.F_TENANT_REF).ref(createReference(tenant).asReferenceValue()); + } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Searching members of role {} with query:\n{}", oid, query.debugDump()); - } + DropDownChoice projectChoice = (DropDownChoice) get(createComponentPath(ID_PROJECT)); + OrgType project = projectChoice.getModelObject(); + if (project != null) { + q = q.and().item(FocusType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(createReference(project).asReferenceValue()); + } - } catch (SchemaException e) { - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't prepare query for org. members.", e); + query = q.build(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Searching members of role {} with query:\n{}", oid, query.debugDump()); } DropDownChoice objectTypeChoice = (DropDownChoice) get(createComponentPath(ID_OBJECT_TYPE)); QName objectType = objectTypeChoice.getModelObject(); if (objectType == null || FocusType.COMPLEX_TYPE.equals(objectType)) { return query; + } else { + return ObjectQuery.createObjectQuery(TypeFilter.createType(objectType, query.getFilter())); } - - return ObjectQuery.createObjectQuery(TypeFilter.createType(objectType, query.getFilter())); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskAdd.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskAdd.java index 2c8fc9b9672..9149c830cb7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskAdd.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskAdd.java @@ -24,6 +24,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; @@ -255,7 +256,7 @@ protected void onUpdate(AjaxRequestTarget target) { resourcesDto.getOid(), PageTaskAdd.this, task, result); try { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, getPrismContext()); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, getPrismContext()); schema.getObjectClassDefinitions(); for(Definition def: schema.getDefinitions()){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java index cf09d3708c0..522260c4ac1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTasks.java @@ -25,6 +25,9 @@ import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -1198,38 +1201,23 @@ private ObjectQuery createTaskQuery() { String category = dto.getCategory(); boolean showSubtasks = dto.isShowSubtasks(); - ObjectQuery query = null; - try { - List filters = new ArrayList<>(); - if (status != null) { - ObjectFilter filter = status.createFilter(TaskType.class, getPrismContext()); - if (filter != null) { - filters.add(filter); - } - } - if (category != null && !ALL_CATEGORIES.equals(category)) { - filters.add(EqualFilter.createEqual(TaskType.F_CATEGORY, TaskType.class, getPrismContext(), null, category)); - } - if (searchText != null && !searchText.trim().equals("")) { - PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); - String normalizedString = normalizer.normalize(searchText); - - ObjectFilter substring = SubstringFilter.createSubstring(TaskType.F_NAME, TaskType.class, - getPrismContext(), PolyStringNormMatchingRule.NAME, normalizedString); - filters.add(substring); - searchText = ""; - } - if (!Boolean.TRUE.equals(showSubtasks)) { - filters.add(EqualFilter.createEqual(TaskType.F_PARENT, TaskType.class, getPrismContext(), null)); - } - if (!filters.isEmpty()) { - query = new ObjectQuery().createObjectQuery(AndFilter.createAnd(filters)); - } - } catch (Exception ex) { - error(getString("pageTasks.message.couldntCreateQuery") + " " + ex.getMessage()); - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't create task filter", ex); + S_AtomicFilterEntry q = QueryBuilder.queryFor(TaskType.class, getPrismContext()); + if (status != null) { + q = status.appendFilter(q); + } + if (category != null && !ALL_CATEGORIES.equals(category)) { + q = q.item(TaskType.F_CATEGORY).eq(category).and(); + } + if (StringUtils.isNotBlank(searchText)) { + PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); + String normalizedString = normalizer.normalize(searchText); + q = q.item(TaskType.F_NAME).containsPoly(normalizedString, normalizedString).matchingNorm().and(); + searchText = ""; // ??? + } + if (!Boolean.TRUE.equals(showSubtasks)) { + q = q.item(TaskType.F_PARENT).isNull().and(); } - return query; + return q.all().build(); } private void clearSearchPerformed(AjaxRequestTarget target) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java index fa63a9618e2..8d425de4cc6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java @@ -788,7 +788,7 @@ public String getObjectQuery() { QueryType queryType = getExtensionPropertyRealValue(SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY, QueryType.class); PrismContext prismContext = ((MidPointApplication) Application.get()).getPrismContext(); try { - return prismContext.serializeAnyData(queryType, SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY, PrismContext.LANG_XML); + return prismContext.xmlSerializer().serializeAnyData(queryType, SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY); } catch (SchemaException e) { throw new SystemException("Couldn't serialize query: " + e.getMessage(), e); } @@ -798,7 +798,7 @@ public String getObjectDelta() { ObjectDeltaType objectDeltaType = getExtensionPropertyRealValue(SchemaConstants.MODEL_EXTENSION_OBJECT_DELTA, ObjectDeltaType.class); PrismContext prismContext = ((MidPointApplication) Application.get()).getPrismContext(); try { - return prismContext.serializeAnyData(objectDeltaType, SchemaConstants.MODEL_EXTENSION_OBJECT_DELTA, PrismContext.LANG_XML); + return prismContext.xmlSerializer().serializeAnyData(objectDeltaType, SchemaConstants.MODEL_EXTENSION_OBJECT_DELTA); } catch (SchemaException e) { throw new SystemException("Couldn't serialize delta: " + e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDtoExecutionStatusFilter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDtoExecutionStatusFilter.java index eabe150019a..19eca8d59a9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDtoExecutionStatusFilter.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDtoExecutionStatusFilter.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; @@ -40,21 +41,15 @@ public enum TaskDtoExecutionStatusFilter { CLOSED, NOT_CLOSED; - public ObjectFilter createFilter(Class clazz, PrismContext prismContext) throws SchemaException { + public S_AtomicFilterEntry appendFilter(S_AtomicFilterEntry q) { switch(this) { - case ALL: return null; - case RUNNING_OR_RUNNABLE: return createExecutionStatusFilter(clazz, prismContext, TaskExecutionStatusType.RUNNABLE); - case WAITING: return createExecutionStatusFilter(clazz, prismContext, TaskExecutionStatusType.WAITING); - case SUSPENDED_OR_SUSPENDING: return createExecutionStatusFilter(clazz, prismContext, TaskExecutionStatusType.SUSPENDED); - case CLOSED: return createExecutionStatusFilter(clazz, prismContext, TaskExecutionStatusType.CLOSED); - case NOT_CLOSED: return NotFilter.createNot(createExecutionStatusFilter(clazz, prismContext, TaskExecutionStatusType.CLOSED)); + case ALL: return q; + case RUNNING_OR_RUNNABLE: return q.item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.RUNNABLE).and(); + case WAITING: return q.item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.WAITING).and(); + case SUSPENDED_OR_SUSPENDING: return q.item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.SUSPENDED).and(); + case CLOSED: return q.item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.CLOSED).and(); + case NOT_CLOSED: return q.block().not().item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.RUNNABLE).endBlock().and(); default: throw new SystemException("Unknown value for TaskDtoExecutionStatusFilter: " + this); } } - - private EqualFilter createExecutionStatusFilter(Class clazz, PrismContext prismContext, TaskExecutionStatusType value){ - return EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, clazz, prismContext, null, value); - } - - } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.java index 6f1be97ae17..9fec27719ab 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.web.page.admin.server.handlers; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; @@ -149,7 +150,7 @@ protected void onUpdate(AjaxRequestTarget target) { resourcesDto.getOid(), parentPage, task, result); try { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, parentPage.getPrismContext()); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, parentPage.getPrismContext()); schema.getObjectClassDefinitions(); for(Definition def: schema.getDefinitions()){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ExecuteChangesHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ExecuteChangesHandlerDto.java index 26f09ab69ba..f7f488db2e8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ExecuteChangesHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ExecuteChangesHandlerDto.java @@ -45,7 +45,7 @@ public String getObjectDeltaXml() { PrismContext prismContext = ((MidPointApplication) Application.get()).getPrismContext(); try { return WebXmlUtil.stripNamespaceDeclarations( - prismContext.serializeAnyData(objectDeltaType, SchemaConstants.MODEL_EXTENSION_OBJECT_DELTA, PrismContext.LANG_XML)); + prismContext.xmlSerializer().serializeAnyData(objectDeltaType, SchemaConstants.MODEL_EXTENSION_OBJECT_DELTA)); } catch (SchemaException e) { throw new SystemException("Couldn't serialize object delta: " + e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java index 3adfd1a0bbe..9a0ea2c88d1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java @@ -72,17 +72,17 @@ public GenericHandlerDto(TaskDto taskDto, @NotNull List items, PageBase pa final PrismContext prismContext = pageBase.getPrismContext(); PrismContainer container = new PrismContainer(new QName("test"), prismContext); - ComplexTypeDefinition ctd = new ComplexTypeDefinition(new QName("Test"), prismContext); + ComplexTypeDefinitionImpl ctd = new ComplexTypeDefinitionImpl(new QName("Test"), prismContext); int displayOrder = 1; for (Item item : items) { PrismProperty property = taskDto.getExtensionProperty(item.name); - PrismPropertyDefinition clonedDefinition = null; + PrismPropertyDefinitionImpl clonedDefinition = null; if (property != null) { try { PrismProperty clonedProperty = property.clone(); container.add(clonedProperty); if (clonedProperty.getDefinition() != null) { - clonedDefinition = clonedProperty.getDefinition().clone(); + clonedDefinition = (PrismPropertyDefinitionImpl) clonedProperty.getDefinition().clone(); clonedProperty.setDefinition((PrismPropertyDefinition) clonedDefinition); } } catch (SchemaException e) { @@ -90,7 +90,7 @@ public GenericHandlerDto(TaskDto taskDto, @NotNull List items, PageBase pa } } if (clonedDefinition == null) { - clonedDefinition = CloneUtil.clone(prismContext.getSchemaRegistry().findPropertyDefinitionByElementName(item.name)); + clonedDefinition = CloneUtil.clone((PrismPropertyDefinitionImpl) prismContext.getSchemaRegistry().findPropertyDefinitionByElementName(item.name)); } if (clonedDefinition == null) { System.out.println("Definition-less property " + item.name); @@ -102,7 +102,7 @@ public GenericHandlerDto(TaskDto taskDto, @NotNull List items, PageBase pa } displayOrder++; } - PrismContainerDefinition containerDefinition = new PrismContainerDefinition<>(new QName("test"), ctd, prismContext); + PrismContainerDefinition containerDefinition = new PrismContainerDefinitionImpl<>(new QName("test"), ctd, prismContext); container.setDefinition(containerDefinition); containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.MODIFYING, ItemPath.EMPTY_PATH, true); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/QueryBasedHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/QueryBasedHandlerDto.java index d6286ac89ef..718837f1664 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/QueryBasedHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/QueryBasedHandlerDto.java @@ -58,7 +58,7 @@ public String getObjectQuery() { PrismContext prismContext = ((MidPointApplication) Application.get()).getPrismContext(); try { return WebXmlUtil.stripNamespaceDeclarations( - prismContext.serializeAnyData(query, SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY, PrismContext.LANG_XML)); + prismContext.xmlSerializer().serializeAnyData(query, SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY)); } catch (SchemaException e) { throw new SystemException("Couldn't serialize query: " + e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ReportCreateHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ReportCreateHandlerDto.java index aa86eb9eebd..0e368554860 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ReportCreateHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ReportCreateHandlerDto.java @@ -57,7 +57,7 @@ public String getReportParams() { PrismContext prismContext = ((MidPointApplication) Application.get()).getPrismContext(); try { return WebXmlUtil.stripNamespaceDeclarations( - prismContext.serializeContainerValueToString(pcv, ReportConstants.REPORT_PARAMS_PROPERTY_NAME, PrismContext.LANG_XML)); + prismContext.xmlSerializer().serialize(pcv, ReportConstants.REPORT_PARAMS_PROPERTY_NAME)); } catch (SchemaException e) { throw new SystemException("Couldn't serialize report parameters: " + e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ResourceRelatedHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ResourceRelatedHandlerDto.java index 32358901613..2bc0d224653 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ResourceRelatedHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ResourceRelatedHandlerDto.java @@ -1,6 +1,7 @@ package com.evolveum.midpoint.web.page.admin.server.handlers.dto; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.*; @@ -155,7 +156,7 @@ private void updateObjectClassList(PageBase pageBase){ pageBase, task, result); try { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, pageBase.getPrismContext()); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, pageBase.getPrismContext()); schema.getObjectClassDefinitions(); for(Definition def: schema.getDefinitions()){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ScriptExecutionHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ScriptExecutionHandlerDto.java index 9f3094c72bb..41495447555 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ScriptExecutionHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/ScriptExecutionHandlerDto.java @@ -45,7 +45,7 @@ public String getScript() { PrismContext prismContext = ((MidPointApplication) Application.get()).getPrismContext(); try { return WebXmlUtil.stripNamespaceDeclarations( - prismContext.serializeAnyData(script, SchemaConstants.SE_EXECUTE_SCRIPT, PrismContext.LANG_XML)); + prismContext.xmlSerializer().serializeAnyData(script, SchemaConstants.SE_EXECUTE_SCRIPT)); } catch (SchemaException e) { throw new SystemException("Couldn't serialize script: " + e.getMessage(), e); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AbstractTreeTablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AbstractTreeTablePanel.java index 5d37217a25e..e7fe9a3bd0e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AbstractTreeTablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AbstractTreeTablePanel.java @@ -20,6 +20,9 @@ import java.util.Iterator; import java.util.List; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.tree.ITreeProvider; @@ -158,42 +161,38 @@ protected ObjectQuery createOrgChildQuery() { if (StringUtils.isBlank(object)) { object = null; } - - OrgFilter org; + + PageBase page = getPageBase(); + PrismContext context = page.getPrismContext(); + + S_AtomicFilterExit q; if (object == null || SEARCH_SCOPE_ONE.equals(scope)) { - org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL); + q = QueryBuilder.queryFor(OrgType.class, context) + .isDirectChildOf(oid); } else { - org = OrgFilter.createOrg(oid, OrgFilter.Scope.SUBTREE); + q = QueryBuilder.queryFor(OrgType.class, context) + .isChildOf(oid); } if (object == null) { - return ObjectQuery.createObjectQuery(org); + return q.build(); } - - PageBase page = getPageBase(); - PrismContext context = page.getPrismContext(); PolyStringNormalizer normalizer = context.getDefaultPolyStringNormalizer(); String normalizedString = normalizer.normalize(object); if (StringUtils.isEmpty(normalizedString)) { - return ObjectQuery.createObjectQuery(org); + return q.build(); } - SubstringFilter substringName = SubstringFilter.createSubstring(OrgType.F_NAME, OrgType.class, context, - PolyStringNormMatchingRule.NAME, normalizedString); - - SubstringFilter substringDisplayName = SubstringFilter.createSubstring(OrgType.F_DISPLAY_NAME, OrgType.class, context, - PolyStringNormMatchingRule.NAME, normalizedString); - OrFilter orName = OrFilter.createOr(substringName, substringDisplayName); - AndFilter and = AndFilter.createAnd(org, orName); - ObjectQuery query = ObjectQuery.createObjectQuery(and); - - if(LOGGER.isTraceEnabled()){ + ObjectQuery query = q.and().block() + .item(OrgType.F_NAME).containsPoly(normalizedString).matchingNorm() + .or().item(OrgType.F_DISPLAY_NAME).containsPoly(normalizedString).matchingNorm() + .build(); + + if (LOGGER.isTraceEnabled()) { LOGGER.trace("Searching child orgs of org {} with query:\n{}", oid, query.debugDump()); } - return query; } - } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgMemberPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgMemberPanel.java index 392c7b064ed..d19dc3c8e36 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgMemberPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgMemberPanel.java @@ -25,6 +25,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; import org.apache.wicket.Component; @@ -446,33 +449,24 @@ private MainObjectListPanel getMemberTable() { createComponentPath(ID_FORM, ID_CONTAINER_MEMBER, ID_MEMBER_TABLE)); } - private QName getSearchType() { + private ObjectTypes getSearchType() { DropDownChoice searchByTypeChoice = (DropDownChoice) get( createComponentPath(ID_FORM, ID_SEARCH_BY_TYPE)); - ObjectTypes typeModel = searchByTypeChoice.getModelObject(); - return typeModel.getTypeQName(); + return searchByTypeChoice.getModelObject(); } private ObjectQuery createManagerQuery() { - String oid = getModelObject().getOid(); PrismReferenceValue referenceFilter = new PrismReferenceValue(); referenceFilter.setOid(oid); referenceFilter.setRelation(SchemaConstants.ORG_MANAGER); - RefFilter referenceOidFilter; - try { - referenceOidFilter = RefFilter.createReferenceEqual(new ItemPath(FocusType.F_PARENT_ORG_REF), - UserType.class, getPageBase().getPrismContext(), referenceFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(referenceOidFilter); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Searching members of org {} with query:\n{}", oid, query.debugDump()); - } - return query; - } catch (SchemaException e) { - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't prepare query for org. managers.", e); - return null; + ObjectQuery query = QueryBuilder.queryFor(FocusType.class, getPageBase().getPrismContext()) + .item(FocusType.F_PARENT_ORG_REF).ref(referenceFilter) + .build(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Searching members of org {} with query:\n{}", oid, query.debugDump()); } - + return query; } private ObjectDelta prepareDelta(MemberOperation operaton, QName type, QName relation, @@ -566,37 +560,27 @@ protected void recomputeManagersPerformed(QueryScope scope, AjaxRequestTarget ta @Override protected ObjectQuery createMemberQuery() { - ObjectQuery query = null; - String oid = getModelObject().getOid(); - List filters = new ArrayList<>(); - DropDownChoice searchScopeChoice = (DropDownChoice) get( createComponentPath(ID_FORM, ID_SEARCH_SCOPE)); String scope = searchScopeChoice.getModelObject(); - QName searchType = getSearchType(); - - OrgFilter org; + ObjectTypes searchType = getSearchType(); + S_FilterEntryOrEmpty q = QueryBuilder.queryFor(ObjectType.class, getPageBase().getPrismContext()); + if (!searchType.equals(ObjectTypes.OBJECT)) { + q = q.type(searchType.getClassDefinition()); + } + ObjectQuery query; if (SEARCH_SCOPE_ONE.equals(scope)) { - filters.add(OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL)); + query = q.isDirectChildOf(oid).build(); } else { - filters.add(OrgFilter.createOrg(oid, OrgFilter.Scope.SUBTREE)); + query = q.isChildOf(oid).build(); } - - query = ObjectQuery.createObjectQuery(AndFilter.createAnd(filters)); - if (LOGGER.isTraceEnabled()) { LOGGER.trace("Searching members of org {} with query:\n{}", oid, query.debugDump()); } - - if (searchType.equals(ObjectType.COMPLEX_TYPE)) { - return query; - } - - return ObjectQuery.createObjectQuery(TypeFilter.createType(searchType, query.getFilter())); - + return query; } private ObjectQuery createQueryForMemberAction(QueryScope scope, QName orgRelation, boolean isFocus) { @@ -639,9 +623,9 @@ private boolean satisfyConstraints(boolean isFocus, Class private ObjectQuery createQueryForAll(QueryScope scope, boolean isFocus, QName relation) { OrgType org = getModelObject(); - - return ObjectQuery.createObjectQuery(OrgFilter.createOrg(org.getOid(), getScope(scope))); - + return QueryBuilder.queryFor(ObjectType.class, getPageBase().getPrismContext()) + .isInScopeOf(org.getOid(), getScope(scope)) + .build(); } private Scope getScope(QueryScope queryScope) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java index 9f04f8ef2e1..302223336e8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.List; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.wicket.Component; import org.apache.wicket.RestartResponseException; import org.apache.wicket.extensions.markup.html.repeater.util.SortableTreeProvider; @@ -97,10 +98,10 @@ public Iterator> getChildren(SelectableBean> iterator = null; - OrgFilter orgFilter = OrgFilter.createOrg(node.getValue().getOid(), OrgFilter.Scope.ONE_LEVEL); - ObjectQuery query = ObjectQuery.createObjectQuery(orgFilter); - query.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, getPageBase().getPrismContext()) + .isDirectChildOf(node.getValue().getOid()) + .asc(ObjectType.F_NAME) + .build(); OperationResult result = new OperationResult(LOAD_ORG_UNITS); try { // Collection> options = WebModelServiceUtils.createOptionsForParentOrgRefs(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java index cac93607e80..5a761555508 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java @@ -29,6 +29,7 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrgFilter; import com.evolveum.midpoint.prism.query.OrgFilter.Scope; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; @@ -425,12 +426,14 @@ public void yesPerformed(AjaxRequestTarget target) { } private boolean hasChildren(SelectableBean orgToDelete) { - OrgFilter childrenFilter = OrgFilter.createOrg(orgToDelete.getValue().getOid(), Scope.SUBTREE); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, getPageBase().getPrismContext()) + .isChildOf(orgToDelete.getValue().getOid()) + .build(); Task task = getPageBase().createSimpleTask(OPERATION_COUNT_CHILDREN); OperationResult result = new OperationResult(OPERATION_COUNT_CHILDREN); try { int count = getPageBase().getModelService().countObjects(ObjectType.class, - ObjectQuery.createObjectQuery(childrenFilter), null, task, result); + query, null, task, result); return (count > 0); } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | ConfigurationException | CommunicationException e) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/forgetpassword/PageForgetPassword.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/forgetpassword/PageForgetPassword.java index 7aa5c6114db..2b71201f5f1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/forgetpassword/PageForgetPassword.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/forgetpassword/PageForgetPassword.java @@ -18,6 +18,7 @@ import java.util.Collection; import java.util.List; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.wicket.RestartResponseException; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.RequiredTextField; @@ -151,12 +152,12 @@ private UserType getUser(String email, String username) { Task task = createAnonymousTask(OPERATION_LOAD_USER); OperationResult result = task.getResult(); - - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd( - EqualFilter.createEqual(UserType.F_NAME, UserType.class,getPrismContext(), PolyStringOrigMatchingRule.NAME, username), - EqualFilter.createEqual(UserType.F_EMAIL_ADDRESS, UserType.class,getPrismContext(), PolyStringOrigMatchingRule.NAME, email))); - - + + ObjectQuery query = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_NAME).eqPoly(username).matchingNorm() + .and().item(UserType.F_EMAIL_ADDRESS).eq(email).matchingCaseIgnore() + .build(); + if (LOGGER.isTraceEnabled()) { LOGGER.trace("Searching for user with query:\n{}", query.debugDump(1)); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ExpressionUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ExpressionUtil.java index 8aede16122b..40c074ae6e8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ExpressionUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ExpressionUtil.java @@ -229,9 +229,9 @@ private static String serialize(JAXBElement element, PrismContext prismContex if (element.getValue() instanceof RawType) { RawType raw = (RawType) element.getValue(); RootXNode rootNode = new RootXNode(element.getName(), raw.serializeToXNode()); - xml = prismContext.serializeXNodeToString(rootNode, PrismContext.LANG_XML); + xml = prismContext.xmlSerializer().serialize(rootNode); } else { - xml = prismContext.serializeAtomicValue(element, PrismContext.LANG_XML); + xml = prismContext.xmlSerializer().serialize(element); } return WebXmlUtil.stripNamespaceDeclarations(xml); } @@ -245,7 +245,7 @@ public static void parseExpressionEvaluators(String xml, ExpressionType expressi if (xml != null && StringUtils.isNotBlank(xml)) { xml = WebXmlUtil.wrapInElement("expression", xml); LOGGER.info("Expression to serialize: {}", xml); - JAXBElement newElement = context.parseAnyValueAsJAXBElement(xml, PrismContext.LANG_XML); + JAXBElement newElement = context.parserFor(xml).xml().parseRealValueToJaxbElement(); expressionObject.getExpressionEvaluator().addAll(((ExpressionType) (newElement.getValue())).getExpressionEvaluator()); } } diff --git a/gui/admin-gui/src/test/resources/common/user-jack-repo.xml b/gui/admin-gui/src/test/resources/common/user-jack-repo.xml index e7b3f162c3b..f4920887da6 100644 --- a/gui/admin-gui/src/test/resources/common/user-jack-repo.xml +++ b/gui/admin-gui/src/test/resources/common/user-jack-repo.xml @@ -100,7 +100,7 @@ - + diff --git a/infra/common/pom.xml b/infra/common/pom.xml index d2578e63908..be166efcafe 100644 --- a/infra/common/pom.xml +++ b/infra/common/pom.xml @@ -59,6 +59,10 @@ commons-configuration commons-configuration + + commons-collections + commons-collections + xml-apis xml-apis diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java b/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java index a587d7ef714..b3fdcfa2e22 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java @@ -28,7 +28,7 @@ import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.parser.XNodeProcessor; +import com.evolveum.midpoint.prism.xnode.RootXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.JAXBUtil; @@ -95,8 +95,7 @@ public static Item pars String contextDescription, PrismContext prismContext) throws SchemaException { Item output = null; - XNodeProcessor xnodeProcessor = prismContext.getXnodeProcessor(); - + for (Object valueElement: valueElements) { if (!(valueElement instanceof JAXBElement)) { throw new SchemaException("Literal expression cannot handle element "+valueElement+" "+valueElement.getClass().getName()+" in " @@ -131,11 +130,10 @@ public static List> elements = new ArrayList<>(item.size()); for (PrismValue value : item.getValues()) { - XNode xnode = xnodeProcessor.serializeItemValue(value); - RawType rawType = new RawType(xnode, item.getPrismContext()); + RootXNode xnode = item.getPrismContext().xnodeSerializer().serialize(value); + RawType rawType = new RawType(xnode.getSubnode(), item.getPrismContext()); JAXBElement jaxbElement = new JAXBElement<>(SchemaConstants.C_VALUE, RawType.class, rawType); elements.add(jaxbElement); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/SynchronizationUtils.java b/infra/common/src/main/java/com/evolveum/midpoint/common/SynchronizationUtils.java index 2a810f9dee0..13187f2ec21 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/SynchronizationUtils.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/SynchronizationUtils.java @@ -22,6 +22,7 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.util.QNameUtil; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; @@ -67,7 +68,7 @@ public static boolean isPolicyApplicable(QName objectClass, ShadowKindType kind, String policyIntent = synchronizationPolicy.getIntent(); ShadowKindType policyKind = synchronizationPolicy.getKind(); ObjectClassComplexTypeDefinition policyObjectClass = null; - RefinedResourceSchema schema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema schema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (schema == null) { throw new SchemaException("No schema defined in resource. Possible configuration problem?"); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java b/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java index cecb1119a44..84e5ed6dc7a 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/Utils.java @@ -17,8 +17,10 @@ package com.evolveum.midpoint.common; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.Nullable; import org.w3c.dom.Element; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -41,7 +43,7 @@ public static String getPropertyName(String name) { } public static Element fillPropertyReference(String resolve) { - com.evolveum.midpoint.prism.parser.XPathHolder xpath = new com.evolveum.midpoint.prism.parser.XPathHolder( + XPathHolder xpath = new XPathHolder( Utils.getPropertyName(resolve)); return xpath.toElement(SchemaConstants.NS_C, "property"); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java index d80e312e8e7..8006644fdab 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java @@ -15,31 +15,9 @@ */ package com.evolveum.midpoint.common.refinery; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.xml.namespace.QName; +import org.jetbrains.annotations.NotNull; -import com.evolveum.midpoint.common.ResourceObjectPattern; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.schema.util.SchemaDebugUtil; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceActivationDefinitionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceBidirectionalMappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; -import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType; +import java.util.Collection; /** * Used to represent combined definition of structural and auxiliary object classes. @@ -47,392 +25,11 @@ * @author semancik * */ -public class CompositeRefinedObjectClassDefinition extends RefinedObjectClassDefinition { - - private RefinedObjectClassDefinition structuralObjectClassDefinition; - private Collection auxiliaryObjectClassDefinitions; - - public CompositeRefinedObjectClassDefinition(RefinedObjectClassDefinition structuralObjectClassDefinition, Collection auxiliaryObjectClassDefinitions) { - super(structuralObjectClassDefinition.getTypeName(), structuralObjectClassDefinition.getPrismContext()); - this.structuralObjectClassDefinition = structuralObjectClassDefinition; - this.auxiliaryObjectClassDefinitions = auxiliaryObjectClassDefinitions; - } - - public RefinedObjectClassDefinition getStructuralObjectClassDefinition() { - return structuralObjectClassDefinition; - } - - public Collection getAuxiliaryObjectClassDefinitions() { - return auxiliaryObjectClassDefinitions; - } - - public Class getCompileTimeClass() { - return structuralObjectClassDefinition.getCompileTimeClass(); - } - - public boolean isContainerMarker() { - return structuralObjectClassDefinition.isContainerMarker(); - } - - public boolean isPrimaryIdentifier(QName attrName) { - return structuralObjectClassDefinition.isPrimaryIdentifier(attrName); - } - - public boolean isObjectMarker() { - return structuralObjectClassDefinition.isObjectMarker(); - } - - public boolean isIgnored() { - return structuralObjectClassDefinition.isIgnored(); - } - - public boolean isEmphasized() { - return structuralObjectClassDefinition.isEmphasized(); - } - - public boolean isAbstract() { - return structuralObjectClassDefinition.isAbstract(); - } - - public QName getSuperType() { - return structuralObjectClassDefinition.getSuperType(); - } - - public boolean isSecondaryIdentifier(QName attrName) { - return structuralObjectClassDefinition.isSecondaryIdentifier(attrName); - } - - public boolean isDeprecated() { - return structuralObjectClassDefinition.isDeprecated(); - } - - public boolean isInherited() { - return structuralObjectClassDefinition.isInherited(); - } - - public Integer getDisplayOrder() { - return structuralObjectClassDefinition.getDisplayOrder(); - } - - public ResourceAttributeDefinition getDescriptionAttribute() { - return structuralObjectClassDefinition.getDescriptionAttribute(); - } - - public String getHelp() { - return structuralObjectClassDefinition.getHelp(); - } - - public RefinedAttributeDefinition getNamingAttribute() { - return structuralObjectClassDefinition.getNamingAttribute(); - } - - public QName getTypeName() { - return structuralObjectClassDefinition.getTypeName(); - } - - public String getNativeObjectClass() { - return structuralObjectClassDefinition.getNativeObjectClass(); - } - - public String getDocumentation() { - return structuralObjectClassDefinition.getDocumentation(); - } - - public boolean isDefaultInAKind() { - return structuralObjectClassDefinition.isDefaultInAKind(); - } - - public String getDocumentationPreview() { - return structuralObjectClassDefinition.getDocumentationPreview(); - } - - public String getIntent() { - return structuralObjectClassDefinition.getIntent(); - } - - public ShadowKindType getKind() { - return structuralObjectClassDefinition.getKind(); - } - - public boolean isRuntimeSchema() { - return structuralObjectClassDefinition.isRuntimeSchema(); - } - - public RefinedAttributeDefinition getDisplayNameAttribute() { - return structuralObjectClassDefinition.getDisplayNameAttribute(); - } - - @Override - public Collection> getPrimaryIdentifiers() { - return structuralObjectClassDefinition.getPrimaryIdentifiers(); - } - - @Override - public Collection> getSecondaryIdentifiers() { - return structuralObjectClassDefinition.getSecondaryIdentifiers(); - } - - @Override - public Collection> getAllIdentifiers() { - return structuralObjectClassDefinition.getAllIdentifiers(); - } - - public boolean isAuxiliary() { - return structuralObjectClassDefinition.isAuxiliary(); - } - - public Collection getAssociations() { - return structuralObjectClassDefinition.getAssociations(); - } - - public Collection getAssociations(ShadowKindType kind) { - return structuralObjectClassDefinition.getAssociations(kind); - } - - public Collection getEntitlementAssociations() { - return structuralObjectClassDefinition.getEntitlementAssociations(); - } - - public Collection getNamesOfAssociations() { - return structuralObjectClassDefinition.getNamesOfAssociations(); - } - - public boolean isEmpty() { - return structuralObjectClassDefinition.isEmpty(); - } - - public Collection getProtectedObjectPatterns() { - return structuralObjectClassDefinition.getProtectedObjectPatterns(); - } - - public String getDocClassName() { - return structuralObjectClassDefinition.getDocClassName(); - } - - public String getDisplayName() { - return structuralObjectClassDefinition.getDisplayName(); - } - - public String getDescription() { - return structuralObjectClassDefinition.getDescription(); - } - - public boolean isDefault() { - return structuralObjectClassDefinition.isDefault(); - } - - public ResourceType getResourceType() { - return structuralObjectClassDefinition.getResourceType(); - } - - // Do NOT override getObjectDefinition(). It will work by itself. - // overriding it will just complicate things. - - public ObjectClassComplexTypeDefinition getObjectClassDefinition() { - return structuralObjectClassDefinition.getObjectClassDefinition(); - } - - public ResourceObjectReferenceType getBaseContext() { - return structuralObjectClassDefinition.getBaseContext(); - } - - public List getPasswordInbound() { - return structuralObjectClassDefinition.getPasswordInbound(); - } - - public MappingType getPasswordOutbound() { - return structuralObjectClassDefinition.getPasswordOutbound(); - } - - public AttributeFetchStrategyType getPasswordFetchStrategy() { - return structuralObjectClassDefinition.getPasswordFetchStrategy(); - } - - public ObjectReferenceType getPasswordPolicy() { - return structuralObjectClassDefinition.getPasswordPolicy(); - } - - public ResourceActivationDefinitionType getActivationSchemaHandling() { - return structuralObjectClassDefinition.getActivationSchemaHandling(); - } - - public ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName) { - return structuralObjectClassDefinition.getActivationBidirectionalMappingType(propertyName); - } - - public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) { - return structuralObjectClassDefinition.getActivationFetchStrategy(propertyName); - } - - public boolean matches(ShadowType shadowType) { - return structuralObjectClassDefinition.matches(shadowType); - } - - public T getEffectiveCapability(Class capabilityClass) { - return structuralObjectClassDefinition.getEffectiveCapability(capabilityClass); - } - - public PagedSearchCapabilityType getPagedSearches() { - return structuralObjectClassDefinition.getPagedSearches(); - } - - public boolean isPagedSearchEnabled() { - return structuralObjectClassDefinition.isPagedSearchEnabled(); - } - - public boolean isObjectCountingEnabled() { - return structuralObjectClassDefinition.isObjectCountingEnabled(); - } - - @Override - public T findItemDefinition(QName name, Class clazz, boolean caseInsensitive) { - T itemDef = structuralObjectClassDefinition.findItemDefinition(name, clazz, caseInsensitive); - if (itemDef == null && auxiliaryObjectClassDefinitions != null) { - for(RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { - itemDef = auxiliaryObjectClassDefinition.findItemDefinition(name, clazz, caseInsensitive); - if (itemDef != null) { - break; - } - } - } - return itemDef; - } - - - @Override - public Collection> getAttributeDefinitions() { - if (auxiliaryObjectClassDefinitions == null || auxiliaryObjectClassDefinitions.isEmpty()) { - return structuralObjectClassDefinition.getAttributeDefinitions(); - } - Collection> defs = new ArrayList<>(); - defs.addAll((Collection)structuralObjectClassDefinition.getAttributeDefinitions()); - for(RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { - for (RefinedAttributeDefinition auxRAttrDef: auxiliaryObjectClassDefinition.getAttributeDefinitions()) { - boolean add = true; - for (RefinedAttributeDefinition def: defs) { - if (def.getName().equals(auxRAttrDef.getName())) { - add = false; - break; - } - } - if (add) { - ((Collection)defs).add(auxRAttrDef); - } - } - } - return defs; - } - - @Override - public PrismContext getPrismContext() { - return structuralObjectClassDefinition.getPrismContext(); - } - - @Override - public CompositeRefinedObjectClassDefinition clone() { - RefinedObjectClassDefinition structuralObjectClassDefinitionClone = structuralObjectClassDefinition.clone(); - Collection auxiliaryObjectClassDefinitionsClone = null; - if (this.auxiliaryObjectClassDefinitions != null) { - auxiliaryObjectClassDefinitionsClone = new ArrayList<>(this.auxiliaryObjectClassDefinitions.size()); - for(RefinedObjectClassDefinition auxiliaryObjectClassDefinition: this.auxiliaryObjectClassDefinitions) { - auxiliaryObjectClassDefinitionsClone.add(auxiliaryObjectClassDefinition.clone()); - } - } - return new CompositeRefinedObjectClassDefinition(structuralObjectClassDefinitionClone, auxiliaryObjectClassDefinitionsClone); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result - + ((auxiliaryObjectClassDefinitions == null) ? 0 : auxiliaryObjectClassDefinitions.hashCode()); - result = prime * result - + ((structuralObjectClassDefinition == null) ? 0 : structuralObjectClassDefinition.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - CompositeRefinedObjectClassDefinition other = (CompositeRefinedObjectClassDefinition) obj; - if (auxiliaryObjectClassDefinitions == null) { - if (other.auxiliaryObjectClassDefinitions != null) { - return false; - } - } else if (!auxiliaryObjectClassDefinitions.equals(other.auxiliaryObjectClassDefinitions)) { - return false; - } - if (structuralObjectClassDefinition == null) { - if (other.structuralObjectClassDefinition != null) { - return false; - } - } else if (!structuralObjectClassDefinition.equals(other.structuralObjectClassDefinition)) { - return false; - } - return true; - } +public interface CompositeRefinedObjectClassDefinition extends RefinedObjectClassDefinition { - @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - return debugDump(indent, null); - } + RefinedObjectClassDefinition getStructuralObjectClassDefinition(); - protected String debugDump(int indent, LayerType layer) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < indent; i++) { - sb.append(INDENT_STRING); - } - sb.append(getDebugDumpClassName()).append(": "); - sb.append(SchemaDebugUtil.prettyPrint(getTypeName())); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "structural", structuralObjectClassDefinition, indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "auxiliary", auxiliaryObjectClassDefinitions, indent + 1); - return sb.toString(); - } - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "crOCD"; - } + @NotNull + Collection getAuxiliaryObjectClassDefinitions(); - public String getHumanReadableName() { - if (getDisplayName() != null) { - return getDisplayName(); - } else { - return getKind()+":"+getIntent(); - } - } - - @Override - public String toString() { - if (auxiliaryObjectClassDefinitions == null || auxiliaryObjectClassDefinitions.isEmpty()) { - return getDebugDumpClassName() + " ("+getTypeName()+")"; - } else { - StringBuilder sb = new StringBuilder(); - sb.append(getDebugDumpClassName()).append("(").append(getTypeName()); - for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { - sb.append("+").append(auxiliaryObjectClassDefinition.getTypeName()); - } - sb.append(")"); - return sb.toString(); - } - } } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java new file mode 100644 index 00000000000..6e9b8fec1b9 --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinitionImpl.java @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import com.evolveum.midpoint.common.ResourceObjectPattern; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinitionImpl; +import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; +import com.evolveum.midpoint.schema.util.SchemaDebugUtil; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Used to represent combined definition of structural and auxiliary object classes. + * + * @author semancik + * + */ +public class CompositeRefinedObjectClassDefinitionImpl implements CompositeRefinedObjectClassDefinition { + + @NotNull private final RefinedObjectClassDefinition structuralObjectClassDefinition; + @NotNull private final Collection auxiliaryObjectClassDefinitions; + + private PrismObjectDefinition objectDefinition; + + public CompositeRefinedObjectClassDefinitionImpl(@NotNull RefinedObjectClassDefinition structuralObjectClassDefinition, Collection auxiliaryObjectClassDefinitions) { + this.structuralObjectClassDefinition = structuralObjectClassDefinition; + if (auxiliaryObjectClassDefinitions != null) { + this.auxiliaryObjectClassDefinitions = auxiliaryObjectClassDefinitions; + } else { + this.auxiliaryObjectClassDefinitions = new ArrayList<>(); + } + } + + public RefinedObjectClassDefinition getStructuralObjectClassDefinition() { + return structuralObjectClassDefinition; + } + + @NotNull + @Override + public Collection getAuxiliaryObjectClassDefinitions() { + return auxiliaryObjectClassDefinitions; + } + + @Override + public PrismObjectDefinition getObjectDefinition() { + if (objectDefinition == null) { + objectDefinition = RefinedObjectClassDefinitionImpl.constructObjectDefinition(this); + } + return objectDefinition; + } + + @Override + public Class getCompileTimeClass() { + return structuralObjectClassDefinition.getCompileTimeClass(); + } + + @Override + public boolean isContainerMarker() { + return structuralObjectClassDefinition.isContainerMarker(); + } + + @Override + public boolean isPrimaryIdentifier(QName attrName) { + return structuralObjectClassDefinition.isPrimaryIdentifier(attrName); + } + + @Override + public boolean isObjectMarker() { + return structuralObjectClassDefinition.isObjectMarker(); + } + + @Override + public boolean isIgnored() { + return structuralObjectClassDefinition.isIgnored(); + } + + @Override + public boolean isEmphasized() { + return structuralObjectClassDefinition.isEmphasized(); + } + + @Override + public boolean isAbstract() { + return structuralObjectClassDefinition.isAbstract(); + } + + @Override + public QName getSuperType() { + return structuralObjectClassDefinition.getSuperType(); + } + + @Override + public boolean isSecondaryIdentifier(QName attrName) { + return structuralObjectClassDefinition.isSecondaryIdentifier(attrName); + } + + @Override + public boolean isDeprecated() { + return structuralObjectClassDefinition.isDeprecated(); + } + + @Override + public Integer getDisplayOrder() { + return structuralObjectClassDefinition.getDisplayOrder(); + } + + @Override + public RefinedAttributeDefinition getDescriptionAttribute() { + return structuralObjectClassDefinition.getDescriptionAttribute(); + } + + @Override + public RefinedAttributeDefinition getNamingAttribute() { + return structuralObjectClassDefinition.getNamingAttribute(); + } + + @Override + public String getHelp() { + return structuralObjectClassDefinition.getHelp(); + } + + @NotNull + @Override + public QName getTypeName() { + return structuralObjectClassDefinition.getTypeName(); + } + + @Override + public String getNativeObjectClass() { + return structuralObjectClassDefinition.getNativeObjectClass(); + } + + @Override + public String getDocumentation() { + return structuralObjectClassDefinition.getDocumentation(); + } + + @Override + public boolean isDefaultInAKind() { + return structuralObjectClassDefinition.isDefaultInAKind(); + } + + @Override + public String getDocumentationPreview() { + return structuralObjectClassDefinition.getDocumentationPreview(); + } + + @Override + public String getIntent() { + return structuralObjectClassDefinition.getIntent(); + } + + @Override + public ShadowKindType getKind() { + return structuralObjectClassDefinition.getKind(); + } + + @Override + public boolean isRuntimeSchema() { + return structuralObjectClassDefinition.isRuntimeSchema(); + } + + @Override + public RefinedAttributeDefinition getDisplayNameAttribute() { + return structuralObjectClassDefinition.getDisplayNameAttribute(); + } + + @NotNull + @Override + public Collection> getPrimaryIdentifiers() { + return structuralObjectClassDefinition.getPrimaryIdentifiers(); + } + + @NotNull + @Override + public Collection> getSecondaryIdentifiers() { + return structuralObjectClassDefinition.getSecondaryIdentifiers(); + } + + @Override + public Collection> getAllIdentifiers() { + return structuralObjectClassDefinition.getAllIdentifiers(); + } + + @Override + public boolean isAuxiliary() { + return structuralObjectClassDefinition.isAuxiliary(); + } + + // TODO - ok??? + @NotNull + @Override + public Collection getAssociationDefinitions() { + return structuralObjectClassDefinition.getAssociationDefinitions(); + } + + @Override + public Collection getAssociationDefinitions(ShadowKindType kind) { + return structuralObjectClassDefinition.getAssociationDefinitions(kind); + } + + @Override + public Collection getNamesOfAssociations() { + return structuralObjectClassDefinition.getNamesOfAssociations(); + } + + @Override + public boolean isEmpty() { + return structuralObjectClassDefinition.isEmpty() + && !auxiliaryObjectClassDefinitions.stream() + .filter(def -> def.isEmpty()) + .findAny().isPresent(); + } + + @Override + public Collection getProtectedObjectPatterns() { + return structuralObjectClassDefinition.getProtectedObjectPatterns(); + } + + @Override + public String getDisplayName() { + return structuralObjectClassDefinition.getDisplayName(); + } + + @Override + public String getDescription() { + return structuralObjectClassDefinition.getDescription(); + } + + @Override + public boolean isDefault() { + return structuralObjectClassDefinition.isDefault(); + } + + @Override + public ResourceType getResourceType() { + return structuralObjectClassDefinition.getResourceType(); + } + + @Override + public ObjectClassComplexTypeDefinition getObjectClassDefinition() { + return structuralObjectClassDefinition.getObjectClassDefinition(); + } + + @Override + public ResourceObjectReferenceType getBaseContext() { + return structuralObjectClassDefinition.getBaseContext(); + } + + @Override + public List getPasswordInbound() { + return structuralObjectClassDefinition.getPasswordInbound(); + } + + @Override + public MappingType getPasswordOutbound() { + return structuralObjectClassDefinition.getPasswordOutbound(); + } + + @Override + public AttributeFetchStrategyType getPasswordFetchStrategy() { + return structuralObjectClassDefinition.getPasswordFetchStrategy(); + } + + @Override + public ObjectReferenceType getPasswordPolicy() { + return structuralObjectClassDefinition.getPasswordPolicy(); + } + + @Override + public ResourceActivationDefinitionType getActivationSchemaHandling() { + return structuralObjectClassDefinition.getActivationSchemaHandling(); + } + + @Override + public ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName) { + return structuralObjectClassDefinition.getActivationBidirectionalMappingType(propertyName); + } + + @Override + public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) { + return structuralObjectClassDefinition.getActivationFetchStrategy(propertyName); + } + + @Override + public boolean matches(ShadowType shadowType) { + return structuralObjectClassDefinition.matches(shadowType); + } + + public T getEffectiveCapability(Class capabilityClass) { + return structuralObjectClassDefinition.getEffectiveCapability(capabilityClass); + } + + @Override + public PagedSearchCapabilityType getPagedSearches() { + return structuralObjectClassDefinition.getPagedSearches(); + } + + @Override + public boolean isPagedSearchEnabled() { + return structuralObjectClassDefinition.isPagedSearchEnabled(); + } + + @Override + public boolean isObjectCountingEnabled() { + return structuralObjectClassDefinition.isObjectCountingEnabled(); + } + + @Override + public T findItemDefinition(@NotNull QName name, @NotNull Class clazz, boolean caseInsensitive) { + T itemDef = structuralObjectClassDefinition.findItemDefinition(name, clazz, caseInsensitive); + if (itemDef == null) { + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + itemDef = auxiliaryObjectClassDefinition.findItemDefinition(name, clazz, caseInsensitive); + if (itemDef != null) { + break; + } + } + } + return itemDef; + } + + @Override + public ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, + @NotNull Class clazz) { + throw new UnsupportedOperationException(); // implement if needed + } + + @NotNull + @Override + public Collection> getAttributeDefinitions() { + if (auxiliaryObjectClassDefinitions.isEmpty()) { + return structuralObjectClassDefinition.getAttributeDefinitions(); + } + Collection> defs = new ArrayList<>(); + defs.addAll((Collection)structuralObjectClassDefinition.getAttributeDefinitions()); + for(RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + for (RefinedAttributeDefinition auxRAttrDef: auxiliaryObjectClassDefinition.getAttributeDefinitions()) { + boolean add = true; + for (RefinedAttributeDefinition def: defs) { + if (def.getName().equals(auxRAttrDef.getName())) { + add = false; + break; + } + } + if (add) { + ((Collection)defs).add(auxRAttrDef); + } + } + } + return defs; + } + + @Override + public PrismContext getPrismContext() { + return structuralObjectClassDefinition.getPrismContext(); + } + + @Override + public void revive(PrismContext prismContext) { + structuralObjectClassDefinition.revive(prismContext); + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : auxiliaryObjectClassDefinitions) { + auxiliaryObjectClassDefinition.revive(prismContext); + } + } + + @NotNull + @Override + public List getDefinitions() { + return (List) getAttributeDefinitions(); + } + + @Override + public QName getExtensionForType() { + return structuralObjectClassDefinition.getExtensionForType(); + } + + @Override + public boolean isXsdAnyMarker() { + return structuralObjectClassDefinition.isXsdAnyMarker(); + } + + @Override + public String getDefaultNamespace() { + return structuralObjectClassDefinition.getDefaultNamespace(); + } + + @NotNull + @Override + public List getIgnoredNamespaces() { + return structuralObjectClassDefinition.getIgnoredNamespaces(); + } + + @Override + public LayerRefinedObjectClassDefinition forLayer(@NotNull LayerType layerType) { + return LayerRefinedObjectClassDefinitionImpl.wrap(this, layerType); + } + + @SuppressWarnings("unchecked") + @Override + public RefinedAttributeDefinition findAttributeDefinition(QName elementQName, boolean caseInsensitive) { + return findItemDefinition(elementQName, RefinedAttributeDefinition.class, caseInsensitive); + } + + @Override + public RefinedAttributeDefinition findAttributeDefinition(@NotNull QName name) { + return findAttributeDefinition(name, false); + } + + public RefinedAssociationDefinition findAssociationDefinition(QName name) { + for (RefinedAssociationDefinition assocType: getAssociationDefinitions()) { + if (QNameUtil.match(assocType.getName(), name)) { + return assocType; + } + } + return null; + } + + public Collection getEntitlementAssociationDefinitions() { + return getAssociationDefinitions(ShadowKindType.ENTITLEMENT); + } + + public RefinedAssociationDefinition findEntitlementAssociationDefinition(QName name) { + for (RefinedAssociationDefinition assocType: getEntitlementAssociationDefinitions()) { + if (QNameUtil.match(assocType.getName(), name)) { + return assocType; + } + } + return null; + } + + @Override + public Collection getNamesOfAssociationsWithOutboundExpressions() { + return getAssociationDefinitions().stream() + .filter(assocDef -> assocDef.getOutboundMappingType() != null) + .map(a -> a.getName()) + .collect(Collectors.toCollection(HashSet::new)); + } + + @Override + public boolean hasAuxiliaryObjectClass(QName expectedObjectClassName) { + if (structuralObjectClassDefinition.hasAuxiliaryObjectClass(expectedObjectClassName)) { + return true; + } + return auxiliaryObjectClassDefinitions.stream().anyMatch( + def -> QNameUtil.match(expectedObjectClassName, def.getTypeName())); + } + + @Override + public ResourceAttributeContainer instantiate(QName elementName) { + return ObjectClassComplexTypeDefinitionImpl.instantiate(elementName, this); + } + + @Override + public ID findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + throw new UnsupportedOperationException("TODO implement if needed"); + } + + @Override + public void merge(ComplexTypeDefinition otherComplexTypeDef) { + throw new UnsupportedOperationException("TODO implement if needed"); + } + + @Override + public String getResourceNamespace() { + return structuralObjectClassDefinition.getResourceNamespace(); + } + + // TODO + @Override + public Class getTypeClassIfKnown() { + return null; + } + + // TODO + @Override + public Class getTypeClass() { + return null; + } + + @Override + public boolean containsAttributeDefinition(ItemPathType pathType) { + return getRefinedObjectClassDefinitionsStream() + .filter(def -> containsAttributeDefinition(pathType)) + .findAny() + .isPresent(); + } + + private Stream getRefinedObjectClassDefinitionsStream() { + return Stream.concat(Stream.of(structuralObjectClassDefinition), auxiliaryObjectClassDefinitions.stream()); + } + + @Override + public boolean containsAttributeDefinition(QName attributeName) { + return getRefinedObjectClassDefinitionsStream() + .filter(def -> containsAttributeDefinition(attributeName)) + .findAny() + .isPresent(); + } + + @Override + public ObjectQuery createShadowSearchQuery(String resourceOid) throws SchemaException { + return structuralObjectClassDefinition.createShadowSearchQuery(resourceOid); + } + + @Override + public PrismObject createBlankShadow(RefinedObjectClassDefinition definition) { + return structuralObjectClassDefinition.createBlankShadow(definition); + } + + @Override + public ResourceShadowDiscriminator getShadowDiscriminator() { + return structuralObjectClassDefinition.getShadowDiscriminator(); + } + + @Override + public Collection getNamesOfAttributesWithOutboundExpressions() { + Set names = new HashSet<>(); + getRefinedObjectClassDefinitionsStream().forEach( + def -> names.addAll(def.getNamesOfAttributesWithOutboundExpressions()) + ); + return names; + } + + @Override + public Collection getNamesOfAttributesWithInboundExpressions() { + Set names = new HashSet<>(); + getRefinedObjectClassDefinitionsStream().forEach( + def -> names.addAll(def.getNamesOfAttributesWithInboundExpressions()) + ); + return names; + } + + @Override + public ResourcePasswordDefinitionType getPasswordDefinition() { // TODO what if there is a conflict? + return getRefinedObjectClassDefinitionsStream() + .map(def -> def.getPasswordDefinition()) + .findFirst().orElse(null); + } + + @NotNull + @Override + public CompositeRefinedObjectClassDefinitionImpl clone() { + RefinedObjectClassDefinition structuralObjectClassDefinitionClone = structuralObjectClassDefinition.clone(); + Collection auxiliaryObjectClassDefinitionsClone = null; + auxiliaryObjectClassDefinitionsClone = new ArrayList<>(this.auxiliaryObjectClassDefinitions.size()); + for(RefinedObjectClassDefinition auxiliaryObjectClassDefinition: this.auxiliaryObjectClassDefinitions) { + auxiliaryObjectClassDefinitionsClone.add(auxiliaryObjectClassDefinition.clone()); + } + return new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinitionClone, auxiliaryObjectClassDefinitionsClone); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + + ((auxiliaryObjectClassDefinitions == null) ? 0 : auxiliaryObjectClassDefinitions.hashCode()); + result = prime * result + + ((structuralObjectClassDefinition == null) ? 0 : structuralObjectClassDefinition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } +// if (!super.equals(obj)) { +// return false; +// } + if (getClass() != obj.getClass()) { + return false; + } + CompositeRefinedObjectClassDefinitionImpl other = (CompositeRefinedObjectClassDefinitionImpl) obj; + if (!auxiliaryObjectClassDefinitions.equals(other.auxiliaryObjectClassDefinitions)) { + return false; + } + if (!structuralObjectClassDefinition.equals(other.structuralObjectClassDefinition)) { + return false; + } + return true; + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + return debugDump(indent, null); + } + + protected String debugDump(int indent, LayerType layer) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(INDENT_STRING); + } + sb.append(getDebugDumpClassName()).append(": "); + sb.append(SchemaDebugUtil.prettyPrint(getTypeName())); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "structural", structuralObjectClassDefinition, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "auxiliary", auxiliaryObjectClassDefinitions, indent + 1); + return sb.toString(); + } + + /** + * Return a human readable name of this class suitable for logs. + */ +// @Override + public String getDebugDumpClassName() { + return "crOCD"; + } + + public String getHumanReadableName() { + if (getDisplayName() != null) { + return getDisplayName(); + } else { + return getKind()+":"+getIntent(); + } + } + + @Override + public String toString() { + if (auxiliaryObjectClassDefinitions.isEmpty()) { + return getDebugDumpClassName() + " ("+getTypeName()+")"; + } else { + StringBuilder sb = new StringBuilder(); + sb.append(getDebugDumpClassName()).append("(").append(getTypeName()); + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + sb.append("+").append(auxiliaryObjectClassDefinition.getTypeName()); + } + sb.append(")"); + return sb.toString(); + } + } + + @NotNull + @Override + public CompositeRefinedObjectClassDefinitionImpl deepClone(Map ctdMap) { + RefinedObjectClassDefinition structuralClone = structuralObjectClassDefinition.deepClone(ctdMap); + List auxiliaryClones = auxiliaryObjectClassDefinitions.stream() + .map(def -> def.deepClone(ctdMap)) + .collect(Collectors.toCollection(ArrayList::new)); + return new CompositeRefinedObjectClassDefinitionImpl(structuralClone, auxiliaryClones); + } + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinition.java index 8ccbc522759..05e88a41b0b 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinition.java @@ -13,549 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.common.refinery; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import javax.xml.namespace.QName; +package com.evolveum.midpoint.common.refinery; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.delta.PropertyDelta; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.DisplayableValue; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; /** - * @author semancik - * + * @author mederly */ -public class LayerRefinedAttributeDefinition extends RefinedAttributeDefinition { - - private RefinedAttributeDefinition refinedAttributeDefinition; - private LayerType layer; - private Boolean overrideCanRead = null; - private Boolean overrideCanAdd = null; - private Boolean overrideCanModify = null; - - private LayerRefinedAttributeDefinition(RefinedAttributeDefinition refinedAttributeDefinition, LayerType layer) { - super(refinedAttributeDefinition, refinedAttributeDefinition.getPrismContext()); - this.refinedAttributeDefinition = refinedAttributeDefinition; - this.layer = layer; - } - - static LayerRefinedAttributeDefinition wrap(RefinedAttributeDefinition rAttrDef, LayerType layer) { - if (rAttrDef == null) { - return null; - } - return new LayerRefinedAttributeDefinition(rAttrDef, layer); - } - - static List> wrapCollection( - Collection defs, LayerType layer) { - List outs = new ArrayList>(defs.size()); - for (ItemDefinition itemDef: defs) { - if (itemDef instanceof LayerRefinedAttributeDefinition) { - outs.add(itemDef); - } else if (itemDef instanceof RefinedAttributeDefinition) { - outs.add(wrap((RefinedAttributeDefinition)itemDef, layer)); - } else { - throw new IllegalStateException("Unexpected type of attribute definition: " + itemDef); - } - } - return outs; - } - - public LayerType getLayer() { - return layer; - } - - @Override - public ResourceAttribute instantiate() { - return refinedAttributeDefinition.instantiate(); - } - - @Override - public ResourceAttribute instantiate(QName name) { - return refinedAttributeDefinition.instantiate(name); - } - - @Override - public boolean isIdentifier(ResourceAttributeContainerDefinition objectDefinition) { - return refinedAttributeDefinition.isIdentifier(objectDefinition); - } - - @Override - public boolean isIdentifier(ObjectClassComplexTypeDefinition objectDefinition) { - return refinedAttributeDefinition.isIdentifier(objectDefinition); - } - - @Override - public void setNativeAttributeName(String nativeAttributeName) { - refinedAttributeDefinition.setNativeAttributeName(nativeAttributeName); - } - - @Override - public boolean isSecondaryIdentifier(ObjectClassComplexTypeDefinition objectDefinition) { - return refinedAttributeDefinition.isSecondaryIdentifier(objectDefinition); - } - - @Override - public boolean isTolerant() { - return refinedAttributeDefinition.isTolerant(); - } - - @Override - public void setTolerant(boolean tolerant) { - refinedAttributeDefinition.setTolerant(tolerant); - } - - public Boolean getOverrideCanRead() { - return overrideCanRead; - } - - public void setOverrideCanRead(Boolean overrideCanRead) { - this.overrideCanRead = overrideCanRead; - } - - public Boolean getOverrideCanAdd() { - return overrideCanAdd; - } - - public void setOverrideCanAdd(Boolean overrideCanAdd) { - this.overrideCanAdd = overrideCanAdd; - } - - public Boolean getOverrideCanModify() { - return overrideCanModify; - } - - public void setOverrideCanModify(Boolean overrideCanModify) { - this.overrideCanModify = overrideCanModify; - } - - @Override - public boolean canAdd() { - if (overrideCanAdd != null) { - return overrideCanAdd; - } - return refinedAttributeDefinition.canAdd(layer); - } - - @Override - public boolean canAdd(LayerType layer) { - return refinedAttributeDefinition.canAdd(layer); - } - - @Override - public boolean canRead() { - if (overrideCanRead != null) { - return overrideCanRead; - } - return refinedAttributeDefinition.canRead(layer); - } - - @Override - public boolean canRead(LayerType layer) { - return refinedAttributeDefinition.canRead(layer); - } - - @Override - public boolean canModify() { - if (overrideCanModify != null) { - return overrideCanModify; - } - return refinedAttributeDefinition.canModify(layer); - } - - @Override - public void setName(QName name) { - refinedAttributeDefinition.setName(name); - } - - @Override - public boolean canModify(LayerType layer) { - return refinedAttributeDefinition.canModify(layer); - } - - @Override - public void setReadOnly() { - refinedAttributeDefinition.setReadOnly(); - } - - @Override - public void setTypeName(QName typeName) { - refinedAttributeDefinition.setTypeName(typeName); - } - - @Override - public QName getValueType() { - return refinedAttributeDefinition.getValueType(); - } - - @Override - public String getNamespace() { - return refinedAttributeDefinition.getNamespace(); - } - - @Override - public Boolean isIndexed() { - return refinedAttributeDefinition.isIndexed(); - } - - @Override - public void setMinOccurs(int minOccurs) { - refinedAttributeDefinition.setMinOccurs(minOccurs); - } - - @Override - public void setMaxOccurs(int maxOccurs) { - refinedAttributeDefinition.setMaxOccurs(maxOccurs); - } - - @Override - public void setCanRead(boolean read) { - refinedAttributeDefinition.setCanRead(read); - } - - @Override - public void setCanModify(boolean update) { - refinedAttributeDefinition.setCanModify(update); - } - - @Override - public void setIndexed(Boolean indexed) { - refinedAttributeDefinition.setIndexed(indexed); - } - - @Override - public Integer getDisplayOrder() { - return refinedAttributeDefinition.getDisplayOrder(); - } - - @Override - public boolean isSingleValue() { - return refinedAttributeDefinition.isSingleValue(layer); - } - - @Override - public void setCanAdd(boolean create) { - refinedAttributeDefinition.setCanAdd(create); - } - - @Override - public PropertyDelta createEmptyDelta(ItemPath path) { - return refinedAttributeDefinition.createEmptyDelta(path); - } - - @Override - public boolean isMultiValue() { - return refinedAttributeDefinition.isMultiValue(layer); - } - - @Override - public boolean isIgnored() { - return refinedAttributeDefinition.isIgnored(layer); - } - - @Override - public boolean isIgnored(LayerType layer) { - return refinedAttributeDefinition.isIgnored(layer); - } - - @Override - public void setDisplayOrder(Integer displayOrder) { - refinedAttributeDefinition.setDisplayOrder(displayOrder); - } - - @Override - public boolean isMandatory() { - return refinedAttributeDefinition.isMandatory(layer); - } - - @Override - public void setIgnored(boolean ignored) { - refinedAttributeDefinition.setIgnored(ignored); - } - - @Override - public boolean isOptional() { - return refinedAttributeDefinition.isOptional(layer); - } - - @Override - public void setHelp(String help) { - refinedAttributeDefinition.setHelp(help); - } - - @Override - public String getDisplayName() { - return refinedAttributeDefinition.getDisplayName(); - } - - @Override - public boolean isDynamic() { - return refinedAttributeDefinition.isDynamic(); - } - - @Override - public void setDisplayName(String displayName) { - refinedAttributeDefinition.setDisplayName(displayName); - } - - @Override - public String getDescription() { - return refinedAttributeDefinition.getDescription(); - } - - @Override - public PrismContext getPrismContext() { - return refinedAttributeDefinition.getPrismContext(); - } - - @Override - public void setDescription(String description) { - refinedAttributeDefinition.setDescription(description); - } - - @Override - public Class getTypeClass() { - return refinedAttributeDefinition.getTypeClass(); - } - - @Override - public ResourceAttributeDefinition getAttributeDefinition() { - return refinedAttributeDefinition.getAttributeDefinition(); - } - - @Override - public void setAttributeDefinition(ResourceAttributeDefinition attributeDefinition) { - refinedAttributeDefinition.setAttributeDefinition(attributeDefinition); - } - - @Override - public void setDynamic(boolean dynamic) { - refinedAttributeDefinition.setDynamic(dynamic); - } - - @Override - public boolean isValidFor(QName elementQName, Class clazz) { - return isValidFor(elementQName, clazz, false); - } - - @Override - public boolean isValidFor(QName elementQName, Class clazz, boolean caseInsensitive) { - return refinedAttributeDefinition.isValidFor(elementQName, clazz, caseInsensitive); - } - - public Boolean getReturnedByDefault() { - return refinedAttributeDefinition.getReturnedByDefault(); - } - - public boolean isAbstract() { - return refinedAttributeDefinition.isAbstract(); - } - - public boolean isDeprecated() { - return refinedAttributeDefinition.isDeprecated(); - } - - public boolean isOperational() { - return refinedAttributeDefinition.isOperational(); - } - - public String getDocumentation() { - return refinedAttributeDefinition.getDocumentation(); - } - - public String getDocumentationPreview() { - return refinedAttributeDefinition.getDocumentationPreview(); - } - - public boolean isRuntimeSchema() { - return refinedAttributeDefinition.isRuntimeSchema(); - } - - public boolean isReturnedByDefault() { - return refinedAttributeDefinition.isReturnedByDefault(); - } - - public String getDocClassName() { - return refinedAttributeDefinition.getDocClassName(); - } - - public boolean isExlusiveStrong() { - return refinedAttributeDefinition.isExlusiveStrong(); - } - - public boolean isSecondaryIdentifier() { - return refinedAttributeDefinition.isSecondaryIdentifier(); - } - - public boolean isInherited() { - return refinedAttributeDefinition.isInherited(); - } - - public boolean isVolatilityTrigger() { - return refinedAttributeDefinition.isVolatilityTrigger(); - } - - public boolean isDisplayNameAttribute() { - return refinedAttributeDefinition.isDisplayNameAttribute(); - } - - public AttributeFetchStrategyType getFetchStrategy() { - return refinedAttributeDefinition.getFetchStrategy(); - } - - public List getTolerantValuePattern() { - return refinedAttributeDefinition.getTolerantValuePattern(); - } - - public List getIntolerantValuePattern() { - return refinedAttributeDefinition.getIntolerantValuePattern(); - } - - @Override - public MappingType getOutboundMappingType() { - return refinedAttributeDefinition.getOutboundMappingType(); - } - - @Override - public void setOutboundMappingType(MappingType outboundMappingType) { - refinedAttributeDefinition.setOutboundMappingType(outboundMappingType); - } - - @Override - public boolean hasOutboundMapping() { - return refinedAttributeDefinition.hasOutboundMapping(); - } - - @Override - public List getInboundMappingTypes() { - return refinedAttributeDefinition.getInboundMappingTypes(); - } - - @Override - public void setInboundMappingTypes(List inboundAssignmentTypes) { - refinedAttributeDefinition.setInboundMappingTypes(inboundAssignmentTypes); - } - - @Override - public QName getName() { - return refinedAttributeDefinition.getName(); - } - - @Override - public QName getTypeName() { - return refinedAttributeDefinition.getTypeName(); - } - - @Override - public String getNativeAttributeName() { - return refinedAttributeDefinition.getNativeAttributeName(); - } - - @Override - public Collection> getAllowedValues() { - return refinedAttributeDefinition.getAllowedValues(); - } - - @Override - public int getMaxOccurs() { - return refinedAttributeDefinition.getMaxOccurs(layer); - } - - @Override - public int getMaxOccurs(LayerType layer) { - return refinedAttributeDefinition.getMaxOccurs(layer); - } - - @Override - public int getMinOccurs() { - return refinedAttributeDefinition.getMinOccurs(layer); - } - - @Override - public int getMinOccurs(LayerType layer) { - return refinedAttributeDefinition.getMinOccurs(layer); - } - - @Override - public PropertyLimitations getLimitations(LayerType layer) { - return refinedAttributeDefinition.getLimitations(layer); - } - - public PropertyLimitations getLimitations() { - return refinedAttributeDefinition.getLimitations(layer); - } - - @Override - public String getHelp() { - return refinedAttributeDefinition.getHelp(); - } +public interface LayerRefinedAttributeDefinition extends RefinedAttributeDefinition { + LayerType getLayer(); - public QName getMatchingRuleQName() { - return refinedAttributeDefinition.getMatchingRuleQName(); - } + Boolean getOverrideCanRead(); - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((layer == null) ? 0 : layer.hashCode()); - result = prime * result + ((refinedAttributeDefinition == null) ? 0 : refinedAttributeDefinition.hashCode()); - return result; - } + Boolean getOverrideCanAdd(); - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - LayerRefinedAttributeDefinition other = (LayerRefinedAttributeDefinition) obj; - if (layer != other.layer) - return false; - if (refinedAttributeDefinition == null) { - if (other.refinedAttributeDefinition != null) - return false; - } else if (!refinedAttributeDefinition.equals(other.refinedAttributeDefinition)) - return false; - return true; - } - - @Override - public String debugDump() { - return debugDump(0); - } + Boolean getOverrideCanModify(); - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - DebugUtil.indentDebugDump(sb, indent); - sb.append(getDebugDumpClassName()).append("(layer=").append(layer).append(",\n"); - sb.append(refinedAttributeDefinition.debugDump(indent+1, layer)); - return sb.toString(); - } - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "LRRAD"; - } - + PropertyLimitations getLimitations(); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinitionImpl.java new file mode 100644 index 00000000000..0b676e06c91 --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedAttributeDefinitionImpl.java @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.delta.PropertyDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttribute; +import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.DisplayableValue; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; +import org.jetbrains.annotations.NotNull; + +/** + * @author semancik + * + */ +public class LayerRefinedAttributeDefinitionImpl implements LayerRefinedAttributeDefinition { + + private RefinedAttributeDefinition refinedAttributeDefinition; + private LayerType layer; + private Boolean overrideCanRead = null; + private Boolean overrideCanAdd = null; + private Boolean overrideCanModify = null; + + private LayerRefinedAttributeDefinitionImpl(RefinedAttributeDefinition refinedAttributeDefinition, LayerType layer) { + this.refinedAttributeDefinition = refinedAttributeDefinition; + this.layer = layer; + } + + static LayerRefinedAttributeDefinition wrap(RefinedAttributeDefinition rAttrDef, LayerType layer) { + if (rAttrDef == null) { + return null; + } + return new LayerRefinedAttributeDefinitionImpl(rAttrDef, layer); + } + + static List> wrapCollection( + Collection defs, LayerType layer) { + List outs = new ArrayList>(defs.size()); + for (ItemDefinition itemDef: defs) { + if (itemDef instanceof LayerRefinedAttributeDefinition) { + outs.add(itemDef); + } else if (itemDef instanceof RefinedAttributeDefinition) { + outs.add(wrap((RefinedAttributeDefinition)itemDef, layer)); + } else { + throw new IllegalStateException("Unexpected type of attribute definition: " + itemDef); + } + } + return outs; + } + + @Override + public LayerType getLayer() { + return layer; + } + + @Override + public Boolean getOverrideCanRead() { + return overrideCanRead; + } + + public void setOverrideCanRead(Boolean overrideCanRead) { + this.overrideCanRead = overrideCanRead; + } + + @Override + public Boolean getOverrideCanAdd() { + return overrideCanAdd; + } + + public void setOverrideCanAdd(Boolean overrideCanAdd) { + this.overrideCanAdd = overrideCanAdd; + } + + @Override + public Boolean getOverrideCanModify() { + return overrideCanModify; + } + + public void setOverrideCanModify(Boolean overrideCanModify) { + this.overrideCanModify = overrideCanModify; + } + + @Override + public boolean canAdd() { + if (overrideCanAdd != null) { + return overrideCanAdd; + } + return refinedAttributeDefinition.canAdd(layer); + } + + @Override + public PropertyLimitations getLimitations() { + return refinedAttributeDefinition.getLimitations(layer); + } + + @NotNull + @Override + public RefinedAttributeDefinition clone() { + return refinedAttributeDefinition.clone(); + } + + // TODO ???????? + @Override + public String debugDump(int indent, LayerType layer) { + return refinedAttributeDefinition.debugDump(indent, layer); + } + + @Override + public boolean canRead() { + if (overrideCanRead != null) { + return overrideCanRead; + } + return refinedAttributeDefinition.canRead(layer); + } + + @Override + public boolean isIgnored(LayerType layer) { + return refinedAttributeDefinition.isIgnored(layer); + } + + @Override + public boolean canModify() { + if (overrideCanModify != null) { + return overrideCanModify; + } + return refinedAttributeDefinition.canModify(layer); + } + + // @Override +// public boolean isValidFor(QName elementQName, Class clazz) { +// return isValidFor(elementQName, clazz, false); +// } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((layer == null) ? 0 : layer.hashCode()); + result = prime * result + ((refinedAttributeDefinition == null) ? 0 : refinedAttributeDefinition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; +// if (!super.equals(obj)) +// return false; + if (getClass() != obj.getClass()) + return false; + LayerRefinedAttributeDefinitionImpl other = (LayerRefinedAttributeDefinitionImpl) obj; + if (layer != other.layer) + return false; + if (refinedAttributeDefinition == null) { + if (other.refinedAttributeDefinition != null) + return false; + } else if (!refinedAttributeDefinition.equals(other.refinedAttributeDefinition)) + return false; + return true; + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append(getDebugDumpClassName()).append("(layer=").append(layer).append(",\n"); + sb.append(refinedAttributeDefinition.debugDump(indent+1, layer)); + return sb.toString(); + } + + /** + * Return a human readable name of this class suitable for logs. + */ + protected String getDebugDumpClassName() { + return "LRRAD"; + } + + //region Delegation (automatically generated) + + @Override + public String getFrameworkAttributeName() { + return refinedAttributeDefinition.getFrameworkAttributeName(); + } + + @Override + public boolean isInherited() { + return refinedAttributeDefinition.isInherited(); + } + + @Override + public Integer getModificationPriority() { + return refinedAttributeDefinition.getModificationPriority(); + } + + @Override + public Boolean getReadReplaceMode() { + return refinedAttributeDefinition.getReadReplaceMode(); + } + + @Override + public T findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + return refinedAttributeDefinition.findItemDefinition(path, clazz); + } + + @Override + public boolean isDisplayNameAttribute() { + return refinedAttributeDefinition.isDisplayNameAttribute(); + } + + @Override + public ItemDefinition> deepClone(boolean ultraDeep) { + return refinedAttributeDefinition.deepClone(ultraDeep); + } + + @Override + public void revive(PrismContext prismContext) { + refinedAttributeDefinition.revive(prismContext); + } + + @Override + public Integer getDisplayOrder() { + return refinedAttributeDefinition.getDisplayOrder(); + } + + @Override + public String getHelp() { + return refinedAttributeDefinition.getHelp(); + } + + @Override + public String getDocumentation() { + return refinedAttributeDefinition.getDocumentation(); + } + + @Override + public String getDocumentationPreview() { + return refinedAttributeDefinition.getDocumentationPreview(); + } + + @Override + public boolean isRuntimeSchema() { + return refinedAttributeDefinition.isRuntimeSchema(); + } + + @Override + public PrismContext getPrismContext() { + return refinedAttributeDefinition.getPrismContext(); + } + + @Override + public Class getTypeClassIfKnown() { + return refinedAttributeDefinition.getTypeClassIfKnown(); + } + + @Override + public Class getTypeClass() { + return refinedAttributeDefinition.getTypeClass(); + } + + @Override + public String getDescription() { + return refinedAttributeDefinition.getDescription(); + } + + @Override + public PrismReferenceValue getValueEnumerationRef() { + return refinedAttributeDefinition.getValueEnumerationRef(); + } + + @Override + public ResourceAttributeDefinition getAttributeDefinition() { + return refinedAttributeDefinition.getAttributeDefinition(); + } + + @Override + public boolean isValidFor(QName elementQName, Class clazz) { + return refinedAttributeDefinition.isValidFor(elementQName, clazz); + } + + @Override + public MappingType getOutboundMappingType() { + return refinedAttributeDefinition.getOutboundMappingType(); + } + + @Override + public boolean hasOutboundMapping() { + return refinedAttributeDefinition.hasOutboundMapping(); + } + + @Override + public boolean isValidFor(@NotNull QName elementQName, + @NotNull Class clazz, boolean caseInsensitive) { + return refinedAttributeDefinition.isValidFor(elementQName, clazz, caseInsensitive); + } + + @Override + public List getInboundMappingTypes() { + return refinedAttributeDefinition.getInboundMappingTypes(); + } + + @Override + public int getMaxOccurs(LayerType layer) { + return refinedAttributeDefinition.getMaxOccurs(layer); + } + + @Override + public int getMinOccurs(LayerType layer) { + return refinedAttributeDefinition.getMinOccurs(layer); + } + + @Override + public void adoptElementDefinitionFrom(ItemDefinition otherDef) { + refinedAttributeDefinition.adoptElementDefinitionFrom(otherDef); + } + + @Override + public boolean isOptional(LayerType layer) { + return refinedAttributeDefinition.isOptional(layer); + } + + @Override + public boolean isEmphasized() { + return refinedAttributeDefinition.isEmphasized(); + } + + @Override + public boolean isMandatory(LayerType layer) { + return refinedAttributeDefinition.isMandatory(layer); + } + + @Override + public boolean isMultiValue(LayerType layer) { + return refinedAttributeDefinition.isMultiValue(layer); + } + + @Override + public boolean isSingleValue(LayerType layer) { + return refinedAttributeDefinition.isSingleValue(layer); + } + + @Override + public boolean isExlusiveStrong() { + return refinedAttributeDefinition.isExlusiveStrong(); + } + + @Override + public PropertyLimitations getLimitations(LayerType layer) { + return refinedAttributeDefinition.getLimitations(layer); + } + + @Override + public AttributeFetchStrategyType getFetchStrategy() { + return refinedAttributeDefinition.getFetchStrategy(); + } + + @Override + public List getTolerantValuePattern() { + return refinedAttributeDefinition.getTolerantValuePattern(); + } + + @Override + public List getIntolerantValuePattern() { + return refinedAttributeDefinition.getIntolerantValuePattern(); + } + + @Override + public boolean isVolatilityTrigger() { + return refinedAttributeDefinition.isVolatilityTrigger(); + } + + @Override + public String getDisplayName() { + return refinedAttributeDefinition.getDisplayName(); + } + + + @Override + public ResourceAttribute instantiate() { + return refinedAttributeDefinition.instantiate(); + } + + @Override + public ResourceAttribute instantiate(QName name) { + return refinedAttributeDefinition.instantiate(name); + } + + @Override + public Boolean getReturnedByDefault() { + return refinedAttributeDefinition.getReturnedByDefault(); + } + + @Override + public boolean isReturnedByDefault() { + return refinedAttributeDefinition.isReturnedByDefault(); + } + + @Override + public boolean isIdentifier(ResourceAttributeContainerDefinition objectDefinition) { + return refinedAttributeDefinition.isIdentifier(objectDefinition); + } + + @Override + @NotNull + public QName getName() { + return refinedAttributeDefinition.getName(); + } + + @Override + public String getNamespace() { + return refinedAttributeDefinition.getNamespace(); + } + + @Override + public int getMinOccurs() { + return refinedAttributeDefinition.getMinOccurs(layer); + } + + @Override + public Collection> getAllowedValues() { + return refinedAttributeDefinition.getAllowedValues(); + } + + @Override + public int getMaxOccurs() { + return refinedAttributeDefinition.getMaxOccurs(layer); + } + + @Override + public boolean isIdentifier(ObjectClassComplexTypeDefinition objectDefinition) { + return refinedAttributeDefinition.isIdentifier(objectDefinition); + } + + @Override + public T defaultValue() { + return refinedAttributeDefinition.defaultValue(); + } + + @Override + public boolean isTolerant() { + return refinedAttributeDefinition.isTolerant(); + } + + @Override + public boolean isSingleValue() { + return refinedAttributeDefinition.isSingleValue(layer); + } + + @Override + public QName getValueType() { + return refinedAttributeDefinition.getValueType(); + } + + @Override + public boolean isSecondaryIdentifier() { + return refinedAttributeDefinition.isSecondaryIdentifier(); + } + + @Override + public boolean isMultiValue() { + return refinedAttributeDefinition.isMultiValue(layer); + } + + @Override + @NotNull + public QName getTypeName() { + return refinedAttributeDefinition.getTypeName(); + } + + @Override + public Boolean isIndexed() { + return refinedAttributeDefinition.isIndexed(); + } + + @Override + public boolean canAdd(LayerType layer) { + return refinedAttributeDefinition.canAdd(layer); + } + + @Override + public boolean isMandatory() { + return refinedAttributeDefinition.isMandatory(layer); + } + + @Override + public boolean isIgnored() { + return refinedAttributeDefinition.isIgnored(layer); + } + + @Override + public boolean isSecondaryIdentifier(ObjectClassComplexTypeDefinition objectDefinition) { + return refinedAttributeDefinition.isSecondaryIdentifier(objectDefinition); + } + + @Override + public QName getMatchingRuleQName() { + return refinedAttributeDefinition.getMatchingRuleQName(); + } + + @Override + public boolean isAbstract() { + return refinedAttributeDefinition.isAbstract(); + } + + @Override + public boolean isOptional() { + return refinedAttributeDefinition.isOptional(layer); + } + + @Override + public boolean canRead(LayerType layer) { + return refinedAttributeDefinition.canRead(layer); + } + + @Override + public boolean isDeprecated() { + return refinedAttributeDefinition.isDeprecated(); + } + + @Override + public boolean isOperational() { + return refinedAttributeDefinition.isOperational(); + } + + @Override + public PropertyDelta createEmptyDelta(ItemPath path) { + return refinedAttributeDefinition.createEmptyDelta(path); + } + + @Override + public boolean canModify(LayerType layer) { + return refinedAttributeDefinition.canModify(layer); + } + + @Override + public boolean isDynamic() { + return refinedAttributeDefinition.isDynamic(); + } + + @Override + public String getNativeAttributeName() { + return refinedAttributeDefinition.getNativeAttributeName(); + } + + @Override + public RefinedAttributeDefinition deepClone(Map ctdMap) { + return new LayerRefinedAttributeDefinitionImpl(refinedAttributeDefinition.deepClone(ctdMap), layer); + } + + //endregion + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinition.java index 7ac879dbdb1..a59d12dd4ec 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinition.java @@ -13,635 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.common.refinery; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import javax.xml.namespace.QName; +package com.evolveum.midpoint.common.refinery; -import com.evolveum.midpoint.common.ResourceObjectPattern; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.Definition; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceActivationDefinitionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceBidirectionalMappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; /** - * @author semancik * @author mederly - * - * Work in-progress. TODO fix this mess - * */ -public class LayerRefinedObjectClassDefinition extends RefinedObjectClassDefinition { - - private RefinedObjectClassDefinition refinedObjectClassDefinition; - private LayerType layer; - /** - * Keeps layer-specific information on resource object attributes. - * This list is lazily evaluated. - */ - private List> layerRefinedAttributeDefinitions; - - private LayerRefinedObjectClassDefinition(RefinedObjectClassDefinition refinedAccountDefinition, LayerType layer) { - super(new QName("fake"), refinedAccountDefinition.getPrismContext()); - this.refinedObjectClassDefinition = refinedAccountDefinition; - this.layer = layer; - } - - static LayerRefinedObjectClassDefinition wrap(RefinedObjectClassDefinition rAccountDef, LayerType layer) { - if (rAccountDef == null) { - return null; - } - return new LayerRefinedObjectClassDefinition(rAccountDef, layer); - } - - static Collection wrapCollection(Collection rAccountDefs, LayerType layer) { - Collection outs = new ArrayList(rAccountDefs.size()); - for (RefinedObjectClassDefinition rAccountDef: rAccountDefs) { - outs.add(wrap(rAccountDef, layer)); - } - return outs; - } - - public LayerType getLayer() { - return layer; - } - - @Override - public QName getTypeName() { - return refinedObjectClassDefinition.getTypeName(); - } - - @Override - public void setTypeName(QName typeName) { - refinedObjectClassDefinition.setTypeName(typeName); - } - - @Override - public boolean isIgnored() { - return refinedObjectClassDefinition.isIgnored(); - } - - @Override - public void setIgnored(boolean ignored) { - refinedObjectClassDefinition.setIgnored(ignored); - } - - public boolean isEmphasized() { - return refinedObjectClassDefinition.isEmphasized(); - } - - public void setEmphasized(boolean emphasized) { - refinedObjectClassDefinition.setEmphasized(emphasized); - } - - @Override - public ResourceAttributeDefinition getDescriptionAttribute() { - return substituteLayerRefinedAttributeDefinition(refinedObjectClassDefinition.getDescriptionAttribute()); - } - - @Override - public void setDescriptionAttribute(ResourceAttributeDefinition descriptionAttribute) { - refinedObjectClassDefinition.setDescriptionAttribute(descriptionAttribute); - } - - private LayerRefinedAttributeDefinition substituteLayerRefinedAttributeDefinition(ResourceAttributeDefinition attributeDef) { - LayerRefinedAttributeDefinition rAttrDef = findAttributeDefinition(attributeDef.getName()); - return rAttrDef; - } - - private Collection> substituteLayerRefinedAttributeDefinitionCollection(Collection> attributes) { - Collection> retval = new ArrayList<>(); - for (RefinedAttributeDefinition rad : attributes) { - retval.add(substituteLayerRefinedAttributeDefinition(rad)); - } - return retval; - } - - @Override - public LayerRefinedAttributeDefinition getNamingAttribute() { - return substituteLayerRefinedAttributeDefinition(refinedObjectClassDefinition.getNamingAttribute()); - } - - @Override - public String getNativeObjectClass() { - return refinedObjectClassDefinition.getNativeObjectClass(); - } - - @Override - public Integer getDisplayOrder() { - return refinedObjectClassDefinition.getDisplayOrder(); - } - - @Override - public boolean isDefaultInAKind() { - return refinedObjectClassDefinition.isDefaultInAKind(); - } - - @Override - public void setDefaultInAKind(boolean defaultAccountType) { - refinedObjectClassDefinition.setDefaultInAKind(defaultAccountType); - } - - @Override - public ShadowKindType getKind() { - return refinedObjectClassDefinition.getKind(); - } - - @Override - public void setKind(ShadowKindType kind) { - refinedObjectClassDefinition.setKind(kind); - } - - @Override - public AttributeFetchStrategyType getPasswordFetchStrategy() { - return refinedObjectClassDefinition.getPasswordFetchStrategy(); - } - - @Override - public String getIntent() { - return refinedObjectClassDefinition.getIntent(); - } - - @Override - public void setIntent(String accountTypeName) { - refinedObjectClassDefinition.setIntent(accountTypeName); - } - - @Override - public void setDisplayOrder(Integer displayOrder) { - refinedObjectClassDefinition.setDisplayOrder(displayOrder); - } - - @Override - public LayerRefinedAttributeDefinition getDisplayNameAttribute() { - return substituteLayerRefinedAttributeDefinition(refinedObjectClassDefinition.getDisplayNameAttribute()); - } - - @Override - public String getHelp() { - return refinedObjectClassDefinition.getHelp(); - } - - @Override - public void setDisplayNameAttribute(QName displayName) { - refinedObjectClassDefinition.setDisplayNameAttribute(displayName); - } - - @Override - public Collection> getPrimaryIdentifiers() { - return substituteLayerRefinedAttributeDefinitionCollection(refinedObjectClassDefinition.getPrimaryIdentifiers()); - } - - @Override - public Collection> getAllIdentifiers() { - return substituteLayerRefinedAttributeDefinitionCollection(refinedObjectClassDefinition.getAllIdentifiers()); - } - - @Override - public D findItemDefinition(QName name, Class clazz) { - D findItemDefinition = refinedObjectClassDefinition.findItemDefinition(name, clazz); - return (D) LayerRefinedAttributeDefinition.wrap((RefinedAttributeDefinition) findItemDefinition, layer); - } - - @Override - public void setHelp(String help) { - refinedObjectClassDefinition.setHelp(help); - } - - @Override - public Collection> getSecondaryIdentifiers() { - return LayerRefinedAttributeDefinition.wrapCollection(refinedObjectClassDefinition.getSecondaryIdentifiers(), layer); - } - - @Override - public Class getTypeClass() { - return refinedObjectClassDefinition.getTypeClass(); - } - - @Override - public Collection getProtectedObjectPatterns() { - return refinedObjectClassDefinition.getProtectedObjectPatterns(); - } - - @Override - public PrismContext getPrismContext() { - return refinedObjectClassDefinition.getPrismContext(); - } - - @Override - public void setNamingAttribute(ResourceAttributeDefinition namingAttribute) { - refinedObjectClassDefinition.setNamingAttribute(namingAttribute); - } - - @Override - public ResourceAttributeContainer instantiate(QName name) { - return refinedObjectClassDefinition.instantiate(name); - } - - @Override - public void setNamingAttribute(QName namingAttribute) { - refinedObjectClassDefinition.setNamingAttribute(namingAttribute); - } - - @Override - public PrismPropertyDefinition findPropertyDefinition(QName name) { - LayerRefinedAttributeDefinition def = findAttributeDefinition(name); - if (def != null) { - return def; - } else { - // actually, can there be properties other than attributes? [mederly] - return LayerRefinedAttributeDefinition.wrap((RefinedAttributeDefinition) refinedObjectClassDefinition.findPropertyDefinition(name), layer); - } - } - - @Override - public LayerRefinedAttributeDefinition findAttributeDefinition(QName elementQName) { - for (LayerRefinedAttributeDefinition definition : getAttributeDefinitions()) { - if (QNameUtil.match(definition.getName(), elementQName)) { - return definition; - } - } - return null; - } - - @Override - public void setNativeObjectClass(String nativeObjectClass) { - refinedObjectClassDefinition.setNativeObjectClass(nativeObjectClass); - } - - @Override - public LayerRefinedAttributeDefinition findAttributeDefinition(String elementLocalname) { - return findAttributeDefinition(new QName(getResourceNamespace(), elementLocalname)); // todo or should we use ns-less matching? - } - - @Override - public String getDisplayName() { - return refinedObjectClassDefinition.getDisplayName(); - } - - @Override - public void setDisplayName(String displayName) { - refinedObjectClassDefinition.setDisplayName(displayName); - } - - @Override - public List getDefinitions() { - return getAttributeDefinitions(); - } +public interface LayerRefinedObjectClassDefinition extends RefinedObjectClassDefinition { - @Override - public String getDescription() { - return refinedObjectClassDefinition.getDescription(); - } - - @Override - public void setDescription(String description) { - refinedObjectClassDefinition.setDescription(description); - } - - @Override - public boolean isDefault() { - return refinedObjectClassDefinition.isDefault(); - } - - @Override - public void setDefault(boolean isDefault) { - refinedObjectClassDefinition.setDefault(isDefault); - } - - @Override - public ObjectClassComplexTypeDefinition getObjectClassDefinition() { - return refinedObjectClassDefinition.getObjectClassDefinition(); - } - - @Override - public void setObjectClassDefinition(ObjectClassComplexTypeDefinition objectClassDefinition) { - refinedObjectClassDefinition.setObjectClassDefinition(objectClassDefinition); - } - - @Override - public List> getAttributeDefinitions() { - if (layerRefinedAttributeDefinitions == null) { - layerRefinedAttributeDefinitions = LayerRefinedAttributeDefinition.wrapCollection(refinedObjectClassDefinition.getAttributeDefinitions(), layer); - } - return layerRefinedAttributeDefinitions; - } - - @Override - public ResourceType getResourceType() { - return refinedObjectClassDefinition.getResourceType(); - } - - @Override - public PrismObjectDefinition getObjectDefinition() { - return refinedObjectClassDefinition.getObjectDefinition(); - } - - @Override - public void setDisplayNameAttribute(ResourceAttributeDefinition displayName) { - refinedObjectClassDefinition.setDisplayNameAttribute(displayName); - } - - @Override - public LayerRefinedAttributeDefinition getAttributeDefinition(QName attributeName) { - // todo should there be any difference between findAttributeDefinition and getAttributeDefinition? [mederly] - return findAttributeDefinition(attributeName); - } - - @Override - public boolean containsAttributeDefinition(QName attributeName) { - return refinedObjectClassDefinition.containsAttributeDefinition(attributeName); - } - - @Override - public PrismPropertyDefinition createPropertyDefinition(String localName, QName typeName) { - throw new UnsupportedOperationException("property definition cannot be created in LayerRefinedObjectClassDefinition"); - // return refinedObjectClassDefinition.createPropertyDefinition(localName, typeName); - } - - @Override - public boolean isEmpty() { - return refinedObjectClassDefinition.isEmpty(); - } - - @Override - public PrismObject createBlankShadow() { - return refinedObjectClassDefinition.createBlankShadow(); - } - - @Override - public ResourceShadowDiscriminator getShadowDiscriminator() { - return refinedObjectClassDefinition.getShadowDiscriminator(); - } - - @Override - public Collection getNamesOfAttributesWithOutboundExpressions() { - return refinedObjectClassDefinition.getNamesOfAttributesWithOutboundExpressions(); - } - - @Override - public Collection getNamesOfAttributesWithInboundExpressions() { - return refinedObjectClassDefinition.getNamesOfAttributesWithInboundExpressions(); - } - - @Override - public List getPasswordInbound() { - return refinedObjectClassDefinition.getPasswordInbound(); - } - - @Override - public MappingType getPasswordOutbound() { - return refinedObjectClassDefinition.getPasswordOutbound(); - } - - @Override - public ObjectReferenceType getPasswordPolicy() { - return refinedObjectClassDefinition.getPasswordPolicy(); - } - - @Override - public Class getCompileTimeClass() { - return refinedObjectClassDefinition.getCompileTimeClass(); - } - - @Override - public QName getExtensionForType() { - return refinedObjectClassDefinition.getExtensionForType(); - } - - @Override - public boolean isContainerMarker() { - return refinedObjectClassDefinition.isContainerMarker(); - } - - @Override - public boolean isPrimaryIdentifier(QName attrName) { - return refinedObjectClassDefinition.isPrimaryIdentifier(attrName); - } - - @Override - public boolean isObjectMarker() { - return refinedObjectClassDefinition.isObjectMarker(); - } - - @Override - public boolean isXsdAnyMarker() { - return refinedObjectClassDefinition.isXsdAnyMarker(); - } - - @Override - public QName getSuperType() { - return refinedObjectClassDefinition.getSuperType(); - } - - @Override - public boolean isSecondaryIdentifier(QName attrName) { - return refinedObjectClassDefinition.isSecondaryIdentifier(attrName); - } - - @Override - public boolean isRuntimeSchema() { - return refinedObjectClassDefinition.isRuntimeSchema(); - } - - @Override - public Collection getAssociations() { - return refinedObjectClassDefinition.getAssociations(); - } - - @Override - public Collection getAssociations(ShadowKindType kind) { - return refinedObjectClassDefinition.getAssociations(kind); - } - - @Override - public ResourceAttributeContainerDefinition toResourceAttributeContainerDefinition() { - ResourceAttributeContainerDefinition resourceAttributeContainerDefinition = refinedObjectClassDefinition.toResourceAttributeContainerDefinition(); - resourceAttributeContainerDefinition.setComplexTypeDefinition(this); - return resourceAttributeContainerDefinition; - } - - @Override - public ResourceAttributeContainerDefinition toResourceAttributeContainerDefinition(QName elementName) { - ResourceAttributeContainerDefinition resourceAttributeContainerDefinition = refinedObjectClassDefinition.toResourceAttributeContainerDefinition(elementName); - resourceAttributeContainerDefinition.setComplexTypeDefinition(this); - return resourceAttributeContainerDefinition; - } - - @Override - public ResourceActivationDefinitionType getActivationSchemaHandling() { - return refinedObjectClassDefinition.getActivationSchemaHandling(); - } - - @Override - public ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName) { - return refinedObjectClassDefinition.getActivationBidirectionalMappingType(propertyName); - } - - @Override - public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) { - return refinedObjectClassDefinition.getActivationFetchStrategy(propertyName); - } - - @Override - public Collection getEntitlementAssociations() { - return refinedObjectClassDefinition.getEntitlementAssociations(); - } - - @Override - public boolean isAbstract() { - return refinedObjectClassDefinition.isAbstract(); - } - - @Override - public boolean isDeprecated() { - return refinedObjectClassDefinition.isDeprecated(); - } - - @Override - public String getDocumentation() { - return refinedObjectClassDefinition.getDocumentation(); - } - - @Override - public String getDocumentationPreview() { - return refinedObjectClassDefinition.getDocumentationPreview(); - } - - @Override - public RefinedAssociationDefinition findAssociation(QName name) { - return refinedObjectClassDefinition.findAssociation(name); - } - - @Override - public RefinedAssociationDefinition findEntitlementAssociation(QName name) { - return refinedObjectClassDefinition.findEntitlementAssociation(name); - } - - @Override - public Collection getNamesOfAssociationsWithOutboundExpressions() { - return refinedObjectClassDefinition.getNamesOfAssociationsWithOutboundExpressions(); - } - - @Override - public String getDocClassName() { - return refinedObjectClassDefinition.getDocClassName(); - } - - @Override - public boolean matches(ShadowType shadowType) { - return refinedObjectClassDefinition.matches(shadowType); - } + LayerType getLayer(); + @NotNull @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((layer == null) ? 0 : layer.hashCode()); - result = prime * result + ((refinedObjectClassDefinition == null) ? 0 : refinedObjectClassDefinition.hashCode()); - return result; - } + Collection> getAttributeDefinitions(); + @NotNull @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - LayerRefinedObjectClassDefinition other = (LayerRefinedObjectClassDefinition) obj; - if (layer != other.layer) - return false; - if (refinedObjectClassDefinition == null) { - if (other.refinedObjectClassDefinition != null) - return false; - } else if (!refinedObjectClassDefinition.equals(other.refinedObjectClassDefinition)) - return false; - return true; - } - - @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - return debugDump(indent, layer); - } - - // Do NOT override&delegate debugDump(int indent, LayerType layer) here. - // We want to use code in the context of this class so things like - // getDebugDumpClassName() will be correct. - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "LRObjectClassDef"; - } - - @Override - public String getHumanReadableName() { - return refinedObjectClassDefinition.getHumanReadableName(); - } - - @Override - public LayerRefinedObjectClassDefinition clone() { - return wrap(refinedObjectClassDefinition.clone(), this.layer); - } - - @Override - protected String getResourceNamespace() { - return refinedObjectClassDefinition.getResourceNamespace(); - } - - @Override - public void add(RefinedAttributeDefinition refinedAttributeDefinition) { - throw new UnsupportedOperationException(); - } + LayerRefinedObjectClassDefinition clone(); - @Override - public void parseAssociations(RefinedResourceSchema rSchema) { - throw new UnsupportedOperationException(); - } - - @Override - public ResourceObjectReferenceType getBaseContext() { - return refinedObjectClassDefinition.getBaseContext(); - } - - @Override - public Collection getAuxiliaryObjectClassDefinitions() { - return refinedObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); - } - - @Override - public ObjectQuery createShadowSearchQuery(String resourceOid) throws SchemaException { - return refinedObjectClassDefinition.createShadowSearchQuery(resourceOid); - } } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java new file mode 100644 index 00000000000..ee78c4e7e46 --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedObjectClassDefinitionImpl.java @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.common.ResourceObjectPattern; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.processor.*; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import org.jetbrains.annotations.NotNull; + +/** + * @author semancik + * @author mederly + * + * Work in-progress. + * + */ +public class LayerRefinedObjectClassDefinitionImpl implements LayerRefinedObjectClassDefinition { + + private RefinedObjectClassDefinition refinedObjectClassDefinition; + private LayerType layer; + /** + * Keeps layer-specific information on resource object attributes. + * This list is lazily evaluated. + */ + private List> layerRefinedAttributeDefinitions; + + private LayerRefinedObjectClassDefinitionImpl(RefinedObjectClassDefinition refinedAccountDefinition, LayerType layer) { + this.refinedObjectClassDefinition = refinedAccountDefinition; + this.layer = layer; + } + + static LayerRefinedObjectClassDefinition wrap(RefinedObjectClassDefinition rOCD, LayerType layer) { + if (rOCD == null) { + return null; + } + return new LayerRefinedObjectClassDefinitionImpl(rOCD, layer); + } + + static List wrapCollection(Collection rOCDs, LayerType layer) { + return(rOCDs.stream() + .map(rAccountDef -> wrap(rAccountDef, layer)) + .collect(Collectors.toCollection(() -> new ArrayList<>(rOCDs.size())))); + } + + @Override + public LayerType getLayer() { + return layer; + } + + @NotNull + @Override + public QName getTypeName() { + return refinedObjectClassDefinition.getTypeName(); + } + + @Override + public boolean isIgnored() { + return refinedObjectClassDefinition.isIgnored(); + } + + public boolean isEmphasized() { + return refinedObjectClassDefinition.isEmphasized(); + } + + @Override + public LayerRefinedAttributeDefinition getDescriptionAttribute() { + // TODO optimize + return substituteLayerRefinedAttributeDefinition(refinedObjectClassDefinition.getDescriptionAttribute()); + } + + @Override + @NotNull + public List getIgnoredNamespaces() { + return refinedObjectClassDefinition.getIgnoredNamespaces(); + } + + private LayerRefinedAttributeDefinition substituteLayerRefinedAttributeDefinition(ResourceAttributeDefinition attributeDef) { + return findAttributeDefinition(attributeDef.getName()); + } + + private Collection> substituteLayerRefinedAttributeDefinitionCollection(Collection> attributes) { + return attributes.stream() + .map(this::substituteLayerRefinedAttributeDefinition) + .collect(Collectors.toList()); + } + + @Override + public LayerRefinedAttributeDefinition getNamingAttribute() { + return substituteLayerRefinedAttributeDefinition(refinedObjectClassDefinition.getNamingAttribute()); + } + + @Override + public String getNativeObjectClass() { + return refinedObjectClassDefinition.getNativeObjectClass(); + } + + @Override + public boolean isAuxiliary() { + return refinedObjectClassDefinition.isAuxiliary(); + } + + @Override + public Integer getDisplayOrder() { + return refinedObjectClassDefinition.getDisplayOrder(); + } + + // TODO - doesn't return layered definition (should it?) + @Override + public ID findItemDefinition(@NotNull ItemPath path, + @NotNull Class clazz) { + return refinedObjectClassDefinition.findItemDefinition(path, clazz); + } + + // TODO - doesn't return layered definition (should it?) + @Override + public ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, + @NotNull Class clazz) { + return refinedObjectClassDefinition.findNamedItemDefinition(firstName, rest, clazz); + } + + @Override + public boolean isDefaultInAKind() { + return refinedObjectClassDefinition.isDefaultInAKind(); + } + + @Override + public ShadowKindType getKind() { + return refinedObjectClassDefinition.getKind(); + } + + @Override + public AttributeFetchStrategyType getPasswordFetchStrategy() { + return refinedObjectClassDefinition.getPasswordFetchStrategy(); + } + + @Override + public String getIntent() { + return refinedObjectClassDefinition.getIntent(); + } + + @Override + public LayerRefinedObjectClassDefinition forLayer(@NotNull LayerType layerType) { + return refinedObjectClassDefinition.forLayer(layerType); + } + + @Override + public LayerRefinedAttributeDefinition getDisplayNameAttribute() { + return substituteLayerRefinedAttributeDefinition(refinedObjectClassDefinition.getDisplayNameAttribute()); + } + + @Override + public String getHelp() { + return refinedObjectClassDefinition.getHelp(); + } + + @NotNull + @Override + public Collection> getPrimaryIdentifiers() { + return substituteLayerRefinedAttributeDefinitionCollection(refinedObjectClassDefinition.getPrimaryIdentifiers()); + } + + @Override + public Collection> getAllIdentifiers() { + return substituteLayerRefinedAttributeDefinitionCollection(refinedObjectClassDefinition.getAllIdentifiers()); + } + + @NotNull + @Override + public Collection> getSecondaryIdentifiers() { + return LayerRefinedAttributeDefinitionImpl.wrapCollection(refinedObjectClassDefinition.getSecondaryIdentifiers(), layer); + } + + @Override + public Class getTypeClass() { + return refinedObjectClassDefinition.getTypeClass(); + } + + @Override + public Collection getProtectedObjectPatterns() { + return refinedObjectClassDefinition.getProtectedObjectPatterns(); + } + + @Override + public void merge(ComplexTypeDefinition otherComplexTypeDef) { + refinedObjectClassDefinition.merge(otherComplexTypeDef); + } + + @Override + public PrismContext getPrismContext() { + return refinedObjectClassDefinition.getPrismContext(); + } + + @Override + public ResourceAttributeContainer instantiate(QName name) { + return ObjectClassComplexTypeDefinitionImpl.instantiate(name, this); + } + +// @Override +// public PrismPropertyDefinition findPropertyDefinition(@NotNull QName name) { +// LayerRefinedAttributeDefinition def = findAttributeDefinition(name); +// if (def != null) { +// return def; +// } else { +// return LayerRefinedAttributeDefinitionImpl.wrap((RefinedAttributeDefinition) refinedObjectClassDefinition.findPropertyDefinition(name), layer); +// } +// } + + @Override + public LayerRefinedAttributeDefinition findAttributeDefinition(@NotNull QName elementQName) { + for (LayerRefinedAttributeDefinition definition : getAttributeDefinitions()) { + if (QNameUtil.match(definition.getName(), elementQName)) { + return definition; + } + } + return null; + } + + @Override + public LayerRefinedAttributeDefinition findAttributeDefinition(String elementLocalname) { + return findAttributeDefinition(new QName(getResourceNamespace(), elementLocalname)); // todo or should we use ns-less matching? + } + + @Override + public String getDisplayName() { + return refinedObjectClassDefinition.getDisplayName(); + } + + @NotNull + @Override + public List getDefinitions() { + return getAttributeDefinitions(); + } + + @Override + public String getDescription() { + return refinedObjectClassDefinition.getDescription(); + } + + @Override + public boolean isDefault() { + return refinedObjectClassDefinition.isDefault(); + } + + @Override + public ObjectClassComplexTypeDefinition getObjectClassDefinition() { + return refinedObjectClassDefinition.getObjectClassDefinition(); + } + + @NotNull + @Override + public List> getAttributeDefinitions() { + if (layerRefinedAttributeDefinitions == null) { + layerRefinedAttributeDefinitions = LayerRefinedAttributeDefinitionImpl.wrapCollection(refinedObjectClassDefinition.getAttributeDefinitions(), layer); + } + return layerRefinedAttributeDefinitions; + } + + @Override + public boolean containsAttributeDefinition(ItemPathType pathType) { + return refinedObjectClassDefinition.containsAttributeDefinition(pathType); + } + + @Override + public ResourceType getResourceType() { + return refinedObjectClassDefinition.getResourceType(); + } + + @Override + public PrismObjectDefinition getObjectDefinition() { + return refinedObjectClassDefinition.getObjectDefinition(); + } + + @Override + public boolean containsAttributeDefinition(QName attributeName) { + return refinedObjectClassDefinition.containsAttributeDefinition(attributeName); + } + + @Override + public boolean isEmpty() { + return refinedObjectClassDefinition.isEmpty(); + } + + @Override + public PrismObject createBlankShadow(RefinedObjectClassDefinition definition) { + return refinedObjectClassDefinition.createBlankShadow(definition); + } + + @Override + public ResourceShadowDiscriminator getShadowDiscriminator() { + return refinedObjectClassDefinition.getShadowDiscriminator(); + } + + @Override + public Collection getNamesOfAttributesWithOutboundExpressions() { + return refinedObjectClassDefinition.getNamesOfAttributesWithOutboundExpressions(); + } + + @Override + public Collection getNamesOfAttributesWithInboundExpressions() { + return refinedObjectClassDefinition.getNamesOfAttributesWithInboundExpressions(); + } + + @Override + public List getPasswordInbound() { + return refinedObjectClassDefinition.getPasswordInbound(); + } + + @Override + public MappingType getPasswordOutbound() { + return refinedObjectClassDefinition.getPasswordOutbound(); + } + + @Override + public ObjectReferenceType getPasswordPolicy() { + return refinedObjectClassDefinition.getPasswordPolicy(); + } + + @Override + public ResourcePasswordDefinitionType getPasswordDefinition() { + return refinedObjectClassDefinition.getPasswordDefinition(); + } + + @Override + public Class getCompileTimeClass() { + return refinedObjectClassDefinition.getCompileTimeClass(); + } + + @Override + public QName getExtensionForType() { + return refinedObjectClassDefinition.getExtensionForType(); + } + + @Override + public boolean isContainerMarker() { + return refinedObjectClassDefinition.isContainerMarker(); + } + + @Override + public boolean isPrimaryIdentifier(QName attrName) { + return refinedObjectClassDefinition.isPrimaryIdentifier(attrName); + } + + @Override + public boolean isObjectMarker() { + return refinedObjectClassDefinition.isObjectMarker(); + } + + @Override + public boolean isXsdAnyMarker() { + return refinedObjectClassDefinition.isXsdAnyMarker(); + } + + @Override + public QName getSuperType() { + return refinedObjectClassDefinition.getSuperType(); + } + + @Override + public boolean isSecondaryIdentifier(QName attrName) { + return refinedObjectClassDefinition.isSecondaryIdentifier(attrName); + } + + @Override + public boolean isRuntimeSchema() { + return refinedObjectClassDefinition.isRuntimeSchema(); + } + + @NotNull + @Override + public Collection getAssociationDefinitions() { + return refinedObjectClassDefinition.getAssociationDefinitions(); + } + + @Override + public Collection getAssociationDefinitions(ShadowKindType kind) { + return refinedObjectClassDefinition.getAssociationDefinitions(kind); + } + + @Override + public Collection getNamesOfAssociations() { + return refinedObjectClassDefinition.getNamesOfAssociations(); + } + + @Override + public ResourceActivationDefinitionType getActivationSchemaHandling() { + return refinedObjectClassDefinition.getActivationSchemaHandling(); + } + + @Override + public ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName) { + return refinedObjectClassDefinition.getActivationBidirectionalMappingType(propertyName); + } + + @Override + public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) { + return refinedObjectClassDefinition.getActivationFetchStrategy(propertyName); + } + + @Override + public T getEffectiveCapability(Class capabilityClass) { + return (T) refinedObjectClassDefinition.getEffectiveCapability(capabilityClass); + } + + @Override + public PagedSearchCapabilityType getPagedSearches() { + return refinedObjectClassDefinition.getPagedSearches(); + } + + @Override + public boolean isPagedSearchEnabled() { + return refinedObjectClassDefinition.isPagedSearchEnabled(); + } + + @Override + public boolean isObjectCountingEnabled() { + return refinedObjectClassDefinition.isObjectCountingEnabled(); + } + + @Override + public Collection getEntitlementAssociationDefinitions() { + return refinedObjectClassDefinition.getEntitlementAssociationDefinitions(); + } + + @Override + public boolean isAbstract() { + return refinedObjectClassDefinition.isAbstract(); + } + + @Override + public boolean isDeprecated() { + return refinedObjectClassDefinition.isDeprecated(); + } + + @Override + public String getDocumentation() { + return refinedObjectClassDefinition.getDocumentation(); + } + + @Override + public String getDocumentationPreview() { + return refinedObjectClassDefinition.getDocumentationPreview(); + } + + @Override + public RefinedAssociationDefinition findAssociationDefinition(QName name) { + return refinedObjectClassDefinition.findAssociationDefinition(name); + } + + @Override + public ID findItemDefinition(@NotNull QName name, @NotNull Class clazz, + boolean caseInsensitive) { + ID def = refinedObjectClassDefinition.findItemDefinition(name, clazz, caseInsensitive); + return (ID) LayerRefinedAttributeDefinitionImpl.wrap((RefinedAttributeDefinition) def, layer); + } + + @Override + public RefinedAssociationDefinition findEntitlementAssociationDefinition(QName name) { + return refinedObjectClassDefinition.findEntitlementAssociationDefinition(name); + } + + @Override + public Collection getNamesOfAssociationsWithOutboundExpressions() { + return refinedObjectClassDefinition.getNamesOfAssociationsWithOutboundExpressions(); + } + + @Override + public boolean matches(ShadowType shadowType) { + return refinedObjectClassDefinition.matches(shadowType); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((layer == null) ? 0 : layer.hashCode()); + result = prime * result + ((refinedObjectClassDefinition == null) ? 0 : refinedObjectClassDefinition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; +// if (!super.equals(obj)) +// return false; + if (getClass() != obj.getClass()) + return false; + LayerRefinedObjectClassDefinitionImpl other = (LayerRefinedObjectClassDefinitionImpl) obj; + if (layer != other.layer) + return false; + if (refinedObjectClassDefinition == null) { + if (other.refinedObjectClassDefinition != null) + return false; + } else if (!refinedObjectClassDefinition.equals(other.refinedObjectClassDefinition)) + return false; + return true; + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String getDefaultNamespace() { + return refinedObjectClassDefinition.getDefaultNamespace(); + } + + @Override + public String debugDump(int indent) { + return RefinedObjectClassDefinitionImpl.debugDump(indent, layer, this); + } + + // Do NOT override&delegate debugDump(int indent, LayerType layer) here. + // We want to use code in the context of this class so things like + // getDebugDumpClassName() will be correct. + + /** + * Return a human readable name of this class suitable for logs. + */ + public String getDebugDumpClassName() { + return "LRObjectClassDef"; + } + + @Override + public String getHumanReadableName() { + return refinedObjectClassDefinition.getHumanReadableName(); + } + + @NotNull + @Override + public LayerRefinedObjectClassDefinition clone() { + return wrap(refinedObjectClassDefinition.clone(), this.layer); + } + + @NotNull + @Override + public RefinedObjectClassDefinition deepClone(Map ctdMap) { + return new LayerRefinedObjectClassDefinitionImpl(refinedObjectClassDefinition.deepClone(ctdMap), layer); + } + + @Override + public String getResourceNamespace() { + return refinedObjectClassDefinition.getResourceNamespace(); + } + + @Override + public ResourceObjectReferenceType getBaseContext() { + return refinedObjectClassDefinition.getBaseContext(); + } + + @Override + public Class getTypeClassIfKnown() { + return refinedObjectClassDefinition.getTypeClassIfKnown(); + } + + @NotNull + @Override + public Collection getAuxiliaryObjectClassDefinitions() { + return refinedObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); + } + + @Override + public boolean hasAuxiliaryObjectClass(QName expectedObjectClassName) { + return refinedObjectClassDefinition.hasAuxiliaryObjectClass(expectedObjectClassName); + } + + @Override + public ObjectQuery createShadowSearchQuery(String resourceOid) throws SchemaException { + return refinedObjectClassDefinition.createShadowSearchQuery(resourceOid); + } + + @Override + public void revive(PrismContext prismContext) { + refinedObjectClassDefinition.revive(prismContext); + } + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchema.java index 55db2b3f792..5f8f375a3f6 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchema.java @@ -13,299 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.common.refinery; - -import java.util.Collection; -import java.util.List; - -import javax.xml.namespace.QName; -import org.w3c.dom.Document; +package com.evolveum.midpoint.common.refinery; -import com.evolveum.midpoint.prism.ComplexTypeDefinition; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Definition; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismReferenceDefinition; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceSchema; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import javax.xml.namespace.QName; + /** - * @author semancik - * - * This class enhances RefinedResourceSchema with a layer-specific view. - * - * TODO: However, there are a few unresolved issues that should be dealt with: - * - * 1) Although it might seem to contain LayerRefinedObjectClassDefinitions (LROCDs), it is not the case: - * it generates them on the fly by calling LROCD.wrap method every time. - * - * 2) When accessing attributes via findItemDefinition of this object, a non-layered version - * of attribute container is returned. - * + * @author mederly */ -public class LayerRefinedResourceSchema extends RefinedResourceSchema { - - private RefinedResourceSchema refinedResourceSchema; - private LayerType layer; - - private LayerRefinedResourceSchema(RefinedResourceSchema refinedResourceSchema, LayerType layer) { - super(refinedResourceSchema.getPrismContext()); - this.refinedResourceSchema = refinedResourceSchema; - this.layer = layer; - } - - public LayerType getLayer() { - return layer; - } - - static LayerRefinedResourceSchema wrap(RefinedResourceSchema rSchema, LayerType layer) { - return new LayerRefinedResourceSchema(rSchema, layer); - } - - public String getNamespace() { - return refinedResourceSchema.getNamespace(); - } - - public Collection getRefinedDefinitions(ShadowKindType kind) { - return LayerRefinedObjectClassDefinition.wrapCollection(refinedResourceSchema.getRefinedDefinitions(kind), layer); - } - - public Collection getDefinitions() { - return refinedResourceSchema.getDefinitions(); - } - - public ResourceSchema getOriginalResourceSchema() { - return refinedResourceSchema.getOriginalResourceSchema(); - } - - public Collection getDefinitions(Class type) { - return refinedResourceSchema.getDefinitions(type); - } - - public LayerRefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, ShadowType shadow) { - return LayerRefinedObjectClassDefinition.wrap(refinedResourceSchema.getRefinedDefinition(kind, shadow),layer); - } - - public LayerRefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, String intent) { - return LayerRefinedObjectClassDefinition.wrap(refinedResourceSchema.getRefinedDefinition(kind, intent),layer); - } - - public LayerRefinedObjectClassDefinition getRefinedDefinition(QName typeName) { - return LayerRefinedObjectClassDefinition.wrap(refinedResourceSchema.getRefinedDefinition(typeName),layer); - } - - public void add(Definition def) { - refinedResourceSchema.add(def); - } - - public PrismContext getPrismContext() { - return refinedResourceSchema.getPrismContext(); - } - - public LayerRefinedObjectClassDefinition getDefaultRefinedDefinition(ShadowKindType kind) { - return LayerRefinedObjectClassDefinition.wrap(refinedResourceSchema.getDefaultRefinedDefinition(kind),layer); - } - - public PrismObjectDefinition getObjectDefinition(ShadowKindType kind, String intent) { - return refinedResourceSchema.getObjectDefinition(kind, intent); - } - - public PrismObjectDefinition getObjectDefinition(ShadowKindType kind, ShadowType shadow) { - return refinedResourceSchema.getObjectDefinition(kind, shadow); - } - - public PrismContainerDefinition findContainerDefinitionByType(QName typeName) { - return refinedResourceSchema.findContainerDefinitionByType(typeName); - } - - public PrismObjectDefinition findObjectDefinitionByType(QName typeName) { - return refinedResourceSchema.findObjectDefinitionByType(typeName); - } - - public PrismObjectDefinition findObjectDefinitionByElementName(QName elementName) { - return refinedResourceSchema.findObjectDefinitionByElementName(elementName); - } - - public PrismObjectDefinition findObjectDefinitionByType(QName typeName, Class type) { - return refinedResourceSchema.findObjectDefinitionByType(typeName, type); - } - - public PrismObjectDefinition findObjectDefinitionByCompileTimeClass(Class type) { - return refinedResourceSchema.findObjectDefinitionByCompileTimeClass(type); - } - - public PrismPropertyDefinition findPropertyDefinitionByElementName(QName elementName) { - return refinedResourceSchema.findPropertyDefinitionByElementName(elementName); - } - - public T findItemDefinition(QName definitionName, Class definitionType) { - return refinedResourceSchema.findItemDefinition(definitionName, definitionType); - } - - public T findItemDefinition(String localName, Class definitionType) { - return refinedResourceSchema.findItemDefinition(localName, definitionType); - } - - public T findItemDefinitionByType(QName typeName, Class definitionType) { - return refinedResourceSchema.findItemDefinitionByType(typeName, definitionType); - } - - public PrismContainerDefinition createPropertyContainerDefinition(String localTypeName) { - return refinedResourceSchema.createPropertyContainerDefinition(localTypeName); - } - - public PrismContainerDefinition createPropertyContainerDefinition(String localElementName, String localTypeName) { - return refinedResourceSchema.createPropertyContainerDefinition(localElementName, localTypeName); - } - - public ComplexTypeDefinition createComplexTypeDefinition(QName typeName) { - return refinedResourceSchema.createComplexTypeDefinition(typeName); - } - - public PrismPropertyDefinition createPropertyDefinition(String localName, QName typeName) { - return refinedResourceSchema.createPropertyDefinition(localName, typeName); - } - - public PrismPropertyDefinition createPropertyDefinition(String localName, String localTypeName) { - return refinedResourceSchema.createPropertyDefinition(localName, localTypeName); - } - - public PrismPropertyDefinition createPropertyDefinition(QName name, QName typeName) { - return refinedResourceSchema.createPropertyDefinition(name, typeName); - } - - public LayerRefinedObjectClassDefinition findRefinedDefinitionByObjectClassQName(ShadowKindType kind, QName objectClass) { - return LayerRefinedObjectClassDefinition.wrap(refinedResourceSchema.findRefinedDefinitionByObjectClassQName(kind, objectClass),layer); - } - - public PrismContainerDefinition findContainerDefinitionByElementName(QName elementName) { - return refinedResourceSchema.findContainerDefinitionByElementName(elementName); - } - - public ComplexTypeDefinition findComplexTypeDefinition(QName typeName) { - return refinedResourceSchema.findComplexTypeDefinition(typeName); - } - - public void setNamespace(String namespace) { - refinedResourceSchema.setNamespace(namespace); - } - - public Document serializeToXsd() throws SchemaException { - return refinedResourceSchema.serializeToXsd(); - } - - public boolean isEmpty() { - return refinedResourceSchema.isEmpty(); - } - - public Collection getObjectClassDefinitions() { - return refinedResourceSchema.getObjectClassDefinitions(); - } - - public ObjectClassComplexTypeDefinition createObjectClassDefinition(String localTypeName) { - return refinedResourceSchema.createObjectClassDefinition(localTypeName); - } - - public ObjectClassComplexTypeDefinition createObjectClassDefinition(QName typeName) { - return refinedResourceSchema.createObjectClassDefinition(typeName); - } - - public List getRefinedDefinitions() { - return refinedResourceSchema.getRefinedDefinitions(); - } - - public ObjectClassComplexTypeDefinition findObjectClassDefinition(ShadowType shadow) { - return refinedResourceSchema.findObjectClassDefinition(shadow); - } - - public ObjectClassComplexTypeDefinition findObjectClassDefinition(String localName) { - return refinedResourceSchema.findObjectClassDefinition(localName); - } - - public Collection getObjectDefinitions() { - return refinedResourceSchema.getObjectDefinitions(); - } - - public Collection getComplexTypeDefinitions() { - return refinedResourceSchema.getComplexTypeDefinitions(); - } - - public ObjectClassComplexTypeDefinition findObjectClassDefinition(ShadowKindType kind, String intent) { - return refinedResourceSchema.findObjectClassDefinition(kind, intent); - } - - public ObjectClassComplexTypeDefinition findDefaultObjectClassDefinition(ShadowKindType kind) { - return refinedResourceSchema.findDefaultObjectClassDefinition(kind); - } - - public ObjectClassComplexTypeDefinition findObjectClassDefinition(QName objectClassQName) { - return refinedResourceSchema.findObjectClassDefinition(objectClassQName); - } - - public PrismObjectDefinition findObjectDefinitionByTypeAssumeNs(QName typeName) { - return refinedResourceSchema.findObjectDefinitionByTypeAssumeNs(typeName); - } - - public PrismContainerDefinition findContainerDefinitionByCompileTimeClass( - Class type) { - return refinedResourceSchema.findContainerDefinitionByCompileTimeClass(type); - } +public interface LayerRefinedResourceSchema extends RefinedResourceSchema { + LayerType getLayer(); - public PrismReferenceDefinition findReferenceDefinitionByElementName(QName elementName) { - return refinedResourceSchema.findReferenceDefinitionByElementName(elementName); - } + LayerRefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, ShadowType shadow); - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((layer == null) ? 0 : layer.hashCode()); - result = prime * result + ((refinedResourceSchema == null) ? 0 : refinedResourceSchema.hashCode()); - return result; - } + LayerRefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, String intent); - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LayerRefinedResourceSchema other = (LayerRefinedResourceSchema) obj; - if (layer != other.layer) - return false; - if (refinedResourceSchema == null) { - if (other.refinedResourceSchema != null) - return false; - } else if (!refinedResourceSchema.equals(other.refinedResourceSchema)) - return false; - return true; - } - - @Override - public String debugDump() { - return debugDump(0); - } + LayerRefinedObjectClassDefinition getRefinedDefinition(QName typeName); - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - DebugUtil.indentDebugDump(sb, indent); - sb.append("LRSchema(layer=").append(layer).append(",\n"); - sb.append(refinedResourceSchema.debugDump(indent+1)); - return sb.toString(); - } - + LayerRefinedObjectClassDefinition getDefaultRefinedDefinition(ShadowKindType kind); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchemaImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchemaImpl.java new file mode 100644 index 00000000000..abcccf6e03c --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/LayerRefinedResourceSchemaImpl.java @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceSchema; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; + +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; + +/** + * @author semancik + * + * This class enhances RefinedResourceSchema with a layer-specific view. + * + * TODO: However, there are a few unresolved issues that should be dealt with: + * + * 1) Although it might seem to contain LayerRefinedObjectClassDefinitions (LROCDs), it is not the case: + * it generates them on the fly by calling LROCD.wrap method every time. + * + * 2) When accessing attributes via findItemDefinition of this object, a non-layered version + * of attribute container is returned. + * + */ +public class LayerRefinedResourceSchemaImpl implements LayerRefinedResourceSchema { + + private final RefinedResourceSchema refinedResourceSchema; + private final LayerType layer; + + LayerRefinedResourceSchemaImpl(RefinedResourceSchema refinedResourceSchema, LayerType layer) { + this.refinedResourceSchema = refinedResourceSchema; + this.layer = layer; + } + + @Override + public LayerType getLayer() { + return layer; + } + + public List getRefinedDefinitions(ShadowKindType kind) { + return LayerRefinedObjectClassDefinitionImpl + .wrapCollection(refinedResourceSchema.getRefinedDefinitions(kind), layer); + } + + @Override + public ResourceSchema getOriginalResourceSchema() { + return refinedResourceSchema.getOriginalResourceSchema(); + } + + @Override + public LayerRefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, ShadowType shadow) { + return LayerRefinedObjectClassDefinitionImpl + .wrap(refinedResourceSchema.getRefinedDefinition(kind, shadow), layer); + } + + @Override + public String getNamespace() { + return refinedResourceSchema.getNamespace(); + } + + @Override + public LayerRefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, String intent) { + return LayerRefinedObjectClassDefinitionImpl + .wrap(refinedResourceSchema.getRefinedDefinition(kind, intent), layer); + } + + @Override + @NotNull + public Collection getDefinitions() { + return refinedResourceSchema.getDefinitions(); + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition( + ResourceShadowDiscriminator discriminator) { + return refinedResourceSchema.determineCompositeObjectClassDefinition(discriminator); + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition( + PrismObject shadow) throws SchemaException { + return refinedResourceSchema.determineCompositeObjectClassDefinition(shadow); + } + + @Override + @NotNull + public List getDefinitions(@NotNull Class type) { + return refinedResourceSchema.getDefinitions(type); + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition( + PrismObject shadow, Collection additionalAuxiliaryObjectClassQNames) throws SchemaException { + return refinedResourceSchema.determineCompositeObjectClassDefinition(shadow, additionalAuxiliaryObjectClassQNames); + } + + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition( + QName structuralObjectClassQName, ShadowKindType kind, String intent) { + return refinedResourceSchema.determineCompositeObjectClassDefinition(structuralObjectClassQName, kind, intent); + } + + @Override + public PrismContext getPrismContext() { + return refinedResourceSchema.getPrismContext(); + } + + @Override + @NotNull + public Document serializeToXsd() throws SchemaException { + return refinedResourceSchema.serializeToXsd(); + } + + @Override + public boolean isEmpty() { + return refinedResourceSchema.isEmpty(); + } + + @Override + public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, Collection intents) + throws SchemaException { + return refinedResourceSchema.getRefinedDefinition(kind, intents); + } + + @Override + public LayerRefinedObjectClassDefinition getRefinedDefinition(QName typeName) { + return LayerRefinedObjectClassDefinitionImpl + .wrap(refinedResourceSchema.getRefinedDefinition(typeName), layer); + } + + @Override + public LayerRefinedObjectClassDefinition getDefaultRefinedDefinition(ShadowKindType kind) { + return LayerRefinedObjectClassDefinitionImpl + .wrap(refinedResourceSchema.getDefaultRefinedDefinition(kind), layer); + } + + public LayerRefinedObjectClassDefinition findRefinedDefinitionByObjectClassQName(ShadowKindType kind, QName objectClass) { + return LayerRefinedObjectClassDefinitionImpl + .wrap(refinedResourceSchema.findRefinedDefinitionByObjectClassQName(kind, objectClass), layer); + } + + @Override + public ObjectClassComplexTypeDefinition findObjectClassDefinition(QName objectClassQName) { + return refinedResourceSchema.findObjectClassDefinition(objectClassQName); + } + + @Override + public LayerRefinedResourceSchema forLayer(LayerType layer) { + return refinedResourceSchema.forLayer(layer); + } + + @NotNull + @Override + public List findItemDefinitionsByCompileTimeClass( + @NotNull Class compileTimeClass, @NotNull Class definitionClass) { + return refinedResourceSchema.findItemDefinitionsByCompileTimeClass(compileTimeClass, definitionClass); + } + + @Override + @Nullable + public ID findItemDefinitionByType(@NotNull QName typeName, + @NotNull Class definitionClass) { + return refinedResourceSchema.findItemDefinitionByType(typeName, definitionClass); + } + + @Override + @NotNull + public List findItemDefinitionsByElementName(@NotNull QName elementName, + @NotNull Class definitionClass) { + return refinedResourceSchema.findItemDefinitionsByElementName(elementName, definitionClass); + } + + @Override + @Nullable + public TD findTypeDefinitionByCompileTimeClass(@NotNull Class compileTimeClass, @NotNull Class definitionClass) { + return refinedResourceSchema.findTypeDefinitionByCompileTimeClass(compileTimeClass, definitionClass); + } + + @Override + @Nullable + public TD findTypeDefinitionByType(@NotNull QName typeName, @NotNull Class definitionClass) { + return refinedResourceSchema.findTypeDefinitionByType(typeName, definitionClass); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((layer == null) ? 0 : layer.hashCode()); + result = prime * result + ((refinedResourceSchema == null) ? 0 : refinedResourceSchema.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LayerRefinedResourceSchemaImpl other = (LayerRefinedResourceSchemaImpl) obj; + if (layer != other.layer) + return false; + if (refinedResourceSchema == null) { + if (other.refinedResourceSchema != null) + return false; + } else if (!refinedResourceSchema.equals(other.refinedResourceSchema)) + return false; + return true; + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append("LRSchema(layer=").append(layer).append(",\n"); + sb.append(refinedResourceSchema.debugDump(indent + 1)); + return sb.toString(); + } + + @Override + public ObjectClassComplexTypeDefinition findObjectClassDefinition( + ShadowKindType kind, String intent) { + return refinedResourceSchema.findObjectClassDefinition(kind, intent); + } + + @Override + public List getRefinedDefinitions() { + return refinedResourceSchema.getRefinedDefinitions(); + } + + @Override + public ObjectClassComplexTypeDefinition findDefaultObjectClassDefinition( + ShadowKindType kind) { + return refinedResourceSchema.findDefaultObjectClassDefinition(kind); + } + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinition.java index 258627c57f0..a1167d13c0b 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinition.java @@ -13,593 +13,83 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.common.refinery; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; -import org.apache.commons.lang.BooleanUtils; +package com.evolveum.midpoint.common.refinery; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.schema.SchemaProcessorUtil; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; -import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.DisplayableValue; -import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.PropertyAccessType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.PropertyLimitationsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceAttributeDefinitionType; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.List; +import java.util.Map; /** - * @author semancik + * @author mederly */ -public class RefinedAttributeDefinition extends ResourceAttributeDefinition implements DebugDumpable { - - private static LayerType DEFAULT_LAYER = LayerType.MODEL; - - private String displayName; - private String description; - private boolean tolerant = true; - private boolean isExclusiveStrong = false; - protected boolean secondaryIdentifier = false; - private boolean isDisplayNameAttribute = false; - private List intolerantValuePattern; - private List tolerantValuePattern; - private ResourceAttributeDefinition attributeDefinition; - private AttributeFetchStrategyType fetchStrategy; - private MappingType outboundMappingType; - private List inboundMappingTypes; - private Map limitationsMap = new HashMap(); - private QName matchingRuleQName = null; - private Integer modificationPriority; - private Boolean readReplaceMode; - private PropertyAccessType accessOverride = new PropertyAccessType(); - private boolean isVolatilityTrigger = false; - - protected RefinedAttributeDefinition(ResourceAttributeDefinition attrDef, PrismContext prismContext) { - super(attrDef.getName(), attrDef.getTypeName(), prismContext); - this.attributeDefinition = attrDef; - } - - @Override - public void setNativeAttributeName(String nativeAttributeName) { - throw new UnsupportedOperationException("Parts of refined attribute are immutable"); - } - - public boolean isTolerant() { - return tolerant; - } - - public void setTolerant(boolean tolerant) { - this.tolerant = tolerant; - } - - public boolean isSecondaryIdentifier() { - return secondaryIdentifier; - } - - public void setSecondaryIdentifier(boolean secondaryIdentifier) { - this.secondaryIdentifier = secondaryIdentifier; - } - - @Override - public boolean canAdd() { - return canAdd(DEFAULT_LAYER); - } - - public boolean canAdd(LayerType layer) { - if (accessOverride.isAdd() != null) { - return accessOverride.isAdd(); - } - return limitationsMap.get(layer).getAccess().isAdd(); - } +public interface RefinedAttributeDefinition extends ResourceAttributeDefinition { + boolean isTolerant(); - @Override - public boolean canRead() { - return canRead(DEFAULT_LAYER); - } - - public boolean canRead(LayerType layer) { - if (accessOverride.isRead() != null) { - return accessOverride.isRead(); - } - return limitationsMap.get(layer).getAccess().isRead(); - } - - @Override - public boolean canModify() { - return canModify(DEFAULT_LAYER); - } - - public boolean canModify(LayerType layer) { - if (accessOverride.isModify() != null) { - return accessOverride.isModify(); - } - return limitationsMap.get(layer).getAccess().isModify(); - } - - @Override - public void setReadOnly() { - setCanRead(false); - } - - @Override - public QName getValueType() { - return attributeDefinition.getValueType(); - } - - @Override - public void setMinOccurs(int minOccurs) { - throw new UnsupportedOperationException("Parts of refined attribute are immutable"); - } - - @Override - public void setMaxOccurs(int maxOccurs) { - throw new UnsupportedOperationException("Parts of refined attribute are immutable"); - } - - @Override - public void setCanRead(boolean read) { - accessOverride.setRead(read); - } - - @Override - public void setCanModify(boolean update) { - accessOverride.setModify(update); - } - - @Override - public void setCanAdd(boolean create) { - accessOverride.setAdd(create); - } - - @Override - public boolean isIgnored() { - return isIgnored(DEFAULT_LAYER); - } - - public boolean isIgnored(LayerType layer) { - return limitationsMap.get(layer).isIgnore(); - } - - @Override - public void setIgnored(boolean ignored) { - throw new UnsupportedOperationException("Parts of refined attribute are immutable"); - } - - @Override - public void setHelp(String help) { - throw new UnsupportedOperationException("Parts of refined attribute are immutable"); - } - - @Override - public String getDisplayName() { - return displayName; - } - - @Override - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public ResourceAttributeDefinition getAttributeDefinition() { - return attributeDefinition; - } - - public void setAttributeDefinition(ResourceAttributeDefinition attributeDefinition) { - this.attributeDefinition = attributeDefinition; - } - - public MappingType getOutboundMappingType() { - return outboundMappingType; - } - - public void setOutboundMappingType(MappingType outboundMappingType) { - this.outboundMappingType = outboundMappingType; - } - - public boolean hasOutboundMapping() { - return outboundMappingType != null; - } - - public List getInboundMappingTypes() { - return inboundMappingTypes; - } - - public void setInboundMappingTypes(List inboundAssignmentTypes) { - this.inboundMappingTypes = inboundAssignmentTypes; - } - - public QName getName() { - return attributeDefinition.getName(); - } - - public QName getTypeName() { - return attributeDefinition.getTypeName(); - } - - public String getNativeAttributeName() { - return attributeDefinition.getNativeAttributeName(); - } - - public String getFrameworkAttributeName() { - return attributeDefinition.getFrameworkAttributeName(); - } - - public Collection> getAllowedValues() { - return attributeDefinition.getAllowedValues(); - } - - public boolean isReturnedByDefault() { - return attributeDefinition.isReturnedByDefault(); - } - - public void setReturnedByDefault(Boolean returnedByDefault) { - throw new UnsupportedOperationException("Cannot change returnedByDefault"); - } + boolean isSecondaryIdentifier(); + + boolean canAdd(LayerType layer); + + boolean canRead(LayerType layer); + + boolean canModify(LayerType layer); + + boolean isIgnored(LayerType layer); + + String getDescription(); + + ResourceAttributeDefinition getAttributeDefinition(); + MappingType getOutboundMappingType(); + + boolean hasOutboundMapping(); + + List getInboundMappingTypes(); + + int getMaxOccurs(LayerType layer); + + int getMinOccurs(LayerType layer); + + boolean isOptional(LayerType layer); + + boolean isMandatory(LayerType layer); + + boolean isMultiValue(LayerType layer); + + boolean isSingleValue(LayerType layer); + + boolean isExlusiveStrong(); + + PropertyLimitations getLimitations(LayerType layer); + + AttributeFetchStrategyType getFetchStrategy(); + + List getTolerantValuePattern(); + + List getIntolerantValuePattern(); + + boolean isVolatilityTrigger(); + + @NotNull @Override - public int getMaxOccurs() { - return getMaxOccurs(DEFAULT_LAYER); - } - - public int getMaxOccurs(LayerType layer) { - return limitationsMap.get(layer).getMaxOccurs(); - } - - @Override - public int getMinOccurs() { - return getMinOccurs(DEFAULT_LAYER); - } - - public int getMinOccurs(LayerType layer) { - return limitationsMap.get(layer).getMinOccurs(); - } - - public boolean isOptional(LayerType layer) { - return limitationsMap.get(layer).getMinOccurs() == 0; - } - - public boolean isMandatory(LayerType layer) { - return limitationsMap.get(layer).getMinOccurs() > 0; - } - - public boolean isMultiValue(LayerType layer) { - int maxOccurs = limitationsMap.get(layer).getMaxOccurs(); - return maxOccurs < 0 || maxOccurs > 1; - } - - public boolean isSingleValue(LayerType layer) { - return limitationsMap.get(layer).getMaxOccurs() == 1; - } - - public boolean isExlusiveStrong() { - return isExclusiveStrong; - } - - public void setExclusiveStrong(boolean isExclusiveStrong) { - this.isExclusiveStrong = isExclusiveStrong; - } - - public PropertyLimitations getLimitations(LayerType layer) { - return limitationsMap.get(layer); - } - - public String getHelp() { - return attributeDefinition.getHelp(); - } - - public AttributeFetchStrategyType getFetchStrategy() { - return fetchStrategy; - } - - public void setFetchStrategy(AttributeFetchStrategyType fetchStrategy) { - this.fetchStrategy = fetchStrategy; - } - - public QName getMatchingRuleQName() { - return matchingRuleQName; - } - - public void setMatchingRuleQName(QName matchingRuleQName) { - this.matchingRuleQName = matchingRuleQName; - } - - public List getTolerantValuePattern(){ - return tolerantValuePattern; - } - - public List getIntolerantValuePattern(){ - return intolerantValuePattern; - } - - public boolean isVolatilityTrigger() { - return isVolatilityTrigger; - } - - public void setVolatilityTrigger(boolean isVolatilityTrigger) { - this.isVolatilityTrigger = isVolatilityTrigger; - } - - // schemaHandlingAttrDefType may be null if we are parsing from schema only - static RefinedAttributeDefinition parse(ResourceAttributeDefinition schemaAttrDef, ResourceAttributeDefinitionType schemaHandlingAttrDefType, - ObjectClassComplexTypeDefinition objectClassDef, PrismContext prismContext, - String contextDescription) throws SchemaException { - - RefinedAttributeDefinition rAttrDef = new RefinedAttributeDefinition(schemaAttrDef, prismContext); - - if (schemaHandlingAttrDefType != null && schemaHandlingAttrDefType.getDisplayName() != null) { - rAttrDef.setDisplayName(schemaHandlingAttrDefType.getDisplayName()); - } else { - if (schemaAttrDef.getDisplayName() != null) { - rAttrDef.setDisplayName(schemaAttrDef.getDisplayName()); - } - } - - if (schemaHandlingAttrDefType != null && schemaHandlingAttrDefType.getDisplayOrder() != null) { - rAttrDef.setDisplayOrder(schemaHandlingAttrDefType.getDisplayOrder()); - } else { - if (schemaAttrDef.getDisplayOrder() != null) { - rAttrDef.setDisplayOrder(schemaAttrDef.getDisplayOrder()); - } - } - - rAttrDef.matchingRuleQName = schemaAttrDef.getMatchingRuleQName(); - if (schemaHandlingAttrDefType != null) { - rAttrDef.fetchStrategy = schemaHandlingAttrDefType.getFetchStrategy(); - if (schemaHandlingAttrDefType.getMatchingRule() != null) { - rAttrDef.matchingRuleQName = schemaHandlingAttrDefType.getMatchingRule(); - } - } - - PropertyLimitations schemaLimitations = getOrCreateLimitations(rAttrDef.limitationsMap, LayerType.SCHEMA); - schemaLimitations.setMinOccurs(schemaAttrDef.getMinOccurs()); - schemaLimitations.setMaxOccurs(schemaAttrDef.getMaxOccurs()); - schemaLimitations.setIgnore(schemaAttrDef.isIgnored()); - schemaLimitations.getAccess().setAdd(schemaAttrDef.canAdd()); - schemaLimitations.getAccess().setModify(schemaAttrDef.canModify()); - schemaLimitations.getAccess().setRead(schemaAttrDef.canRead()); - - if (schemaHandlingAttrDefType != null) { - - if (schemaHandlingAttrDefType.getDescription() != null) { - rAttrDef.setDescription(schemaHandlingAttrDefType.getDescription()); - } - - if (schemaHandlingAttrDefType.isTolerant() == null) { - rAttrDef.tolerant = true; - } else { - rAttrDef.tolerant = schemaHandlingAttrDefType.isTolerant(); - } - - if (schemaHandlingAttrDefType.isSecondaryIdentifier() == null) { - rAttrDef.secondaryIdentifier = false; - } else { - rAttrDef.secondaryIdentifier = schemaHandlingAttrDefType.isSecondaryIdentifier(); - } - - rAttrDef.tolerantValuePattern = schemaHandlingAttrDefType.getTolerantValuePattern(); - rAttrDef.intolerantValuePattern = schemaHandlingAttrDefType.getIntolerantValuePattern(); - - rAttrDef.isExclusiveStrong = BooleanUtils.isTrue(schemaHandlingAttrDefType.isExclusiveStrong()); - rAttrDef.isVolatilityTrigger = BooleanUtils.isTrue(schemaHandlingAttrDefType.isVolatilityTrigger()); - - if (schemaHandlingAttrDefType.getOutbound() != null) { - rAttrDef.setOutboundMappingType(schemaHandlingAttrDefType.getOutbound()); - } - - if (schemaHandlingAttrDefType.getInbound() != null) { - rAttrDef.setInboundMappingTypes(schemaHandlingAttrDefType.getInbound()); - } - - rAttrDef.setModificationPriority(schemaHandlingAttrDefType.getModificationPriority()); - - rAttrDef.setReadReplaceMode(schemaHandlingAttrDefType.isReadReplaceMode()); // may be null at this point - - if (schemaHandlingAttrDefType.isDisplayNameAttribute() != null && schemaHandlingAttrDefType.isDisplayNameAttribute()) { - rAttrDef.isDisplayNameAttribute = true; - } - } - - PropertyLimitations previousLimitations = null; - for (LayerType layer : LayerType.values()) { - PropertyLimitations limitations = getOrCreateLimitations(rAttrDef.limitationsMap, layer); - if (previousLimitations != null) { - limitations.setMinOccurs(previousLimitations.getMinOccurs()); - limitations.setMaxOccurs(previousLimitations.getMaxOccurs()); - limitations.setIgnore(previousLimitations.isIgnore()); - limitations.getAccess().setAdd(previousLimitations.getAccess().isAdd()); - limitations.getAccess().setRead(previousLimitations.getAccess().isRead()); - limitations.getAccess().setModify(previousLimitations.getAccess().isModify()); - } - previousLimitations = limitations; - if (schemaHandlingAttrDefType != null) { - if (layer != LayerType.SCHEMA) { - // SCHEMA is a pseudo-layer. It cannot be overriden ... unless specified explicitly - PropertyLimitationsType genericLimitationsType = MiscSchemaUtil.getLimitationsType(schemaHandlingAttrDefType.getLimitations(), null); - if (genericLimitationsType != null) { - applyLimitationsType(limitations, genericLimitationsType); - } - } - PropertyLimitationsType layerLimitationsType = MiscSchemaUtil.getLimitationsType(schemaHandlingAttrDefType.getLimitations(), layer); - if (layerLimitationsType != null) { - applyLimitationsType(limitations, layerLimitationsType); - } - } - } - - return rAttrDef; - - } - - private static void applyLimitationsType(PropertyLimitations limitations, PropertyLimitationsType layerLimitationsType) { - if (layerLimitationsType.getMinOccurs() != null) { - limitations.setMinOccurs(SchemaProcessorUtil.parseMultiplicity(layerLimitationsType.getMinOccurs())); - } - if (layerLimitationsType.getMaxOccurs() != null) { - limitations.setMaxOccurs(SchemaProcessorUtil.parseMultiplicity(layerLimitationsType.getMaxOccurs())); - } - if (layerLimitationsType.isIgnore() != null) { - limitations.setIgnore(layerLimitationsType.isIgnore()); - } - if (layerLimitationsType.getAccess() != null) { - PropertyAccessType accessType = layerLimitationsType.getAccess(); - if (accessType.isAdd() != null) { - limitations.getAccess().setAdd(accessType.isAdd()); - } - if (accessType.isRead() != null) { - limitations.getAccess().setRead(accessType.isRead()); - } - if (accessType.isModify() != null) { - limitations.getAccess().setModify(accessType.isModify()); - } - } - - } - - private static PropertyLimitations getOrCreateLimitations(Map limitationsMap, - LayerType layer) { - PropertyLimitations limitations = limitationsMap.get(layer); - if (limitations == null) { - limitations = new PropertyLimitations(); - limitationsMap.put(layer, limitations); - } - return limitations; - } - - static boolean isIgnored(ResourceAttributeDefinitionType attrDefType) throws SchemaException { - List limitations = attrDefType.getLimitations(); - if (limitations == null) { - return false; - } - PropertyLimitationsType limitationsType = MiscSchemaUtil.getLimitationsType(limitations, DEFAULT_LAYER); - if (limitationsType == null) { - return false; - } - if (limitationsType.isIgnore() == null) { - return false; - } - return limitationsType.isIgnore(); - } - - @Override - public RefinedAttributeDefinition clone() { - ResourceAttributeDefinition attrDefClone = this.attributeDefinition.clone(); - RefinedAttributeDefinition clone = new RefinedAttributeDefinition<>(attrDefClone, prismContext); - copyDefinitionData(clone); - return clone; - } - - protected void copyDefinitionData(RefinedAttributeDefinition clone) { - super.copyDefinitionData(clone); - clone.accessOverride = this.accessOverride.clone(); - clone.description = this.description; - clone.displayName = this.displayName; - clone.fetchStrategy = this.fetchStrategy; - clone.inboundMappingTypes = this.inboundMappingTypes; - clone.intolerantValuePattern = this.intolerantValuePattern; - clone.isExclusiveStrong = this.isExclusiveStrong; - clone.isVolatilityTrigger = this.isVolatilityTrigger; - clone.limitationsMap = this.limitationsMap; - clone.matchingRuleQName = this.matchingRuleQName; - clone.modificationPriority = this.modificationPriority; - clone.outboundMappingType = this.outboundMappingType; - clone.readReplaceMode = this.readReplaceMode; - clone.secondaryIdentifier = this.secondaryIdentifier; - clone.tolerant = this.tolerant; - clone.tolerantValuePattern = this.tolerantValuePattern; - } - - + RefinedAttributeDefinition clone(); @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(super.toString()); - if (getDisplayName() != null) { - sb.append(",Disp"); - } - if (getDescription() != null) { - sb.append(",Desc"); - } - if (getOutboundMappingType() != null) { - sb.append(",OUT"); - } - if (getInboundMappingTypes() != null) { - sb.append(",IN"); - } - if (Boolean.TRUE.equals(getReadReplaceMode())) { - sb.append(",R+E"); - } - if (getModificationPriority() != null) { - sb.append(",P").append(getModificationPriority()); - } - return sb.toString(); - } - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "rRAD"; - } - - @Override - public String debugDump(int indent) { - return debugDump(indent, null); - } - - String debugDump(int indent, LayerType layer) { - StringBuilder sb = new StringBuilder(); - sb.append(super.debugDump(indent)); - if (layer == null) { - sb.append("\n"); - DebugUtil.debugDumpMapSingleLine(sb, limitationsMap, indent + 1); - } else { - PropertyLimitations limitations = limitationsMap.get(layer); - if (limitations != null) { - sb.append(limitations.toString()); - } - } - return sb.toString(); - } - - public void setModificationPriority(Integer modificationPriority) { - this.modificationPriority = modificationPriority; - } - - public Integer getModificationPriority() { - return modificationPriority; - } - - public Boolean getReadReplaceMode() { // "get" instead of "is" because it may be null - return readReplaceMode; - } - - public void setReadReplaceMode(Boolean readReplaceMode) { - this.readReplaceMode = readReplaceMode; - } - - public boolean isDisplayNameAttribute() { - return isDisplayNameAttribute; - } + RefinedAttributeDefinition deepClone(Map ctdMap); + + String debugDump(int indent, LayerType layer); + + Integer getModificationPriority(); + + Boolean getReadReplaceMode(); + + boolean isDisplayNameAttribute(); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinitionImpl.java new file mode 100644 index 00000000000..487ca11335c --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAttributeDefinitionImpl.java @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinitionImpl; +import org.apache.commons.lang.BooleanUtils; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.schema.SchemaProcessorUtil; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.util.DebugDumpable; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.DisplayableValue; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PropertyAccessType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PropertyLimitationsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceAttributeDefinitionType; +import org.jetbrains.annotations.NotNull; + +/** + * @author semancik + */ +public class RefinedAttributeDefinitionImpl extends ResourceAttributeDefinitionImpl implements RefinedAttributeDefinition { + + private static LayerType DEFAULT_LAYER = LayerType.MODEL; + + private String displayName; + private String description; + private boolean tolerant = true; + private boolean isExclusiveStrong = false; + protected boolean secondaryIdentifier = false; + private boolean isDisplayNameAttribute = false; + private List intolerantValuePattern; + private List tolerantValuePattern; + private ResourceAttributeDefinition attributeDefinition; + private AttributeFetchStrategyType fetchStrategy; + private MappingType outboundMappingType; + private List inboundMappingTypes; + private Map limitationsMap = new HashMap<>(); + private QName matchingRuleQName = null; + private Integer modificationPriority; + private Boolean readReplaceMode; + private PropertyAccessType accessOverride = new PropertyAccessType(); + private boolean isVolatilityTrigger = false; + + protected RefinedAttributeDefinitionImpl(ResourceAttributeDefinition attrDef, PrismContext prismContext) { + super(attrDef.getName(), attrDef.getTypeName(), prismContext); + this.attributeDefinition = attrDef; + } + + @Override + public void setNativeAttributeName(String nativeAttributeName) { + throw new UnsupportedOperationException("Parts of refined attribute are immutable"); + } + + @Override + public boolean isTolerant() { + return tolerant; + } + + public void setTolerant(boolean tolerant) { + this.tolerant = tolerant; + } + + @Override + public boolean isSecondaryIdentifier() { + return secondaryIdentifier; + } + + public void setSecondaryIdentifier(boolean secondaryIdentifier) { + this.secondaryIdentifier = secondaryIdentifier; + } + + @Override + public boolean canAdd() { + return canAdd(DEFAULT_LAYER); + } + + @Override + public boolean canAdd(LayerType layer) { + if (accessOverride.isAdd() != null) { + return accessOverride.isAdd(); + } + return limitationsMap.get(layer).getAccess().isAdd(); + } + + @Override + public boolean canRead() { + return canRead(DEFAULT_LAYER); + } + + @Override + public boolean canRead(LayerType layer) { + if (accessOverride.isRead() != null) { + return accessOverride.isRead(); + } + return limitationsMap.get(layer).getAccess().isRead(); + } + + @Override + public boolean canModify() { + return canModify(DEFAULT_LAYER); + } + + @Override + public boolean canModify(LayerType layer) { + if (accessOverride.isModify() != null) { + return accessOverride.isModify(); + } + return limitationsMap.get(layer).getAccess().isModify(); + } + + @Override + public void setReadOnly() { + setCanRead(false); + } + + @Override + public QName getValueType() { + return attributeDefinition.getValueType(); + } + + @Override + public void setMinOccurs(int minOccurs) { + throw new UnsupportedOperationException("Parts of refined attribute are immutable"); + } + + @Override + public void setMaxOccurs(int maxOccurs) { + throw new UnsupportedOperationException("Parts of refined attribute are immutable"); + } + + @Override + public void setCanRead(boolean read) { + accessOverride.setRead(read); + } + + @Override + public void setCanModify(boolean update) { + accessOverride.setModify(update); + } + + @Override + public void setCanAdd(boolean create) { + accessOverride.setAdd(create); + } + + @Override + public boolean isIgnored() { + return isIgnored(DEFAULT_LAYER); + } + + @Override + public boolean isIgnored(LayerType layer) { + return limitationsMap.get(layer).isIgnore(); + } + + @Override + public void setIgnored(boolean ignored) { + throw new UnsupportedOperationException("Parts of refined attribute are immutable"); + } + + @Override + public void setHelp(String help) { + throw new UnsupportedOperationException("Parts of refined attribute are immutable"); + } + + @Override + public String getDisplayName() { + return displayName; + } + + @Override + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + @Override + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public ResourceAttributeDefinition getAttributeDefinition() { + return attributeDefinition; + } + + public void setAttributeDefinition(ResourceAttributeDefinition attributeDefinition) { + this.attributeDefinition = attributeDefinition; + } + + @Override + public MappingType getOutboundMappingType() { + return outboundMappingType; + } + + public void setOutboundMappingType(MappingType outboundMappingType) { + this.outboundMappingType = outboundMappingType; + } + + @Override + public boolean hasOutboundMapping() { + return outboundMappingType != null; + } + + @Override + public List getInboundMappingTypes() { + return inboundMappingTypes; + } + + public void setInboundMappingTypes(List inboundAssignmentTypes) { + this.inboundMappingTypes = inboundAssignmentTypes; + } + + @NotNull + public QName getName() { + return attributeDefinition.getName(); + } + + @NotNull + public QName getTypeName() { + return attributeDefinition.getTypeName(); + } + + public String getNativeAttributeName() { + return attributeDefinition.getNativeAttributeName(); + } + + public String getFrameworkAttributeName() { + return attributeDefinition.getFrameworkAttributeName(); + } + + public Collection> getAllowedValues() { + return attributeDefinition.getAllowedValues(); + } + + public boolean isReturnedByDefault() { + return attributeDefinition.isReturnedByDefault(); + } + + public void setReturnedByDefault(Boolean returnedByDefault) { + throw new UnsupportedOperationException("Cannot change returnedByDefault"); + } + + @Override + public int getMaxOccurs() { + return getMaxOccurs(DEFAULT_LAYER); + } + + @Override + public int getMaxOccurs(LayerType layer) { + return limitationsMap.get(layer).getMaxOccurs(); + } + + @Override + public int getMinOccurs() { + return getMinOccurs(DEFAULT_LAYER); + } + + @Override + public int getMinOccurs(LayerType layer) { + return limitationsMap.get(layer).getMinOccurs(); + } + + @Override + public boolean isOptional(LayerType layer) { + return limitationsMap.get(layer).getMinOccurs() == 0; + } + + @Override + public boolean isMandatory(LayerType layer) { + return limitationsMap.get(layer).getMinOccurs() > 0; + } + + @Override + public boolean isMultiValue(LayerType layer) { + int maxOccurs = limitationsMap.get(layer).getMaxOccurs(); + return maxOccurs < 0 || maxOccurs > 1; + } + + @Override + public boolean isSingleValue(LayerType layer) { + return limitationsMap.get(layer).getMaxOccurs() == 1; + } + + @Override + public boolean isExlusiveStrong() { + return isExclusiveStrong; + } + + public void setExclusiveStrong(boolean isExclusiveStrong) { + this.isExclusiveStrong = isExclusiveStrong; + } + + @Override + public PropertyLimitations getLimitations(LayerType layer) { + return limitationsMap.get(layer); + } + + public String getHelp() { + return attributeDefinition.getHelp(); + } + + @Override + public AttributeFetchStrategyType getFetchStrategy() { + return fetchStrategy; + } + + public void setFetchStrategy(AttributeFetchStrategyType fetchStrategy) { + this.fetchStrategy = fetchStrategy; + } + + public QName getMatchingRuleQName() { + return matchingRuleQName; + } + + public void setMatchingRuleQName(QName matchingRuleQName) { + this.matchingRuleQName = matchingRuleQName; + } + + @Override + public List getTolerantValuePattern(){ + return tolerantValuePattern; + } + + @Override + public List getIntolerantValuePattern(){ + return intolerantValuePattern; + } + + @Override + public boolean isVolatilityTrigger() { + return isVolatilityTrigger; + } + + public void setVolatilityTrigger(boolean isVolatilityTrigger) { + this.isVolatilityTrigger = isVolatilityTrigger; + } + + // schemaHandlingAttrDefType may be null if we are parsing from schema only + static RefinedAttributeDefinition parse(ResourceAttributeDefinition schemaAttrDef, ResourceAttributeDefinitionType schemaHandlingAttrDefType, + ObjectClassComplexTypeDefinition objectClassDef, PrismContext prismContext, + String contextDescription) throws SchemaException { + + RefinedAttributeDefinitionImpl rAttrDef = new RefinedAttributeDefinitionImpl(schemaAttrDef, prismContext); + + if (schemaHandlingAttrDefType != null && schemaHandlingAttrDefType.getDisplayName() != null) { + rAttrDef.setDisplayName(schemaHandlingAttrDefType.getDisplayName()); + } else { + if (schemaAttrDef.getDisplayName() != null) { + rAttrDef.setDisplayName(schemaAttrDef.getDisplayName()); + } + } + + if (schemaHandlingAttrDefType != null && schemaHandlingAttrDefType.getDisplayOrder() != null) { + rAttrDef.setDisplayOrder(schemaHandlingAttrDefType.getDisplayOrder()); + } else { + if (schemaAttrDef.getDisplayOrder() != null) { + rAttrDef.setDisplayOrder(schemaAttrDef.getDisplayOrder()); + } + } + + rAttrDef.matchingRuleQName = schemaAttrDef.getMatchingRuleQName(); + if (schemaHandlingAttrDefType != null) { + rAttrDef.fetchStrategy = schemaHandlingAttrDefType.getFetchStrategy(); + if (schemaHandlingAttrDefType.getMatchingRule() != null) { + rAttrDef.matchingRuleQName = schemaHandlingAttrDefType.getMatchingRule(); + } + } + + PropertyLimitations schemaLimitations = getOrCreateLimitations(rAttrDef.limitationsMap, LayerType.SCHEMA); + schemaLimitations.setMinOccurs(schemaAttrDef.getMinOccurs()); + schemaLimitations.setMaxOccurs(schemaAttrDef.getMaxOccurs()); + schemaLimitations.setIgnore(schemaAttrDef.isIgnored()); + schemaLimitations.getAccess().setAdd(schemaAttrDef.canAdd()); + schemaLimitations.getAccess().setModify(schemaAttrDef.canModify()); + schemaLimitations.getAccess().setRead(schemaAttrDef.canRead()); + + if (schemaHandlingAttrDefType != null) { + + if (schemaHandlingAttrDefType.getDescription() != null) { + rAttrDef.setDescription(schemaHandlingAttrDefType.getDescription()); + } + + if (schemaHandlingAttrDefType.isTolerant() == null) { + rAttrDef.tolerant = true; + } else { + rAttrDef.tolerant = schemaHandlingAttrDefType.isTolerant(); + } + + if (schemaHandlingAttrDefType.isSecondaryIdentifier() == null) { + rAttrDef.secondaryIdentifier = false; + } else { + rAttrDef.secondaryIdentifier = schemaHandlingAttrDefType.isSecondaryIdentifier(); + } + + rAttrDef.tolerantValuePattern = schemaHandlingAttrDefType.getTolerantValuePattern(); + rAttrDef.intolerantValuePattern = schemaHandlingAttrDefType.getIntolerantValuePattern(); + + rAttrDef.isExclusiveStrong = BooleanUtils.isTrue(schemaHandlingAttrDefType.isExclusiveStrong()); + rAttrDef.isVolatilityTrigger = BooleanUtils.isTrue(schemaHandlingAttrDefType.isVolatilityTrigger()); + + if (schemaHandlingAttrDefType.getOutbound() != null) { + rAttrDef.setOutboundMappingType(schemaHandlingAttrDefType.getOutbound()); + } + + if (schemaHandlingAttrDefType.getInbound() != null) { + rAttrDef.setInboundMappingTypes(schemaHandlingAttrDefType.getInbound()); + } + + rAttrDef.setModificationPriority(schemaHandlingAttrDefType.getModificationPriority()); + + rAttrDef.setReadReplaceMode(schemaHandlingAttrDefType.isReadReplaceMode()); // may be null at this point + + if (schemaHandlingAttrDefType.isDisplayNameAttribute() != null && schemaHandlingAttrDefType.isDisplayNameAttribute()) { + rAttrDef.isDisplayNameAttribute = true; + } + } + + PropertyLimitations previousLimitations = null; + for (LayerType layer : LayerType.values()) { + PropertyLimitations limitations = getOrCreateLimitations(rAttrDef.limitationsMap, layer); + if (previousLimitations != null) { + limitations.setMinOccurs(previousLimitations.getMinOccurs()); + limitations.setMaxOccurs(previousLimitations.getMaxOccurs()); + limitations.setIgnore(previousLimitations.isIgnore()); + limitations.getAccess().setAdd(previousLimitations.getAccess().isAdd()); + limitations.getAccess().setRead(previousLimitations.getAccess().isRead()); + limitations.getAccess().setModify(previousLimitations.getAccess().isModify()); + } + previousLimitations = limitations; + if (schemaHandlingAttrDefType != null) { + if (layer != LayerType.SCHEMA) { + // SCHEMA is a pseudo-layer. It cannot be overriden ... unless specified explicitly + PropertyLimitationsType genericLimitationsType = MiscSchemaUtil.getLimitationsType(schemaHandlingAttrDefType.getLimitations(), null); + if (genericLimitationsType != null) { + applyLimitationsType(limitations, genericLimitationsType); + } + } + PropertyLimitationsType layerLimitationsType = MiscSchemaUtil.getLimitationsType(schemaHandlingAttrDefType.getLimitations(), layer); + if (layerLimitationsType != null) { + applyLimitationsType(limitations, layerLimitationsType); + } + } + } + + return rAttrDef; + + } + + private static void applyLimitationsType(PropertyLimitations limitations, PropertyLimitationsType layerLimitationsType) { + if (layerLimitationsType.getMinOccurs() != null) { + limitations.setMinOccurs(SchemaProcessorUtil.parseMultiplicity(layerLimitationsType.getMinOccurs())); + } + if (layerLimitationsType.getMaxOccurs() != null) { + limitations.setMaxOccurs(SchemaProcessorUtil.parseMultiplicity(layerLimitationsType.getMaxOccurs())); + } + if (layerLimitationsType.isIgnore() != null) { + limitations.setIgnore(layerLimitationsType.isIgnore()); + } + if (layerLimitationsType.getAccess() != null) { + PropertyAccessType accessType = layerLimitationsType.getAccess(); + if (accessType.isAdd() != null) { + limitations.getAccess().setAdd(accessType.isAdd()); + } + if (accessType.isRead() != null) { + limitations.getAccess().setRead(accessType.isRead()); + } + if (accessType.isModify() != null) { + limitations.getAccess().setModify(accessType.isModify()); + } + } + + } + + private static PropertyLimitations getOrCreateLimitations(Map limitationsMap, + LayerType layer) { + PropertyLimitations limitations = limitationsMap.get(layer); + if (limitations == null) { + limitations = new PropertyLimitations(); + limitationsMap.put(layer, limitations); + } + return limitations; + } + + static boolean isIgnored(ResourceAttributeDefinitionType attrDefType) throws SchemaException { + List limitations = attrDefType.getLimitations(); + if (limitations == null) { + return false; + } + PropertyLimitationsType limitationsType = MiscSchemaUtil.getLimitationsType(limitations, DEFAULT_LAYER); + if (limitationsType == null) { + return false; + } + if (limitationsType.isIgnore() == null) { + return false; + } + return limitationsType.isIgnore(); + } + + @NotNull + @Override + public RefinedAttributeDefinition clone() { + ResourceAttributeDefinition attrDefClone = this.attributeDefinition.clone(); + RefinedAttributeDefinitionImpl clone = new RefinedAttributeDefinitionImpl(attrDefClone, prismContext); + copyDefinitionData(clone); + return clone; + } + + protected void copyDefinitionData(RefinedAttributeDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.accessOverride = this.accessOverride.clone(); + clone.description = this.description; + clone.displayName = this.displayName; + clone.fetchStrategy = this.fetchStrategy; + clone.inboundMappingTypes = this.inboundMappingTypes; + clone.intolerantValuePattern = this.intolerantValuePattern; + clone.isExclusiveStrong = this.isExclusiveStrong; + clone.isVolatilityTrigger = this.isVolatilityTrigger; + clone.limitationsMap = this.limitationsMap; + clone.matchingRuleQName = this.matchingRuleQName; + clone.modificationPriority = this.modificationPriority; + clone.outboundMappingType = this.outboundMappingType; + clone.readReplaceMode = this.readReplaceMode; + clone.secondaryIdentifier = this.secondaryIdentifier; + clone.tolerant = this.tolerant; + clone.tolerantValuePattern = this.tolerantValuePattern; + } + + @Override + public RefinedAttributeDefinition deepClone(Map ctdMap) { + return (RefinedAttributeDefinition) super.deepClone(ctdMap); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(super.toString()); + if (getDisplayName() != null) { + sb.append(",Disp"); + } + if (getDescription() != null) { + sb.append(",Desc"); + } + if (getOutboundMappingType() != null) { + sb.append(",OUT"); + } + if (getInboundMappingTypes() != null) { + sb.append(",IN"); + } + if (Boolean.TRUE.equals(getReadReplaceMode())) { + sb.append(",R+E"); + } + if (getModificationPriority() != null) { + sb.append(",P").append(getModificationPriority()); + } + return sb.toString(); + } + + /** + * Return a human readable name of this class suitable for logs. + */ + @Override + protected String getDebugDumpClassName() { + return "rRAD"; + } + + @Override + public String debugDump(int indent) { + return debugDump(indent, null); + } + + @Override + public String debugDump(int indent, LayerType layer) { + StringBuilder sb = new StringBuilder(); + sb.append(super.debugDump(indent)); + if (layer == null) { + sb.append("\n"); + DebugUtil.debugDumpMapSingleLine(sb, limitationsMap, indent + 1); + } else { + PropertyLimitations limitations = limitationsMap.get(layer); + if (limitations != null) { + sb.append(limitations.toString()); + } + } + return sb.toString(); + } + + public void setModificationPriority(Integer modificationPriority) { + this.modificationPriority = modificationPriority; + } + + @Override + public Integer getModificationPriority() { + return modificationPriority; + } + + @Override + public Boolean getReadReplaceMode() { // "get" instead of "is" because it may be null + return readReplaceMode; + } + + public void setReadReplaceMode(Boolean readReplaceMode) { + this.readReplaceMode = readReplaceMode; + } + + @Override + public boolean isDisplayNameAttribute() { + return isDisplayNameAttribute; + } +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchema.java index f9ce9629031..bd84fe23725 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchema.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,77 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.evolveum.midpoint.common.refinery; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.schema.PrismSchema; import com.evolveum.midpoint.schema.processor.ConnectorSchema; -import com.evolveum.midpoint.schema.util.ConnectorTypeUtil; import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; - -import org.w3c.dom.Element; /** - * @author semancik - * + * @author mederly */ -public class RefinedConnectorSchema extends PrismSchema implements DebugDumpable { - - private static final String USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA = RefinedConnectorSchema.class.getName()+".parsedConnectorSchema"; - - protected RefinedConnectorSchema(PrismContext prismContext) { - super(prismContext); - } - - public static ConnectorSchema getConnectorSchema(ConnectorType connectorType, PrismContext prismContext) throws SchemaException { - PrismObject connector = connectorType.asPrismObject(); - return getConnectorSchema(connector, prismContext); - } - - public static ConnectorSchema getConnectorSchema(PrismObject connector, PrismContext prismContext) throws SchemaException { - Element connectorXsdSchema = ConnectorTypeUtil.getConnectorXsdSchema(connector); - if (connectorXsdSchema == null) { - return null; - } - Object userDataEntry = connector.getUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA); - if (userDataEntry != null) { - if (userDataEntry instanceof ConnectorSchema) { - return (ConnectorSchema)userDataEntry; - } else { - throw new IllegalStateException("Expected ConnectorSchema under user data key "+ - USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA + "in "+connector+", but got "+userDataEntry.getClass()); - } - } else { - //InternalMonitor.recordConnectorSchemaParse(); - ConnectorSchema parsedSchema = ConnectorSchema.parse(connectorXsdSchema, "connector schema of "+connector, prismContext); - if (parsedSchema == null) { - throw new IllegalStateException("Parsed schema is null: most likely an internall error"); - } - parsedSchema.setUsualNamespacePrefix(ConnectorSchema.retrieveUsualNamespacePrefix(connector.asObjectable())); - connector.setUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA, parsedSchema); - return parsedSchema; - } - } - - public static void setParsedConnectorSchemaConditional(ConnectorType connectorType, ConnectorSchema parsedSchema) { - if (hasParsedSchema(connectorType)) { - return; - } - PrismObject connector = connectorType.asPrismObject(); - connector.setUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA, parsedSchema); - } - - public static boolean hasParsedSchema(ConnectorType connectorType) { - PrismObject connector = connectorType.asPrismObject(); - return connector.getUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA) != null; - } - - @Override - public String toString() { - return "rSchema(ns=" + namespace + ")"; - } - +public interface RefinedConnectorSchema extends ConnectorSchema { } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchemaImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchemaImpl.java new file mode 100644 index 00000000000..e68664ee4a7 --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedConnectorSchemaImpl.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010-2014 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.schema.PrismSchema; +import com.evolveum.midpoint.schema.processor.ConnectorSchema; +import com.evolveum.midpoint.schema.processor.ConnectorSchemaImpl; +import com.evolveum.midpoint.schema.util.ConnectorTypeUtil; +import com.evolveum.midpoint.util.DebugDumpable; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; + +import org.w3c.dom.Element; + +/** + * @author semancik + * + */ +public class RefinedConnectorSchemaImpl extends ConnectorSchemaImpl implements RefinedConnectorSchema { + + private static final String USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA = RefinedConnectorSchemaImpl.class.getName()+".parsedConnectorSchema"; + + protected RefinedConnectorSchemaImpl(PrismContext prismContext) { + super(prismContext); + } + + public static ConnectorSchema getConnectorSchema(ConnectorType connectorType, PrismContext prismContext) throws SchemaException { + PrismObject connector = connectorType.asPrismObject(); + return getConnectorSchema(connector, prismContext); + } + + public static ConnectorSchema getConnectorSchema(PrismObject connector, PrismContext prismContext) throws SchemaException { + Element connectorXsdSchema = ConnectorTypeUtil.getConnectorXsdSchema(connector); + if (connectorXsdSchema == null) { + return null; + } + Object userDataEntry = connector.getUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA); + if (userDataEntry != null) { + if (userDataEntry instanceof ConnectorSchema) { + return (ConnectorSchema)userDataEntry; + } else { + throw new IllegalStateException("Expected ConnectorSchema under user data key "+ + USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA + "in "+connector+", but got "+userDataEntry.getClass()); + } + } else { + //InternalMonitor.recordConnectorSchemaParse(); + ConnectorSchemaImpl parsedSchema = ConnectorSchemaImpl.parse(connectorXsdSchema, "connector schema of "+connector, prismContext); + if (parsedSchema == null) { + throw new IllegalStateException("Parsed schema is null: most likely an internall error"); + } + parsedSchema.setUsualNamespacePrefix(ConnectorSchemaImpl.retrieveUsualNamespacePrefix(connector.asObjectable())); + connector.setUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA, parsedSchema); + return parsedSchema; + } + } + + public static void setParsedConnectorSchemaConditional(ConnectorType connectorType, ConnectorSchema parsedSchema) { + if (hasParsedSchema(connectorType)) { + return; + } + PrismObject connector = connectorType.asPrismObject(); + connector.setUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA, parsedSchema); + } + + public static boolean hasParsedSchema(ConnectorType connectorType) { + PrismObject connector = connectorType.asPrismObject(); + return connector.getUserData(USER_DATA_KEY_PARSED_CONNECTOR_SCHEMA) != null; + } + + @Override + public String toString() { + return "rSchema(ns=" + namespace + ")"; + } + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index a6c27687d62..9c6dfcb8a5b 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -13,1150 +13,200 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.evolveum.midpoint.common.refinery; import com.evolveum.midpoint.common.ResourceObjectPattern; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.ComplexTypeDefinition; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.parser.QueryConvertor; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.util.ItemPathUtil; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.processor.*; -import com.evolveum.midpoint.schema.util.ResourceTypeUtil; -import com.evolveum.midpoint.schema.util.SchemaDebugUtil; -import com.evolveum.midpoint.schema.util.ObjectQueryUtil; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; -import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType; -import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; - -import javax.xml.namespace.QName; - -import org.apache.commons.lang.Validate; import org.jetbrains.annotations.NotNull; -import java.util.*; +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** - * @author semancik + * @author mederly */ -public class RefinedObjectClassDefinition extends ObjectClassComplexTypeDefinition implements DebugDumpable { - - private static final Trace LOGGER = TraceManager.getTrace(RefinedObjectClassDefinition.class); - - private String intent; - private String displayName; - private String description; - private boolean isDefault; - private ObjectClassComplexTypeDefinition objectClassDefinition; - private ResourceObjectTypeDefinitionType schemaHandlingObjectTypeDefinitionType; - private ResourceType resourceType; - private Collection> identifiers; - private Collection> secondaryIdentifiers; - private Collection protectedObjectPatterns; - private List> attributeDefinitions; - private Collection associations = new ArrayList(); - private Collection auxiliaryObjectClassDefinitions; - private ResourceObjectReferenceType baseContext; - private RefinedAttributeDefinition displayNameAttributeDefinition; - - /** - * Refined object definition. The "any" parts are replaced with appropriate schema (e.g. resource schema) - */ - PrismObjectDefinition objectDefinition = null; - private ShadowKindType kind = null; - - /** - * This is needed by the LayerRefinedObjectClassDefinition class - */ - protected RefinedObjectClassDefinition(QName typeName, PrismContext prismContext) { - super(typeName, prismContext); - } - - private RefinedObjectClassDefinition(PrismContext prismContext, ResourceType resourceType, - ObjectClassComplexTypeDefinition objectClassDefinition) { - super(objectClassDefinition.getTypeName(), prismContext); - Validate.notNull(objectClassDefinition, "ObjectClass definition must not be null"); - attributeDefinitions = new ArrayList<>(); - this.resourceType = resourceType; - this.objectClassDefinition = objectClassDefinition; - } - - /** - * Creates a derived version of this ROCD for a given layer. - * TODO clone if necessary/if specified (currently there is no cloning) - * - * @param layerType - * @return - */ - public LayerRefinedObjectClassDefinition forLayer(LayerType layerType) { - Validate.notNull(layerType); - return LayerRefinedObjectClassDefinition.wrap(this, layerType); - } - - @Override - public ResourceAttributeDefinition getDescriptionAttribute() { - return getObjectClassDefinition().getDescriptionAttribute(); - } - - @Override - public void setDescriptionAttribute(ResourceAttributeDefinition descriptionAttribute) { - throw new UnsupportedOperationException("Parts of refined account are immutable"); - } - - @Override - public RefinedAttributeDefinition getNamingAttribute() { - return substituteRefinedAttributeDefinition(getObjectClassDefinition().getNamingAttribute()); - } - - @Override - public QName getTypeName() { - return getObjectClassDefinition().getTypeName(); - } +public interface RefinedObjectClassDefinition extends ObjectClassComplexTypeDefinition { + + //region General attribute definitions ======================================================== + /** + * Returns definitions of all attributes as an unmodifiable collection. + * Note: content of this is exactly the same as for getDefinitions + */ + @NotNull @Override - public String getNativeObjectClass() { - return getObjectClassDefinition().getNativeObjectClass(); - } - - @Override - public boolean isDefaultInAKind() { - return isDefault; - } - - @Override - public void setDefaultInAKind(boolean defaultAccountType) { - this.isDefault = defaultAccountType; - } - - @Override - public String getIntent() { - return intent; - } - - @Override - public void setIntent(String intent) { - this.intent = intent; - } - - @Override - public ShadowKindType getKind() { - if (kind != null) { - return kind; - } - return getObjectClassDefinition().getKind(); + Collection> getAttributeDefinitions(); + + default boolean containsAttributeDefinition(ItemPathType pathType) { + QName segmentQName = ItemPathUtil.getOnlySegmentQName(pathType); + return containsAttributeDefinition(segmentQName); } - @Override - public void setKind(ShadowKindType kind) { - this.kind = kind; + default boolean containsAttributeDefinition(QName attributeName) { + return findAttributeDefinition(attributeName) != null; } + Collection getNamesOfAttributesWithOutboundExpressions(); + + Collection getNamesOfAttributesWithInboundExpressions(); + + //endregion + + //region Special attribute definitions ======================================================== + // Note that these are simply type-narrowed versions of methods in ObjectClassComplexTypeDefinition + + @NotNull @Override - public RefinedAttributeDefinition getDisplayNameAttribute() { - if (displayNameAttributeDefinition == null) { - ResourceAttributeDefinition displayNameAttribute = getObjectClassDefinition().getDisplayNameAttribute(); - if (displayNameAttribute == null) { - return null; - } - displayNameAttributeDefinition = substituteRefinedAttributeDefinition(displayNameAttribute); - } - return displayNameAttributeDefinition; - } - - @Override - public void setDisplayNameAttribute(QName displayName) { - throw new UnsupportedOperationException("Parts of refined account are immutable"); - } - - @Override - public Collection> getPrimaryIdentifiers() { - if (identifiers == null) { - identifiers = createIdentifiersCollection(); - } - return identifiers; - } + Collection> getPrimaryIdentifiers(); + @NotNull @Override - public Collection> getSecondaryIdentifiers() { - if (secondaryIdentifiers == null) { - secondaryIdentifiers = createIdentifiersCollection(); - } - return secondaryIdentifiers; - } - - public Collection> getAllIdentifiers() { - Collection> allIdentifiers = new ArrayList<>(); - if (identifiers != null) { - allIdentifiers.addAll((Collection)getPrimaryIdentifiers()); - } - if (secondaryIdentifiers != null) { - allIdentifiers.addAll((Collection)getSecondaryIdentifiers()); - } - return allIdentifiers; - } + Collection> getSecondaryIdentifiers(); - private Collection> createIdentifiersCollection() { - return new ArrayList<>(); - } - - public Collection getAssociations() { - return associations; - } - - public Collection getAssociations(ShadowKindType kind) { - Collection retAssoc = new ArrayList(); - for (RefinedAssociationDefinition association: associations) { - if (kind == association.getKind()) { - retAssoc.add(association); - } - } - return retAssoc; + @Override + default Collection> getAllIdentifiers() { + return Stream.concat(getPrimaryIdentifiers().stream(), getSecondaryIdentifiers().stream()) + .collect(Collectors.toList()); } - public RefinedAssociationDefinition findAssociation(QName name) { - for (RefinedAssociationDefinition assocType: getAssociations()) { - if (QNameUtil.match(assocType.getName(), name)) { - return assocType; - } - } - return null; - } + RefinedAttributeDefinition getDescriptionAttribute(); + RefinedAttributeDefinition getNamingAttribute(); + RefinedAttributeDefinition getDisplayNameAttribute(); - public Collection getEntitlementAssociations() { - return getAssociations(ShadowKindType.ENTITLEMENT); - } - - public RefinedAssociationDefinition findEntitlementAssociation(QName name) { - for (RefinedAssociationDefinition assocType: getEntitlementAssociations()) { - if (QNameUtil.match(assocType.getName(), name)) { - return assocType; - } - } - return null; - } - - public Collection getNamesOfAssociations() { - Collection names = new HashSet(); - for (RefinedAssociationDefinition assocDef : getAssociations()) { - names.add(assocDef.getName()); - } - return names; - } - - public Collection getNamesOfAssociationsWithOutboundExpressions() { - Collection names = new HashSet(); - for (RefinedAssociationDefinition assocDef : getAssociations()) { - if (assocDef.getOutboundMappingType() != null) { - names.add(assocDef.getName()); - } - } - return names; - } - - public Collection getAuxiliaryObjectClassDefinitions() { - return auxiliaryObjectClassDefinitions; - } - - public boolean hasAuxiliaryObjectClass(QName expectedObjectClassName) { - if (getAuxiliaryObjectClassDefinitions() == null) { - return false; - } - for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: getAuxiliaryObjectClassDefinitions()) { - if (QNameUtil.match(auxiliaryObjectClassDefinition.getTypeName(), expectedObjectClassName)) { - return true; - } - } - return false; - } + //endregion - public Collection getProtectedObjectPatterns() { - if (protectedObjectPatterns == null) { - protectedObjectPatterns = new ArrayList(); - } - return protectedObjectPatterns; - } - - public PrismContext getPrismContext() { - return getResourceType().asPrismObject().getPrismContext(); - } + //region General association definitions ======================================================== - @Override - public RefinedObjectClassDefinition clone() { - RefinedObjectClassDefinition clone = new RefinedObjectClassDefinition(getPrismContext(), resourceType, objectClassDefinition); - copyDefinitionData(clone); - return clone; - } - - private void copyDefinitionData(RefinedObjectClassDefinition clone) { - super.copyDefinitionData(clone); - clone.intent = this.intent; - clone.kind = this.kind; - clone.attributeDefinitions = cloneDefinitions(this.attributeDefinitions); - clone.identifiers = cloneDefinitions(this.identifiers); - clone.secondaryIdentifiers = cloneDefinitions(this.secondaryIdentifiers); - clone.associations = cloneAssociations(this.associations); - clone.baseContext = this.baseContext; - clone.description = this.description; - clone.displayName = this.displayName; - clone.isDefault = this.isDefault; - clone.objectClassDefinition = this.objectClassDefinition.clone(); - clone.objectDefinition = this.objectDefinition; - clone.resourceType = this.resourceType; - clone.protectedObjectPatterns = this.protectedObjectPatterns; - clone.resourceType = this.resourceType; - clone.schemaHandlingObjectTypeDefinitionType = this.schemaHandlingObjectTypeDefinitionType; - } - - private Collection cloneAssociations( - Collection origAsoc) { - if (origAsoc == null) { - return null; - } - Collection cloned = new ArrayList<>(); - for (RefinedAssociationDefinition rAsocDef: origAsoc) { - cloned.add(rAsocDef.clone()); - } - return cloned; - } + /** + * Returns definitions of all associations as an unmodifiable collection. + * Note: these items are _not_ included in getDefinitions. (BTW, RefinedAssociationDefinition + * is not a subtype of ItemDefinition, not even of Definition.) + */ + @NotNull + Collection getAssociationDefinitions(); - private List> cloneDefinitions(Collection> origDefs) { - if (origDefs == null) { - return null; - } - List> clonedAttributes = new ArrayList<>(); - for (RefinedAttributeDefinition attributeDefinition: origDefs) { - clonedAttributes.add(attributeDefinition.clone()); - } - return clonedAttributes; - } + Collection getAssociationDefinitions(ShadowKindType kind); - @Override - public RefinedAttributeDefinition findAttributeDefinition(QName elementQName) { - return findItemDefinition(elementQName, RefinedAttributeDefinition.class); - } - - @Override - public RefinedAttributeDefinition findAttributeDefinition(String elementLocalname) { - QName elementQName = new QName(getResourceNamespace(), elementLocalname); - return findAttributeDefinition(elementQName); - } - - protected String getResourceNamespace() { - return ResourceTypeUtil.getResourceNamespace(getResourceType()); + default Collection getEntitlementAssociationDefinitions() { + return getAssociationDefinitions(ShadowKindType.ENTITLEMENT); } - @Override - public String getDisplayName() { - return displayName; - } - - @Override - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public boolean isDefault() { - return isDefault; - } - - public void setDefault(boolean isDefault) { - this.isDefault = isDefault; - } - - public ObjectClassComplexTypeDefinition getObjectClassDefinition() { - return objectClassDefinition; - } - - public void setObjectClassDefinition(ObjectClassComplexTypeDefinition objectClassDefinition) { - Validate.notNull(objectClassDefinition, "ObjectClass definition must not be null"); - this.objectClassDefinition = objectClassDefinition; - } - - @Override - public Collection> getAttributeDefinitions() { - return attributeDefinitions; - } - - @Override - public List getDefinitions() { - return (List) getAttributeDefinitions(); - } - - public ResourceType getResourceType() { - return resourceType; - } - - public PrismObjectDefinition getObjectDefinition() { - if (objectDefinition == null) { - constructObjectDefinition(); - } - return objectDefinition; - } - - public ResourceObjectReferenceType getBaseContext() { - return baseContext; - } + RefinedAssociationDefinition findAssociationDefinition(QName name); - public void setBaseContext(ResourceObjectReferenceType baseContext) { - this.baseContext = baseContext; - } + RefinedAssociationDefinition findEntitlementAssociationDefinition(QName name); - private void constructObjectDefinition() { - // Almost-shallow clone of object definition and complex type - PrismObjectDefinition originalObjectDefinition = - getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); - PrismObjectDefinition refinedObjectDef = - originalObjectDefinition.cloneWithReplacedDefinition(ShadowType.F_ATTRIBUTES, - this.toResourceAttributeContainerDefinition()); - this.objectDefinition = refinedObjectDef; - } - - public RefinedAttributeDefinition getAttributeDefinition(QName attributeName) { - for (RefinedAttributeDefinition attrDef : getAttributeDefinitions()) { - if (QNameUtil.match(attrDef.getName(), attributeName)) { - return attrDef; - } - } - return null; - } - - - public void add(RefinedAttributeDefinition refinedAttributeDefinition) { - ((Collection)getAttributeDefinitions()).add(refinedAttributeDefinition); - } - - public boolean containsAttributeDefinition(ItemPathType pathType) { - QName segmentQName = ItemPathUtil.getOnlySegmentQName(pathType); - return containsAttributeDefinition(segmentQName); - } - - public boolean containsAttributeDefinition(QName attributeName) { - for (RefinedAttributeDefinition rAttributeDef : getAttributeDefinitions()) { - if (QNameUtil.match(rAttributeDef.getName(), attributeName)) { - return true; - } - } - return false; - } - - static RefinedObjectClassDefinition parse(ResourceObjectTypeDefinitionType entTypeDefType, - ResourceType resourceType, RefinedResourceSchema rSchema, ShadowKindType impliedKind, PrismContext prismContext, - String contextDescription) throws SchemaException { - - ShadowKindType kind = entTypeDefType.getKind(); - if (kind == null) { - kind = impliedKind; - } - if (kind == null) { - kind = ShadowKindType.ACCOUNT; - } - String intent = entTypeDefType.getIntent(); - if (intent == null) { - intent = SchemaConstants.INTENT_DEFAULT; - } - RefinedObjectClassDefinition rObjectClassDef = parseRefinedObjectClass(entTypeDefType, - resourceType, rSchema, prismContext, kind, intent, kind.value(), kind.value() + " type definition '"+intent+"' in " + contextDescription); - - if (entTypeDefType.getPagedSearches() != null) { - LOGGER.warn("PagedSearches element is no more supported and is ignored. Use PagedSearchCapabilityType instead. In {}", resourceType); - } - return rObjectClassDef; - } + Collection getNamesOfAssociations(); - private static void parseProtected(RefinedObjectClassDefinition rAccountDef, ResourceObjectTypeDefinitionType accountTypeDefType) throws SchemaException { - for (ResourceObjectPatternType protectedType: accountTypeDefType.getProtected()) { - ResourceObjectPattern protectedPattern = convertToPattern(protectedType, rAccountDef); - rAccountDef.getProtectedObjectPatterns().add(protectedPattern); - } - } - - private static ResourceObjectPattern convertToPattern(ResourceObjectPatternType patternType, RefinedObjectClassDefinition rAccountDef) throws SchemaException { - ResourceObjectPattern resourceObjectPattern = new ResourceObjectPattern(rAccountDef); - SearchFilterType filterType = patternType.getFilter(); - if (filterType != null) { - ObjectFilter filter = QueryConvertor.parseFilter(filterType, rAccountDef.getObjectDefinition()); - resourceObjectPattern.addFilter(filter); - return resourceObjectPattern; - } - - // Deprecated - if (patternType.getName() != null) { - RefinedAttributeDefinition attributeDefinition = rAccountDef.findAttributeDefinition(new QName(SchemaConstants.NS_ICF_SCHEMA,"name")); - if (attributeDefinition == null) { - throw new SchemaException("No ICF NAME attribute in schema as specified in the definition of protected objects (this is deprecated syntax anyway, convert it to filter)"); - } - ResourceAttribute attr = attributeDefinition.instantiate(); - attr.setRealValue(patternType.getName()); - resourceObjectPattern.addIdentifier(attr); - } else if (patternType.getUid() != null) { - RefinedAttributeDefinition attributeDefinition = rAccountDef.findAttributeDefinition(new QName(SchemaConstants.NS_ICF_SCHEMA,"uid")); - if (attributeDefinition == null) { - throw new SchemaException("No ICF UID attribute in schema as specified in the definition of protected objects (this is deprecated syntax anyway, convert it to filter)"); - } - ResourceAttribute attr = attributeDefinition.instantiate(); - attr.setRealValue(patternType.getUid()); - resourceObjectPattern.addIdentifier(attr); - } else { - throw new SchemaException("No filter and no deprecated name/uid in resource object pattern"); - } - return resourceObjectPattern; - } + Collection getNamesOfAssociationsWithOutboundExpressions(); + //endregion - public static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTypeDefinition objectClassDef, ResourceType resourceType, - RefinedResourceSchema rSchema, - PrismContext prismContext, String contextDescription) throws SchemaException { - - RefinedObjectClassDefinition rOcDef = new RefinedObjectClassDefinition(prismContext, resourceType, objectClassDef); - - String intent = objectClassDef.getIntent(); - if (intent == null && objectClassDef.isDefaultInAKind()) { - intent = SchemaConstants.INTENT_DEFAULT; - } - rOcDef.setIntent(intent); - - if (objectClassDef.getDisplayName() != null) { - rOcDef.setDisplayName(objectClassDef.getDisplayName()); - } - - rOcDef.setDefault(objectClassDef.isDefaultInAKind()); - - for (ResourceAttributeDefinition attrDef : objectClassDef.getAttributeDefinitions()) { - String attrContextDescription = intent + ", in " + contextDescription; - - RefinedAttributeDefinition rAttrDef = RefinedAttributeDefinition.parse(attrDef, null, objectClassDef, prismContext, - attrContextDescription); - rOcDef.processIdentifiers(rAttrDef, objectClassDef); - - if (rOcDef.containsAttributeDefinition(rAttrDef.getName())) { - throw new SchemaException("Duplicate definition of attribute " + rAttrDef.getName() + " in " + attrContextDescription); - } - rOcDef.add(rAttrDef); - - } - - return rOcDef; - - } - - private static RefinedObjectClassDefinition parseRefinedObjectClass(ResourceObjectTypeDefinitionType schemaHandlingObjDefType, - ResourceType resourceType, RefinedResourceSchema rSchema, PrismContext prismContext, - @NotNull ShadowKindType kind, @NotNull String intent, String typeDesc, String contextDescription) throws SchemaException { - - ObjectClassComplexTypeDefinition objectClassDef; - if (schemaHandlingObjDefType.getObjectClass() != null) { - QName objectClass = schemaHandlingObjDefType.getObjectClass(); - objectClassDef = rSchema.getOriginalResourceSchema().findObjectClassDefinition(objectClass); - if (objectClassDef == null) { - throw new SchemaException("Object class " + objectClass + " as specified in "+typeDesc+" type " + schemaHandlingObjDefType.getIntent() + " was not found in the resource schema of " + contextDescription); - } - } else { - throw new SchemaException("Definition of "+typeDesc+" type " + schemaHandlingObjDefType.getIntent() + " does not have objectclass, in " + contextDescription); - } - - RefinedObjectClassDefinition rOcDef = new RefinedObjectClassDefinition(prismContext, resourceType, objectClassDef); - rOcDef.setKind(kind); - rOcDef.schemaHandlingObjectTypeDefinitionType = schemaHandlingObjDefType; - rOcDef.setIntent(intent); - - if (schemaHandlingObjDefType.getDisplayName() != null) { - rOcDef.setDisplayName(schemaHandlingObjDefType.getDisplayName()); - } else { - if (objectClassDef.getDisplayName() != null) { - rOcDef.setDisplayName(objectClassDef.getDisplayName()); - } - } - - if (schemaHandlingObjDefType.getDescription() != null) { - rOcDef.setDescription(schemaHandlingObjDefType.getDescription()); - } - - if (schemaHandlingObjDefType.isDefault() != null) { - rOcDef.setDefault(schemaHandlingObjDefType.isDefault()); - } else { - rOcDef.setDefault(objectClassDef.isDefaultInAKind()); - } - - if (schemaHandlingObjDefType.getBaseContext() != null) { - rOcDef.setBaseContext(schemaHandlingObjDefType.getBaseContext()); - } - - return rOcDef; - } + //region General information ======================================================== - public void parseAssociations(RefinedResourceSchema rSchema) throws SchemaException { - if (schemaHandlingObjectTypeDefinitionType == null) { - return; - } - for (ResourceObjectAssociationType resourceObjectAssociationType: schemaHandlingObjectTypeDefinitionType.getAssociation()) { - RefinedAssociationDefinition rAssocDef = new RefinedAssociationDefinition(resourceObjectAssociationType); - ShadowKindType assocKind = rAssocDef.getKind(); - RefinedObjectClassDefinition assocTarget = rSchema.getRefinedDefinition(assocKind, rAssocDef.getIntents()); - rAssocDef.setAssociationTarget(assocTarget); - associations.add(rAssocDef); - } - } - - public void parseAuxiliaryObjectClasses(RefinedResourceSchema rSchema) throws SchemaException { - if (schemaHandlingObjectTypeDefinitionType == null) { - return; - } - List auxiliaryObjectClassQNames = schemaHandlingObjectTypeDefinitionType.getAuxiliaryObjectClass(); - auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); - for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { - RefinedObjectClassDefinition auxiliaryObjectClassDef = rSchema.getRefinedDefinition(auxiliaryObjectClassQName); - if (auxiliaryObjectClassDef == null) { - throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+this+" does not exist"); - } - auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); - } - } + String getDescription(); - public void parseAttributes(RefinedResourceSchema rSchema, String contextDescription) throws SchemaException { - if (schemaHandlingObjectTypeDefinitionType == null) { - // this is definition from schema. We already have all we need. - return; - } - - parseAttributesFrom(rSchema, getObjectClassDefinition(), false, contextDescription); - if (auxiliaryObjectClassDefinitions != null) { - for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { - parseAttributesFrom(rSchema, auxiliaryObjectClassDefinition, true, contextDescription); - } - } - - // Check for extra attribute definitions in the account type - for (ResourceAttributeDefinitionType attrDefType : schemaHandlingObjectTypeDefinitionType.getAttribute()) { - if (!containsAttributeDefinition(attrDefType.getRef()) && !RefinedAttributeDefinition.isIgnored(attrDefType)) { - throw new SchemaException("Definition of attribute " + attrDefType.getRef() + " not found in object class " + objectClassDefinition.getTypeName() + " as defined in " + contextDescription); - } - } - - parseProtected(this, schemaHandlingObjectTypeDefinitionType); - } - - public void parseAttributesFrom(RefinedResourceSchema rSchema, ObjectClassComplexTypeDefinition ocDef, boolean auxiliary, String contextDescription) throws SchemaException { - if (schemaHandlingObjectTypeDefinitionType == null) { - // this is definition from schema. We already have all we need. - return; - } - for (ResourceAttributeDefinition road : ocDef.getAttributeDefinitions()) { - String attrContextDescription = road.getName() + ", in " + contextDescription; - ResourceAttributeDefinitionType attrDefType = findAttributeDefinitionType(road.getName(), schemaHandlingObjectTypeDefinitionType, - attrContextDescription); - // We MUST NOT skip ignored attribute definitions here. We must include them in the schema as - // the shadows will still have that attributes and we will need their type definition to work - // well with them. They may also be mandatory. We cannot pretend that they do not exist. - - RefinedAttributeDefinition rAttrDef = RefinedAttributeDefinition.parse(road, attrDefType, ocDef, - prismContext, "in "+kind+" type " + intent + ", in " + contextDescription); - if (!auxiliary) { - processIdentifiers(rAttrDef, ocDef); - } - - if (containsAttributeDefinition(rAttrDef.getName())) { - if (auxiliary) { - continue; - } else { - throw new SchemaException("Duplicate definition of attribute " + rAttrDef.getName() + " in "+kind+" type " + - intent + ", in " + contextDescription); - } - } - add(rAttrDef); - - if (rAttrDef.isDisplayNameAttribute()) { - displayNameAttributeDefinition = rAttrDef; - } - - } - - - } + ObjectClassComplexTypeDefinition getObjectClassDefinition(); - private void processIdentifiers(RefinedAttributeDefinition rAttrDef, ObjectClassComplexTypeDefinition objectClassDef) { - QName attrName = rAttrDef.getName(); - if (objectClassDef.isPrimaryIdentifier(attrName)) { - ((Collection)getPrimaryIdentifiers()).add(rAttrDef); - } - if (objectClassDef.isSecondaryIdentifier(attrName) || rAttrDef.isSecondaryIdentifier()) { - ((Collection)getSecondaryIdentifiers()).add(rAttrDef); - } - } - - private RefinedAttributeDefinition substituteRefinedAttributeDefinition(ResourceAttributeDefinition attributeDef) { - RefinedAttributeDefinition rAttrDef = findAttributeDefinition(attributeDef.getName()); - return rAttrDef; - } + ResourceType getResourceType(); - private ResourceAttributeDefinitionType findAttributeDefinitionType(QName attrName, - ResourceObjectTypeDefinitionType rOcDefType, String contextDescription) throws SchemaException { - ResourceAttributeDefinitionType foundAttrDefType = null; - for (ResourceAttributeDefinitionType attrDefType : rOcDefType.getAttribute()) { - if (attrDefType.getRef() != null) { - QName ref = ItemPathUtil.getOnlySegmentQName(attrDefType.getRef()); - if (QNameUtil.match(ref, attrName)) { - if (foundAttrDefType == null) { - foundAttrDefType = attrDefType; - } else { - throw new SchemaException("Duplicate definition of attribute " + ref + " in "+kind+" type " - + rOcDefType.getIntent() + ", in " + contextDescription); - } - } - } else { - throw new SchemaException("Missing reference to the attribute schema definition in definition " + SchemaDebugUtil.prettyPrint(attrDefType) + " during processing of " + contextDescription); - } - } - return foundAttrDefType; - } - - - - public PrismObject createBlankShadow() { - PrismObject accountShadow; - try { - accountShadow = prismContext.getSchemaRegistry().instantiate(ShadowType.class); - } catch (SchemaException e) { - // This should not happen - throw new SystemException("Internal error instantiating account shadow: "+e.getMessage(), e); - } - ShadowType accountShadowType = accountShadow.asObjectable(); - - accountShadowType.setIntent(getIntent()); - accountShadowType.setKind(getKind()); - accountShadowType.setObjectClass(getObjectClassDefinition().getTypeName()); - accountShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(getResourceType())); - - // Setup definition - PrismObjectDefinition newDefinition = accountShadow.getDefinition().cloneWithReplacedDefinition( - ShadowType.F_ATTRIBUTES, toResourceAttributeContainerDefinition()); - accountShadow.setDefinition(newDefinition); - - return accountShadow; - } - - public ResourceShadowDiscriminator getShadowDiscriminator() { - return new ResourceShadowDiscriminator(getResourceType().getOid(), getKind(), getIntent()); - } - - public Collection getNamesOfAttributesWithOutboundExpressions() { - Collection attrNames = new HashSet(); - for (RefinedAttributeDefinition attrDef : getAttributeDefinitions()) { - if (attrDef.getOutboundMappingType() != null) { - attrNames.add(attrDef.getName()); - } - } - return attrNames; - } - - public Collection getNamesOfAttributesWithInboundExpressions() { - Collection attrNames = new HashSet(); - for (RefinedAttributeDefinition attrDef : getAttributeDefinitions()) { - List inbounds = attrDef.getInboundMappingTypes(); - if (inbounds != null && !inbounds.isEmpty()) { - attrNames.add(attrDef.getName()); - } - } - - return attrNames; - } - - public List getPasswordInbound() { - - ResourcePasswordDefinitionType password = getPasswordDefinition(); - - if (password == null || password.getInbound() == null) { - return null; - } - - return password.getInbound(); - } - - public MappingType getPasswordOutbound() { - - ResourcePasswordDefinitionType password = getPasswordDefinition(); - - if (password == null || password.getOutbound() == null) { - return null; - } - - return password.getOutbound(); - } - - public AttributeFetchStrategyType getPasswordFetchStrategy() { - ResourcePasswordDefinitionType password = getPasswordDefinition(); - if (password == null) { - return AttributeFetchStrategyType.IMPLICIT; - } - if (password.getFetchStrategy() == null) { - return AttributeFetchStrategyType.IMPLICIT; - } - return password.getFetchStrategy(); - } - - public ObjectReferenceType getPasswordPolicy(){ - ResourcePasswordDefinitionType password = getPasswordDefinition(); - - if (password == null || password.getPasswordPolicyRef() == null){ - return null; - } - - return password.getPasswordPolicyRef(); - } - - public ResourcePasswordDefinitionType getPasswordDefinition(){ - if (schemaHandlingObjectTypeDefinitionType == null) { - return null; - } - ResourceCredentialsDefinitionType credentials = schemaHandlingObjectTypeDefinitionType.getCredentials(); - if (credentials == null) { - return null; - } - - return credentials.getPassword(); - } - - public ResourceActivationDefinitionType getActivationSchemaHandling(){ - if (schemaHandlingObjectTypeDefinitionType == null) { - return null; - } - - return schemaHandlingObjectTypeDefinitionType.getActivation(); - } - - public ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName) { - ResourceActivationDefinitionType activationSchemaHandling = getActivationSchemaHandling(); - if (activationSchemaHandling == null) { - return null; - } - - if (QNameUtil.match(ActivationType.F_ADMINISTRATIVE_STATUS, propertyName)) { - return activationSchemaHandling.getAdministrativeStatus(); - } else if (QNameUtil.match(ActivationType.F_VALID_FROM, propertyName)) { - return activationSchemaHandling.getValidFrom(); - } else if (QNameUtil.match(ActivationType.F_VALID_TO, propertyName)) { - return activationSchemaHandling.getValidTo(); - } else if (QNameUtil.match(ActivationType.F_LOCKOUT_STATUS, propertyName)) { - return null; // todo implement this - } else if (QNameUtil.match(ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP, propertyName)) { - return null; // todo implement this - } else { - throw new IllegalArgumentException("Unknown activation property "+propertyName); - } - } - - public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) { - ResourceBidirectionalMappingType biType = getActivationBidirectionalMappingType(propertyName); - if (biType == null) { - return AttributeFetchStrategyType.IMPLICIT; - } - if (biType.getFetchStrategy() == null) { - return AttributeFetchStrategyType.IMPLICIT; - } - return biType.getFetchStrategy(); - } - - public T getEffectiveCapability(Class capabilityClass) { - return ResourceTypeUtil.getEffectiveCapability(getResourceType(), schemaHandlingObjectTypeDefinitionType, capabilityClass); - } + String getResourceNamespace(); - public PagedSearchCapabilityType getPagedSearches() { - return getEffectiveCapability(PagedSearchCapabilityType.class); - } - - public boolean isPagedSearchEnabled() { - return getPagedSearches() != null; // null means nothing or disabled - } - - public boolean isObjectCountingEnabled() { - return getEffectiveCapability(CountObjectsCapabilityType.class) != null; - } - - - - public boolean isAuxiliary() { - return getObjectClassDefinition().isAuxiliary(); - } + boolean isDefault(); - public boolean matches(ShadowType shadowType) { - if (shadowType == null) { - return false; - } - if (!QNameUtil.match(getObjectClassDefinition().getTypeName(), shadowType.getObjectClass())) { - return false; - } - if (shadowType.getKind() == null) { - if (kind != ShadowKindType.ACCOUNT) { - return false; - } - } else { - if (!MiscUtil.equals(kind, shadowType.getKind())) { - return false; - } - } - if (shadowType.getIntent() != null) { -// if (isDefault) { -// return true; -// } else { -// return false; -// } -// } else { - return MiscUtil.equals(intent, shadowType.getIntent()); - } - return true; - } + ResourceObjectReferenceType getBaseContext(); - @Override - public ObjectQuery createShadowSearchQuery(String resourceOid) throws SchemaException { - if (getKind() == null) { - return super.createShadowSearchQuery(resourceOid); - } else { - return ObjectQueryUtil.createResourceAndKindIntent(resourceOid, getKind(), getIntent(), getPrismContext()); - } - } + String getHumanReadableName(); + //endregion - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((associations == null) ? 0 : associations.hashCode()); - result = prime * result + ((attributeDefinitions == null) ? 0 : attributeDefinitions.hashCode()); - result = prime * result - + ((auxiliaryObjectClassDefinitions == null) ? 0 : auxiliaryObjectClassDefinitions.hashCode()); - result = prime * result + ((baseContext == null) ? 0 : baseContext.hashCode()); - result = prime * result + ((description == null) ? 0 : description.hashCode()); - result = prime * result + ((displayName == null) ? 0 : displayName.hashCode()); - result = prime * result - + ((displayNameAttributeDefinition == null) ? 0 : displayNameAttributeDefinition.hashCode()); - result = prime * result + ((identifiers == null) ? 0 : identifiers.hashCode()); - result = prime * result + ((intent == null) ? 0 : intent.hashCode()); - result = prime * result + (isDefault ? 1231 : 1237); - result = prime * result + ((kind == null) ? 0 : kind.hashCode()); - result = prime * result + ((objectClassDefinition == null) ? 0 : objectClassDefinition.hashCode()); - result = prime * result + ((objectDefinition == null) ? 0 : objectDefinition.hashCode()); - result = prime * result + ((protectedObjectPatterns == null) ? 0 : protectedObjectPatterns.hashCode()); - result = prime * result + ((resourceType == null) ? 0 : resourceType.hashCode()); - result = prime * result + ((schemaHandlingObjectTypeDefinitionType == null) ? 0 - : schemaHandlingObjectTypeDefinitionType.hashCode()); - result = prime * result + ((secondaryIdentifiers == null) ? 0 : secondaryIdentifiers.hashCode()); - return result; - } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - RefinedObjectClassDefinition other = (RefinedObjectClassDefinition) obj; - if (associations == null) { - if (other.associations != null) { - return false; - } - } else if (!associations.equals(other.associations)) { - return false; - } - if (attributeDefinitions == null) { - if (other.attributeDefinitions != null) { - return false; - } - } else if (!attributeDefinitions.equals(other.attributeDefinitions)) { - return false; - } - if (auxiliaryObjectClassDefinitions == null) { - if (other.auxiliaryObjectClassDefinitions != null) { - return false; - } - } else if (!auxiliaryObjectClassDefinitions.equals(other.auxiliaryObjectClassDefinitions)) { - return false; - } - if (baseContext == null) { - if (other.baseContext != null) { - return false; - } - } else if (!baseContext.equals(other.baseContext)) { - return false; - } - if (description == null) { - if (other.description != null) { - return false; - } - } else if (!description.equals(other.description)) { - return false; - } - if (displayName == null) { - if (other.displayName != null) { - return false; - } - } else if (!displayName.equals(other.displayName)) { - return false; - } - if (displayNameAttributeDefinition == null) { - if (other.displayNameAttributeDefinition != null) { - return false; - } - } else if (!displayNameAttributeDefinition.equals(other.displayNameAttributeDefinition)) { - return false; - } - if (identifiers == null) { - if (other.identifiers != null) { - return false; - } - } else if (!identifiers.equals(other.identifiers)) { - return false; - } - if (intent == null) { - if (other.intent != null) { - return false; - } - } else if (!intent.equals(other.intent)) { - return false; - } - if (isDefault != other.isDefault) { - return false; - } - if (kind != other.kind) { - return false; - } - if (objectClassDefinition == null) { - if (other.objectClassDefinition != null) { - return false; - } - } else if (!objectClassDefinition.equals(other.objectClassDefinition)) { - return false; - } - if (objectDefinition == null) { - if (other.objectDefinition != null) { - return false; - } - } else if (!objectDefinition.equals(other.objectDefinition)) { - return false; - } - if (protectedObjectPatterns == null) { - if (other.protectedObjectPatterns != null) { - return false; - } - } else if (!protectedObjectPatterns.equals(other.protectedObjectPatterns)) { - return false; - } - if (resourceType == null) { - if (other.resourceType != null) { - return false; - } - } else if (!resourceType.equals(other.resourceType)) { - return false; - } - if (schemaHandlingObjectTypeDefinitionType == null) { - if (other.schemaHandlingObjectTypeDefinitionType != null) { - return false; - } - } else if (!schemaHandlingObjectTypeDefinitionType.equals(other.schemaHandlingObjectTypeDefinitionType)) { - return false; - } - if (secondaryIdentifiers == null) { - if (other.secondaryIdentifiers != null) { - return false; - } - } else if (!secondaryIdentifiers.equals(other.secondaryIdentifiers)) { - return false; - } - return true; + //region Generating and matching artifacts ======================================================== + PrismObjectDefinition getObjectDefinition(); + + default PrismObject createBlankShadow() { + return createBlankShadow(this); } + PrismObject createBlankShadow(RefinedObjectClassDefinition definition); + + ResourceShadowDiscriminator getShadowDiscriminator(); + + boolean matches(ShadowType shadowType); + //endregion + + //region Accessing parts of schema handling ======================================================== + + @NotNull + Collection getAuxiliaryObjectClassDefinitions(); + + boolean hasAuxiliaryObjectClass(QName expectedObjectClassName); + + Collection getProtectedObjectPatterns(); + + ResourcePasswordDefinitionType getPasswordDefinition(); + + List getPasswordInbound(); + + MappingType getPasswordOutbound(); + + AttributeFetchStrategyType getPasswordFetchStrategy(); + + ObjectReferenceType getPasswordPolicy(); + + ResourceActivationDefinitionType getActivationSchemaHandling(); + + ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName); + + AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName); + //endregion + + //region Capabilities ======================================================== + + T getEffectiveCapability(Class capabilityClass); + + PagedSearchCapabilityType getPagedSearches(); + + boolean isPagedSearchEnabled(); + + boolean isObjectCountingEnabled(); + + //endregion + + //region Cloning ======================================================== + @NotNull @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - return debugDump(indent, null); - } - - protected String debugDump(int indent, LayerType layer) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < indent; i++) { - sb.append(INDENT_STRING); - } - sb.append(getDebugDumpClassName()).append("("); - sb.append(SchemaDebugUtil.prettyPrint(getTypeName())); - if (isDefault()) { - sb.append(",default"); - } - if (getKind() != null) { - sb.append(" ").append(getKind().value()); - } - sb.append(","); - if (getIntent() != null) { - sb.append("intent=").append(getIntent()); - } - if (layer != null) { - sb.append(",layer=").append(layer); - } - sb.append(")"); - for (RefinedAttributeDefinition rAttrDef: getAttributeDefinitions()) { - sb.append("\n"); - sb.append(rAttrDef.debugDump(indent + 1, layer)); - } - return sb.toString(); - } - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "rOCD"; - } - - public String getHumanReadableName() { - if (getDisplayName() != null) { - return getDisplayName(); - } else if (getKind() != null) { - return getKind()+":"+getIntent(); - } else if (getTypeName() != null) { - return getTypeName().getLocalPart(); - } else { - return "null"; - } - } - + RefinedObjectClassDefinition clone(); + + @NotNull @Override - public String toString() { - if (getKind() == null) { - return getDebugDumpClassName() + "("+PrettyPrinter.prettyPrint(getTypeName())+")"; - } else { - return getDebugDumpClassName() + "("+getKind()+":"+getIntent()+"="+PrettyPrinter.prettyPrint(getTypeName())+")"; - } + RefinedObjectClassDefinition deepClone(Map ctdMap); + //endregion + + LayerRefinedObjectClassDefinition forLayer(@NotNull LayerType layerType); + + //region Type variance ======================================================== + + RefinedAttributeDefinition findAttributeDefinition(@NotNull QName name); + + default RefinedAttributeDefinition findAttributeDefinition(String name) { + return findAttributeDefinition(new QName(getTypeName().getNamespaceURI(), name)); } + + //endregion + + String getDebugDumpClassName(); + } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java new file mode 100644 index 00000000000..214d79ccb4d --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinitionImpl.java @@ -0,0 +1,1258 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import com.evolveum.midpoint.common.ResourceObjectPattern; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.util.ItemPathUtil; +import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.processor.*; +import com.evolveum.midpoint.schema.util.ObjectQueryUtil; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.schema.util.ResourceTypeUtil; +import com.evolveum.midpoint.schema.util.SchemaDebugUtil; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsCapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.namespace.QName; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author semancik + */ +public class RefinedObjectClassDefinitionImpl implements RefinedObjectClassDefinition { + + private static final Trace LOGGER = TraceManager.getTrace(RefinedObjectClassDefinition.class); + + @NotNull private final List> attributeDefinitions = new ArrayList<>(); + @NotNull private final List associationDefinitions = new ArrayList<>(); + + @NotNull private final ObjectClassComplexTypeDefinition originalObjectClassDefinition; + @NotNull private final List auxiliaryObjectClassDefinitions = new ArrayList<>(); + + @NotNull private final ResourceType resourceType; + private ResourceObjectTypeDefinitionType schemaHandlingObjectTypeDefinitionType; + private String intent; + private ShadowKindType kind; + private String displayName; + private String description; + private boolean isDefault; + @NotNull private final List> identifiers = new ArrayList<>(); + @NotNull private final List> secondaryIdentifiers = new ArrayList<>(); + @NotNull private final List protectedObjectPatterns = new ArrayList<>(); + private ResourceObjectReferenceType baseContext; + private RefinedAttributeDefinition displayNameAttributeDefinition; + private RefinedAttributeDefinition namingAttributeDefinition; + private RefinedAttributeDefinition descriptionAttributeDefinition; + + /** + * Refined object definition. The "any" parts are replaced with appropriate schema (e.g. resource schema) + */ + private PrismObjectDefinition objectDefinition = null; + + private RefinedObjectClassDefinitionImpl(@NotNull ResourceType resourceType, @NotNull ObjectClassComplexTypeDefinition objectClassDefinition) { + this.resourceType = resourceType; + this.originalObjectClassDefinition = objectClassDefinition; + } + + //region General attribute definitions ======================================================== + @NotNull + @Override + public Collection> getAttributeDefinitions() { + return Collections.unmodifiableList(attributeDefinitions); + } + + @NotNull + @Override + public List getDefinitions() { + return (List) getAttributeDefinitions(); + } + + @Override + public Collection getNamesOfAttributesWithOutboundExpressions() { + return getAttributeDefinitions().stream() + .filter(attrDef -> attrDef.getOutboundMappingType() != null) + .map(attrDef -> attrDef.getName()) + .collect(Collectors.toCollection(HashSet::new)); + } + + @Override + public Collection getNamesOfAttributesWithInboundExpressions() { + return getAttributeDefinitions().stream() + .filter(attrDef -> CollectionUtils.isNotEmpty(attrDef.getInboundMappingTypes())) + .map(attrDef -> attrDef.getName()) + .collect(Collectors.toCollection(HashSet::new)); + } + + @Override + public ID findItemDefinition(@NotNull QName name, @NotNull Class clazz, + boolean caseInsensitive) { + for (ItemDefinition def : getDefinitions()) { + if (def.isValidFor(name, clazz, caseInsensitive)) { + return (ID) def; + } + } + return null; + } + + //endregion + + //region Special attribute definitions ======================================================== + @NotNull + @Override + public Collection> getPrimaryIdentifiers() { + return identifiers; + } + + @NotNull + @Override + public Collection> getSecondaryIdentifiers() { + return secondaryIdentifiers; + } + + @Override + public RefinedAttributeDefinition getDescriptionAttribute() { + return substituteRefinedAttributeDefinition( + () -> (RefinedAttributeDefinition) descriptionAttributeDefinition, + rad -> descriptionAttributeDefinition = rad, + originalObjectClassDefinition::getDescriptionAttribute + ); + } + + @Override + public RefinedAttributeDefinition getNamingAttribute() { + return substituteRefinedAttributeDefinition( + () -> (RefinedAttributeDefinition) namingAttributeDefinition, + rad -> namingAttributeDefinition = rad, + originalObjectClassDefinition::getNamingAttribute + ); + } + + @Override + public RefinedAttributeDefinition getDisplayNameAttribute() { + return substituteRefinedAttributeDefinition( + () -> (RefinedAttributeDefinition) displayNameAttributeDefinition, + rad -> displayNameAttributeDefinition = rad, + originalObjectClassDefinition::getDisplayNameAttribute + ); + } + + private RefinedAttributeDefinition substituteRefinedAttributeDefinition( + Supplier> getter, Consumer> setter, + Supplier> getterOfOriginal) { + RefinedAttributeDefinition value = getter.get(); + if (value == null) { + ResourceAttributeDefinition original = getterOfOriginal.get(); + if (original == null) { + return null; + } + value = findAttributeDefinition(original.getName()); + setter.accept(value); + } + return value; + } + //endregion + + //region General association definitions ======================================================== + @NotNull + @Override + public Collection getAssociationDefinitions() { + return Collections.unmodifiableList(associationDefinitions); + } + + @Override + public Collection getAssociationDefinitions(ShadowKindType kind) { + return Collections.unmodifiableList( + associationDefinitions.stream() + .filter(association -> kind == association.getKind()) + .collect(Collectors.toList())); + } + + @Override + public RefinedAssociationDefinition findAssociationDefinition(QName name) { + return associationDefinitions.stream() + .filter(a -> QNameUtil.match(a.getName(), name)) + .findFirst().orElse(null); + } + + @Override + public RefinedAssociationDefinition findEntitlementAssociationDefinition(QName name) { + return getEntitlementAssociationDefinitions().stream() + .filter(a -> QNameUtil.match(a.getName(), name)) + .findFirst().orElse(null); + } + + @Override + public Collection getNamesOfAssociations() { + return getAssociationDefinitions().stream() + .map(a -> a.getName()) + .collect(Collectors.toCollection(HashSet::new)); + } + + @Override + public Collection getNamesOfAssociationsWithOutboundExpressions() { + return getAssociationDefinitions().stream() + .filter(assocDef -> assocDef.getOutboundMappingType() != null) + .map(a -> a.getName()) + .collect(Collectors.toCollection(HashSet::new)); + } + //endregion + + //region General information ======================================================== + @Override + public String getDisplayName() { + return displayName; + } + + private void setDisplayName(String displayName) { + this.displayName = displayName; + } + + @Override + public String getDescription() { + return description; + } + + private void setDescription(String description) { + this.description = description; + } + + @Override + public ObjectClassComplexTypeDefinition getObjectClassDefinition() { + return originalObjectClassDefinition; + } + + @NotNull + @Override + public ResourceType getResourceType() { + return resourceType; + } + + @Override + public String getResourceNamespace() { + return ResourceTypeUtil.getResourceNamespace(getResourceType()); + } + + @Override + public boolean isDefault() { + return isDefault; + } + + private void setDefault(boolean isDefault) { + this.isDefault = isDefault; + } + + @Override + public boolean isDefaultInAKind() { + return isDefault; + } + + @Override + public ResourceObjectReferenceType getBaseContext() { + return baseContext; + } + + private void setBaseContext(ResourceObjectReferenceType baseContext) { + this.baseContext = baseContext; + } + + @Override + public String getIntent() { + return intent; + } + + public void setIntent(String intent) { + this.intent = intent; + } + + @Override + public ShadowKindType getKind() { + if (kind != null) { + return kind; + } + return getObjectClassDefinition().getKind(); + } + + public void setKind(ShadowKindType kind) { + this.kind = kind; + } + + //endregion + + //region Generating and matching artifacts ======================================================== + + @Override + public PrismObjectDefinition getObjectDefinition() { + if (objectDefinition == null) { + objectDefinition = constructObjectDefinition(this); + } + return objectDefinition; + } + + static PrismObjectDefinition constructObjectDefinition(RefinedObjectClassDefinition refinedObjectClassDefinition) { + // Almost-shallow clone of object definition and complex type + PrismObjectDefinition originalObjectDefinition = + refinedObjectClassDefinition.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); + return originalObjectDefinition.cloneWithReplacedDefinition(ShadowType.F_ATTRIBUTES, + refinedObjectClassDefinition.toResourceAttributeContainerDefinition()); + } + + @Override + public PrismObject createBlankShadow(RefinedObjectClassDefinition definition) { + PrismObject accountShadow; + try { + accountShadow = getPrismContext().createObject(ShadowType.class); + } catch (SchemaException e) { + // This should not happen + throw new SystemException("Internal error instantiating account shadow: "+e.getMessage(), e); + } + ShadowType accountShadowType = accountShadow.asObjectable(); + + accountShadowType.setIntent(getIntent()); + accountShadowType.setKind(getKind()); + accountShadowType.setObjectClass(getObjectClassDefinition().getTypeName()); + accountShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(getResourceType())); + + // Setup definition + PrismObjectDefinition newDefinition = accountShadow.getDefinition().cloneWithReplacedDefinition( + ShadowType.F_ATTRIBUTES, definition.toResourceAttributeContainerDefinition()); + accountShadow.setDefinition(newDefinition); + + return accountShadow; + } + + @Override + public ResourceShadowDiscriminator getShadowDiscriminator() { + return new ResourceShadowDiscriminator(getResourceType().getOid(), getKind(), getIntent()); + } + + @Override + public boolean matches(ShadowType shadowType) { + if (shadowType == null) { + return false; + } + if (!QNameUtil.match(getObjectClassDefinition().getTypeName(), shadowType.getObjectClass())) { + return false; + } + if (shadowType.getKind() == null) { + if (kind != ShadowKindType.ACCOUNT) { + return false; + } + } else { + if (!MiscUtil.equals(kind, shadowType.getKind())) { + return false; + } + } + if (shadowType.getIntent() != null) { + // if (isDefault) { + // return true; + // } else { + // return false; + // } + // } else { + return MiscUtil.equals(intent, shadowType.getIntent()); + } + return true; + } + + @Override + public ObjectQuery createShadowSearchQuery(String resourceOid) throws SchemaException { + if (getKind() == null) { + return ObjectQueryUtil.createResourceAndObjectClassQuery(resourceOid, getTypeName(), getPrismContext()); + } else { + return ObjectQueryUtil.createResourceAndKindIntent(resourceOid, getKind(), getIntent(), getPrismContext()); + } + } + //endregion + + //region Accessing parts of schema handling ======================================================== + @NotNull + @Override + public Collection getAuxiliaryObjectClassDefinitions() { + return auxiliaryObjectClassDefinitions; + } + + @Override + public boolean hasAuxiliaryObjectClass(QName expectedObjectClassName) { + return auxiliaryObjectClassDefinitions.stream() + .anyMatch(def -> QNameUtil.match(def.getTypeName(), expectedObjectClassName)); + } + + @Override + public Collection getProtectedObjectPatterns() { + return protectedObjectPatterns; + } + + @Override + public ResourcePasswordDefinitionType getPasswordDefinition() { + if (schemaHandlingObjectTypeDefinitionType == null) { + return null; + } + ResourceCredentialsDefinitionType credentials = schemaHandlingObjectTypeDefinitionType.getCredentials(); + if (credentials == null) { + return null; + } + return credentials.getPassword(); + } + + @Override + public List getPasswordInbound() { + ResourcePasswordDefinitionType password = getPasswordDefinition(); + if (password == null || password.getInbound() == null) { + return null; + } + return password.getInbound(); + } + + @Override + public MappingType getPasswordOutbound() { + ResourcePasswordDefinitionType password = getPasswordDefinition(); + if (password == null || password.getOutbound() == null) { + return null; + } + return password.getOutbound(); + } + + @Override + public AttributeFetchStrategyType getPasswordFetchStrategy() { + ResourcePasswordDefinitionType password = getPasswordDefinition(); + if (password == null) { + return AttributeFetchStrategyType.IMPLICIT; + } + if (password.getFetchStrategy() == null) { + return AttributeFetchStrategyType.IMPLICIT; + } + return password.getFetchStrategy(); + } + + @Override + public ObjectReferenceType getPasswordPolicy() { + ResourcePasswordDefinitionType password = getPasswordDefinition(); + if (password == null || password.getPasswordPolicyRef() == null){ + return null; + } + return password.getPasswordPolicyRef(); + } + + + @Override + public ResourceActivationDefinitionType getActivationSchemaHandling(){ + if (schemaHandlingObjectTypeDefinitionType == null) { + return null; + } + return schemaHandlingObjectTypeDefinitionType.getActivation(); + } + + @Override + public ResourceBidirectionalMappingType getActivationBidirectionalMappingType(QName propertyName) { + ResourceActivationDefinitionType activationSchemaHandling = getActivationSchemaHandling(); + if (activationSchemaHandling == null) { + return null; + } + if (QNameUtil.match(ActivationType.F_ADMINISTRATIVE_STATUS, propertyName)) { + return activationSchemaHandling.getAdministrativeStatus(); + } else if (QNameUtil.match(ActivationType.F_VALID_FROM, propertyName)) { + return activationSchemaHandling.getValidFrom(); + } else if (QNameUtil.match(ActivationType.F_VALID_TO, propertyName)) { + return activationSchemaHandling.getValidTo(); + } else if (QNameUtil.match(ActivationType.F_LOCKOUT_STATUS, propertyName)) { + return activationSchemaHandling.getLockoutStatus(); + } else if (QNameUtil.match(ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP, propertyName)) { + return null; // todo implement this + } else { + throw new IllegalArgumentException("Unknown activation property "+propertyName); + } + } + + @Override + public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) { + ResourceBidirectionalMappingType biType = getActivationBidirectionalMappingType(propertyName); + if (biType == null) { + return AttributeFetchStrategyType.IMPLICIT; + } + if (biType.getFetchStrategy() == null) { + return AttributeFetchStrategyType.IMPLICIT; + } + return biType.getFetchStrategy(); + } + //endregion + + //region Capabilities ======================================================== + @Override + public T getEffectiveCapability(Class capabilityClass) { + return ResourceTypeUtil.getEffectiveCapability(getResourceType(), schemaHandlingObjectTypeDefinitionType, capabilityClass); + } + + @Override + public PagedSearchCapabilityType getPagedSearches() { + return getEffectiveCapability(PagedSearchCapabilityType.class); + } + + @Override + public boolean isPagedSearchEnabled() { + return getPagedSearches() != null; // null means nothing or disabled + } + + @Override + public boolean isObjectCountingEnabled() { + return getEffectiveCapability(CountObjectsCapabilityType.class) != null; + } + //endregion + + //region Cloning ======================================================== + @NotNull + @Override + public RefinedObjectClassDefinitionImpl clone() { + RefinedObjectClassDefinitionImpl clone = new RefinedObjectClassDefinitionImpl(resourceType, originalObjectClassDefinition); + copyDefinitionData(clone); + return clone; + } + + // assuming we are called on empty object + private void copyDefinitionData(RefinedObjectClassDefinitionImpl clone) { + clone.attributeDefinitions.addAll(cloneDefinitions(this.attributeDefinitions)); + clone.associationDefinitions.addAll(cloneAssociations(this.associationDefinitions)); + clone.auxiliaryObjectClassDefinitions.addAll(auxiliaryObjectClassDefinitions); + clone.schemaHandlingObjectTypeDefinitionType = this.schemaHandlingObjectTypeDefinitionType; + clone.intent = this.intent; + clone.kind = this.kind; + clone.displayName = this.displayName; + clone.description = this.description; + clone.isDefault = this.isDefault; + clone.identifiers.addAll(cloneDefinitions(this.identifiers)); + clone.secondaryIdentifiers.addAll(cloneDefinitions(this.secondaryIdentifiers)); + clone.protectedObjectPatterns.addAll(this.protectedObjectPatterns); + clone.baseContext = this.baseContext; + } + + @NotNull + @Override + public RefinedObjectClassDefinition deepClone(Map ctdMap) { + // TODO TODO TODO (note that in original implementation this was also missing...) + return clone(); + } + + private Collection cloneAssociations(Collection origAsoc) { + return origAsoc.stream() + .map(RefinedAssociationDefinition::clone) + .collect(Collectors.toList()); + } + + private List> cloneDefinitions(Collection> origDefs) { + return origDefs.stream() + .map(RefinedAttributeDefinition::clone) + .collect(Collectors.toList()); + } + + //endregion + + /** + * Creates a derived version of this ROCD for a given layer. + * TODO clone if necessary/if specified (currently there is no cloning) + * + * @param layerType + * @return + */ + @Override + public LayerRefinedObjectClassDefinition forLayer(@NotNull LayerType layerType) { + Validate.notNull(layerType); + return LayerRefinedObjectClassDefinitionImpl.wrap(this, layerType); + } + + + //region Delegations ======================================================== + @NotNull + @Override + public QName getTypeName() { + return getObjectClassDefinition().getTypeName(); + } + + @Override + public String getNativeObjectClass() { + return getObjectClassDefinition().getNativeObjectClass(); + } + + public boolean isAuxiliary() { + return getObjectClassDefinition().isAuxiliary(); + } + + public PrismContext getPrismContext() { + return getResourceType().asPrismObject().getPrismContext(); + } + + @Nullable + @Override + public Class getCompileTimeClass() { + return originalObjectClassDefinition.getCompileTimeClass(); // most probably null + } + + @Nullable + @Override + public QName getExtensionForType() { + return originalObjectClassDefinition.getExtensionForType(); // most probably null + } + + @Override + public boolean isContainerMarker() { + return originalObjectClassDefinition.isContainerMarker(); // most probably false + } + + @Override + public boolean isObjectMarker() { + return originalObjectClassDefinition.isObjectMarker(); // most probably false + } + + @Override + public boolean isXsdAnyMarker() { + return originalObjectClassDefinition.isXsdAnyMarker(); + } + + // TODO + @Override + public ID findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + if (path.size() != 1) { + return null; + } + QName first = ItemPath.getFirstName(path); + if (first == null) { + return null; + } + return findItemDefinition(first, clazz); + } + + // TODO + @Override + public ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, + @NotNull Class clazz) { + return findItemDefinition(firstName); + } + + @Nullable + @Override + public String getDefaultNamespace() { + return originalObjectClassDefinition.getDefaultNamespace(); + } + + @Override + public boolean isRuntimeSchema() { + return originalObjectClassDefinition.isRuntimeSchema(); + } + + @NotNull + @Override + public List getIgnoredNamespaces() { + return originalObjectClassDefinition.getIgnoredNamespaces(); + } + + @Nullable + @Override + public QName getSuperType() { + return originalObjectClassDefinition.getSuperType(); + } + + @Override + public void merge(ComplexTypeDefinition otherComplexTypeDef) { + throw new UnsupportedOperationException("TODO implement this"); + } + + @Override + public void revive(PrismContext prismContext) { + originalObjectClassDefinition.revive(prismContext); + // TODO revive attributes + } + + @Override + public boolean isIgnored() { + return originalObjectClassDefinition.isIgnored(); + } + + @Override + public boolean isAbstract() { + return originalObjectClassDefinition.isAbstract(); + } + + @Override + public boolean isEmpty() { + return attributeDefinitions.isEmpty() && associationDefinitions.isEmpty(); + } + + @Override + public boolean isDeprecated() { + return originalObjectClassDefinition.isDeprecated(); + } + + @Override + public boolean isEmphasized() { + return originalObjectClassDefinition.isEmphasized(); + } + + @Override + public Integer getDisplayOrder() { + return originalObjectClassDefinition.getDisplayOrder(); + } + + @Override + public String getHelp() { + return originalObjectClassDefinition.getHelp(); + } + + @Override + public String getDocumentation() { + return originalObjectClassDefinition.getDocumentation(); + } + + @Override + public String getDocumentationPreview() { + return originalObjectClassDefinition.getDocumentationPreview(); + } + + @Override + public Class getTypeClassIfKnown() { + return originalObjectClassDefinition.getTypeClassIfKnown(); + } + + @Override + public Class getTypeClass() { + return originalObjectClassDefinition.getTypeClass(); + } + + @Override + public ResourceAttributeContainer instantiate(QName elementName) { + return ObjectClassComplexTypeDefinitionImpl.instantiate(elementName, this); + } + + //endregion + + //region ==== Parsing ================================================================================= + + static RefinedObjectClassDefinition parse(ResourceObjectTypeDefinitionType entTypeDefType, + ResourceType resourceType, RefinedResourceSchema rSchema, ShadowKindType impliedKind, PrismContext prismContext, + String contextDescription) throws SchemaException { + + ShadowKindType kind = entTypeDefType.getKind(); + if (kind == null) { + kind = impliedKind; + } + if (kind == null) { + kind = ShadowKindType.ACCOUNT; + } + String intent = entTypeDefType.getIntent(); + if (intent == null) { + intent = SchemaConstants.INTENT_DEFAULT; + } + RefinedObjectClassDefinition rObjectClassDef = parseRefinedObjectClass(entTypeDefType, + resourceType, rSchema, prismContext, kind, intent, kind.value(), kind.value() + " type definition '"+intent+"' in " + contextDescription); + + if (entTypeDefType.getPagedSearches() != null) { + LOGGER.warn("PagedSearches element is no more supported and is ignored. Use PagedSearchCapabilityType instead. In {}", resourceType); + } + return rObjectClassDef; + } + + private static void parseProtected(RefinedObjectClassDefinition rAccountDef, ResourceObjectTypeDefinitionType accountTypeDefType) throws SchemaException { + for (ResourceObjectPatternType protectedType: accountTypeDefType.getProtected()) { + ResourceObjectPattern protectedPattern = convertToPattern(protectedType, rAccountDef); + rAccountDef.getProtectedObjectPatterns().add(protectedPattern); + } + } + + private static ResourceObjectPattern convertToPattern(ResourceObjectPatternType patternType, RefinedObjectClassDefinition rAccountDef) throws SchemaException { + ResourceObjectPattern resourceObjectPattern = new ResourceObjectPattern(rAccountDef); + SearchFilterType filterType = patternType.getFilter(); + if (filterType != null) { + ObjectFilter filter = QueryConvertor.parseFilter(filterType, rAccountDef.getObjectDefinition()); + resourceObjectPattern.addFilter(filter); + return resourceObjectPattern; + } + + // Deprecated + if (patternType.getName() != null) { + RefinedAttributeDefinition attributeDefinition = rAccountDef.findAttributeDefinition(new QName(SchemaConstants.NS_ICF_SCHEMA,"name")); + if (attributeDefinition == null) { + throw new SchemaException("No ICF NAME attribute in schema as specified in the definition of protected objects (this is deprecated syntax anyway, convert it to filter)"); + } + ResourceAttribute attr = attributeDefinition.instantiate(); + attr.setRealValue(patternType.getName()); + resourceObjectPattern.addIdentifier(attr); + } else if (patternType.getUid() != null) { + RefinedAttributeDefinition attributeDefinition = rAccountDef.findAttributeDefinition(new QName(SchemaConstants.NS_ICF_SCHEMA,"uid")); + if (attributeDefinition == null) { + throw new SchemaException("No ICF UID attribute in schema as specified in the definition of protected objects (this is deprecated syntax anyway, convert it to filter)"); + } + ResourceAttribute attr = attributeDefinition.instantiate(); + attr.setRealValue(patternType.getUid()); + resourceObjectPattern.addIdentifier(attr); + } else { + throw new SchemaException("No filter and no deprecated name/uid in resource object pattern"); + } + return resourceObjectPattern; + } + + public static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTypeDefinition objectClassDef, ResourceType resourceType, + RefinedResourceSchema rSchema, + PrismContext prismContext, String contextDescription) throws SchemaException { + + RefinedObjectClassDefinitionImpl rOcDef = new RefinedObjectClassDefinitionImpl(resourceType, objectClassDef); + + String intent = objectClassDef.getIntent(); + if (intent == null && objectClassDef.isDefaultInAKind()) { + intent = SchemaConstants.INTENT_DEFAULT; + } + rOcDef.setIntent(intent); + + if (objectClassDef.getDisplayName() != null) { + rOcDef.setDisplayName(objectClassDef.getDisplayName()); + } + + rOcDef.setDefault(objectClassDef.isDefaultInAKind()); + + for (ResourceAttributeDefinition attrDef : objectClassDef.getAttributeDefinitions()) { + String attrContextDescription = intent + ", in " + contextDescription; + + RefinedAttributeDefinition rAttrDef = RefinedAttributeDefinitionImpl.parse(attrDef, null, objectClassDef, prismContext, + attrContextDescription); + rOcDef.processIdentifiers(rAttrDef, objectClassDef); + + if (rOcDef.containsAttributeDefinition(rAttrDef.getName())) { + throw new SchemaException("Duplicate definition of attribute " + rAttrDef.getName() + " in " + attrContextDescription); + } + rOcDef.add(rAttrDef); + + } + + return rOcDef; + + } + + private static RefinedObjectClassDefinition parseRefinedObjectClass(ResourceObjectTypeDefinitionType schemaHandlingObjDefType, + ResourceType resourceType, RefinedResourceSchema rSchema, PrismContext prismContext, + @NotNull ShadowKindType kind, @NotNull String intent, String typeDesc, String contextDescription) throws SchemaException { + + ObjectClassComplexTypeDefinition objectClassDef; + if (schemaHandlingObjDefType.getObjectClass() != null) { + QName objectClass = schemaHandlingObjDefType.getObjectClass(); + objectClassDef = rSchema.getOriginalResourceSchema().findObjectClassDefinition(objectClass); + if (objectClassDef == null) { + throw new SchemaException("Object class " + objectClass + " as specified in "+typeDesc+" type " + schemaHandlingObjDefType.getIntent() + " was not found in the resource schema of " + contextDescription); + } + } else { + throw new SchemaException("Definition of "+typeDesc+" type " + schemaHandlingObjDefType.getIntent() + " does not have objectclass, in " + contextDescription); + } + + RefinedObjectClassDefinitionImpl rOcDef = new RefinedObjectClassDefinitionImpl(resourceType, objectClassDef); + rOcDef.setKind(kind); + rOcDef.schemaHandlingObjectTypeDefinitionType = schemaHandlingObjDefType; + rOcDef.setIntent(intent); + + if (schemaHandlingObjDefType.getDisplayName() != null) { + rOcDef.setDisplayName(schemaHandlingObjDefType.getDisplayName()); + } else { + if (objectClassDef.getDisplayName() != null) { + rOcDef.setDisplayName(objectClassDef.getDisplayName()); + } + } + + if (schemaHandlingObjDefType.getDescription() != null) { + rOcDef.setDescription(schemaHandlingObjDefType.getDescription()); + } + + if (schemaHandlingObjDefType.isDefault() != null) { + rOcDef.setDefault(schemaHandlingObjDefType.isDefault()); + } else { + rOcDef.setDefault(objectClassDef.isDefaultInAKind()); + } + + if (schemaHandlingObjDefType.getBaseContext() != null) { + rOcDef.setBaseContext(schemaHandlingObjDefType.getBaseContext()); + } + + return rOcDef; + } + + void parseAssociations(RefinedResourceSchema rSchema) throws SchemaException { + if (schemaHandlingObjectTypeDefinitionType == null) { + return; + } + for (ResourceObjectAssociationType resourceObjectAssociationType: schemaHandlingObjectTypeDefinitionType.getAssociation()) { + RefinedAssociationDefinition rAssocDef = new RefinedAssociationDefinition(resourceObjectAssociationType); + ShadowKindType assocKind = rAssocDef.getKind(); + RefinedObjectClassDefinition assocTarget = rSchema.getRefinedDefinition(assocKind, rAssocDef.getIntents()); + rAssocDef.setAssociationTarget(assocTarget); + associationDefinitions.add(rAssocDef); + } + } + + void parseAuxiliaryObjectClasses(RefinedResourceSchema rSchema) throws SchemaException { + if (schemaHandlingObjectTypeDefinitionType == null) { + return; + } + List auxiliaryObjectClassQNames = schemaHandlingObjectTypeDefinitionType.getAuxiliaryObjectClass(); + for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { + RefinedObjectClassDefinition auxiliaryObjectClassDef = rSchema.getRefinedDefinition(auxiliaryObjectClassQName); + if (auxiliaryObjectClassDef == null) { + throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+this+" does not exist"); + } + auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); + } + } + + void parseAttributes(RefinedResourceSchema rSchema, String contextDescription) throws SchemaException { + if (schemaHandlingObjectTypeDefinitionType == null) { + // this is definition from schema. We already have all we need. + return; + } + + parseAttributesFrom(rSchema, getObjectClassDefinition(), false, contextDescription); + for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { + parseAttributesFrom(rSchema, auxiliaryObjectClassDefinition, true, contextDescription); + } + + // Check for extra attribute definitions in the account type + for (ResourceAttributeDefinitionType attrDefType : schemaHandlingObjectTypeDefinitionType.getAttribute()) { + if (!containsAttributeDefinition(attrDefType.getRef()) && !RefinedAttributeDefinitionImpl.isIgnored(attrDefType)) { + throw new SchemaException("Definition of attribute " + attrDefType.getRef() + " not found in object class " + originalObjectClassDefinition + .getTypeName() + " as defined in " + contextDescription); + } + } + + parseProtected(this, schemaHandlingObjectTypeDefinitionType); + } + + private void parseAttributesFrom(RefinedResourceSchema rSchema, ObjectClassComplexTypeDefinition ocDef, boolean auxiliary, + String contextDescription) throws SchemaException { + if (schemaHandlingObjectTypeDefinitionType == null) { + // this is definition from schema. We already have all we need. + return; + } + for (ResourceAttributeDefinition road : ocDef.getAttributeDefinitions()) { + String attrContextDescription = road.getName() + ", in " + contextDescription; + ResourceAttributeDefinitionType attrDefType = findAttributeDefinitionType(road.getName(), schemaHandlingObjectTypeDefinitionType, + attrContextDescription); + // We MUST NOT skip ignored attribute definitions here. We must include them in the schema as + // the shadows will still have that attributes and we will need their type definition to work + // well with them. They may also be mandatory. We cannot pretend that they do not exist. + + // TODO !!!! fix the cast + RefinedAttributeDefinition rAttrDef = (RefinedAttributeDefinition) RefinedAttributeDefinitionImpl.parse(road, attrDefType, ocDef, + rSchema.getPrismContext(), "in "+kind+" type " + intent + ", in " + contextDescription); + if (!auxiliary) { + processIdentifiers(rAttrDef, ocDef); + } + + if (containsAttributeDefinition(rAttrDef.getName())) { + if (auxiliary) { + continue; + } else { + throw new SchemaException("Duplicate definition of attribute " + rAttrDef.getName() + " in "+kind+" type " + + intent + ", in " + contextDescription); + } + } + add(rAttrDef); + + if (rAttrDef.isDisplayNameAttribute()) { + displayNameAttributeDefinition = rAttrDef; + } + + } + + + } + + private void processIdentifiers(RefinedAttributeDefinition rAttrDef, ObjectClassComplexTypeDefinition objectClassDef) { + QName attrName = rAttrDef.getName(); + if (objectClassDef.isPrimaryIdentifier(attrName)) { + ((Collection)getPrimaryIdentifiers()).add(rAttrDef); + } + if (objectClassDef.isSecondaryIdentifier(attrName) || rAttrDef.isSecondaryIdentifier()) { + ((Collection)getSecondaryIdentifiers()).add(rAttrDef); + } + } + + private ResourceAttributeDefinitionType findAttributeDefinitionType(QName attrName, + ResourceObjectTypeDefinitionType rOcDefType, String contextDescription) throws SchemaException { + ResourceAttributeDefinitionType foundAttrDefType = null; + for (ResourceAttributeDefinitionType attrDefType : rOcDefType.getAttribute()) { + if (attrDefType.getRef() != null) { + QName ref = ItemPathUtil.getOnlySegmentQName(attrDefType.getRef()); + if (QNameUtil.match(ref, attrName)) { + if (foundAttrDefType == null) { + foundAttrDefType = attrDefType; + } else { + throw new SchemaException("Duplicate definition of attribute " + ref + " in "+kind+" type " + + rOcDefType.getIntent() + ", in " + contextDescription); + } + } + } else { + throw new SchemaException("Missing reference to the attribute schema definition in definition " + SchemaDebugUtil.prettyPrint(attrDefType) + " during processing of " + contextDescription); + } + } + return foundAttrDefType; + } + + private void add(RefinedAttributeDefinition refinedAttributeDefinition) { + attributeDefinitions.add(refinedAttributeDefinition); + } + //endregion + + //region Diagnostic output, hashCode/equals ========================================================= + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + return debugDump(indent, null, this); + } + + public static String debugDump(int indent, LayerType layer, RefinedObjectClassDefinition _this) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(INDENT_STRING); + } + sb.append(_this.getDebugDumpClassName()).append("("); + sb.append(SchemaDebugUtil.prettyPrint(_this.getTypeName())); + if (_this.isDefault()) { + sb.append(",default"); + } + if (_this.getKind() != null) { + sb.append(" ").append(_this.getKind().value()); + } + sb.append(","); + if (_this.getIntent() != null) { + sb.append("intent=").append(_this.getIntent()); + } + if (layer != null) { + sb.append(",layer=").append(layer); + } + sb.append(")"); + for (RefinedAttributeDefinition rAttrDef: _this.getAttributeDefinitions()) { + sb.append("\n"); + sb.append(rAttrDef.debugDump(indent + 1, layer)); + } + return sb.toString(); + } + + /** + * Return a human readable name of this class suitable for logs. + */ + public String getDebugDumpClassName() { + return "rOCD"; + } + + @Override + public String getHumanReadableName() { + if (getDisplayName() != null) { + return getDisplayName(); + } else if (getKind() != null) { + return getKind()+":"+getIntent(); + } else { + return getTypeName().getLocalPart(); + } + } + + @Override + public String toString() { + if (getKind() == null) { + return getDebugDumpClassName() + "("+PrettyPrinter.prettyPrint(getTypeName())+")"; + } else { + return getDebugDumpClassName() + "("+getKind()+":"+getIntent()+"="+PrettyPrinter.prettyPrint(getTypeName())+")"; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + associationDefinitions.hashCode(); + result = prime * result + attributeDefinitions.hashCode(); + result = prime * result + auxiliaryObjectClassDefinitions.hashCode(); + result = prime * result + ((baseContext == null) ? 0 : baseContext.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((displayName == null) ? 0 : displayName.hashCode()); + result = prime * result + + ((displayNameAttributeDefinition == null) ? 0 : displayNameAttributeDefinition.hashCode()); + result = prime * result + ((identifiers == null) ? 0 : identifiers.hashCode()); + result = prime * result + ((intent == null) ? 0 : intent.hashCode()); + result = prime * result + (isDefault ? 1231 : 1237); + result = prime * result + ((kind == null) ? 0 : kind.hashCode()); + result = prime * result + originalObjectClassDefinition.hashCode(); + result = prime * result + ((objectDefinition == null) ? 0 : objectDefinition.hashCode()); + result = prime * result + ((protectedObjectPatterns == null) ? 0 : protectedObjectPatterns.hashCode()); + result = prime * result + resourceType.hashCode(); + result = prime * result + ((schemaHandlingObjectTypeDefinitionType == null) ? 0 + : schemaHandlingObjectTypeDefinitionType.hashCode()); + result = prime * result + ((secondaryIdentifiers == null) ? 0 : secondaryIdentifiers.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + RefinedObjectClassDefinitionImpl other = (RefinedObjectClassDefinitionImpl) obj; + if (!associationDefinitions.equals(other.associationDefinitions)) { + return false; + } + if (!attributeDefinitions.equals(other.attributeDefinitions)) { + return false; + } + if (!auxiliaryObjectClassDefinitions.equals(other.auxiliaryObjectClassDefinitions)) { + return false; + } + if (baseContext == null) { + if (other.baseContext != null) { + return false; + } + } else if (!baseContext.equals(other.baseContext)) { + return false; + } + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (displayName == null) { + if (other.displayName != null) { + return false; + } + } else if (!displayName.equals(other.displayName)) { + return false; + } + if (displayNameAttributeDefinition == null) { + if (other.displayNameAttributeDefinition != null) { + return false; + } + } else if (!displayNameAttributeDefinition.equals(other.displayNameAttributeDefinition)) { + return false; + } + if (identifiers == null) { + if (other.identifiers != null) { + return false; + } + } else if (!identifiers.equals(other.identifiers)) { + return false; + } + if (intent == null) { + if (other.intent != null) { + return false; + } + } else if (!intent.equals(other.intent)) { + return false; + } + if (isDefault != other.isDefault) { + return false; + } + if (kind != other.kind) { + return false; + } + if (!originalObjectClassDefinition.equals(other.originalObjectClassDefinition)) { + return false; + } + if (objectDefinition == null) { + if (other.objectDefinition != null) { + return false; + } + } else if (!objectDefinition.equals(other.objectDefinition)) { + return false; + } + if (protectedObjectPatterns == null) { + if (other.protectedObjectPatterns != null) { + return false; + } + } else if (!protectedObjectPatterns.equals(other.protectedObjectPatterns)) { + return false; + } + if (!resourceType.equals(other.resourceType)) { + return false; + } + if (schemaHandlingObjectTypeDefinitionType == null) { + if (other.schemaHandlingObjectTypeDefinitionType != null) { + return false; + } + } else if (!schemaHandlingObjectTypeDefinitionType.equals(other.schemaHandlingObjectTypeDefinitionType)) { + return false; + } + if (secondaryIdentifiers == null) { + if (other.secondaryIdentifiers != null) { + return false; + } + } else if (!secondaryIdentifiers.equals(other.secondaryIdentifiers)) { + return false; + } + return true; + } + //endregion + + //region Typing overhead ============================================================== + /* + * There is a natural correspondence between "type definition" classes and items in these classes: + * + * ComplexTypeDefinition .............................. ItemDefinition + * ObjectClassComplexTypeDefinition ................... ResourceAttributeDefinition + * RefinedObjectClassDefinition ....................... RefinedAttributeDefinition + * LayerRefinedObjectClassDefinition .................. LayerRefinedAttributeDefinition + * + * It would be great if the interface of "type definition" classes, i.e. methods like getDefinitions(), + * findItemDefinition, findAttributeDefinition, and so on would be parametrized on the type of item definitions + * from the list above. Unfortunately, this would make clients very unintuitive, using interfaces like + * + * RefinedObjectClassDefinition> + * + * Therefore the decision is to keep clients' lives simple; at the cost of "typing overhead" - providing correct + * signatures of derived types. In order to keep it manageable we put all such methods in this single section. + */ + + @Override + public RefinedAttributeDefinition findAttributeDefinition(@NotNull QName name) { + return findItemDefinition(name, RefinedAttributeDefinition.class, false); + } + + //endregion + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java index 383d8d4ef07..dd113518ab5 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java @@ -13,502 +13,90 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.common.refinery; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.util.QNameUtil; - -import org.apache.commons.lang.Validate; -import org.w3c.dom.Element; +package com.evolveum.midpoint.common.refinery; -import com.evolveum.midpoint.prism.Definition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.prism.schema.PrismSchema; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.ResourceSchema; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; -import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDefinitionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SchemaHandlingType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; + /** - * @author semancik - * + * @author mederly */ -public class RefinedResourceSchema extends ResourceSchema implements DebugDumpable { - - private static final String USER_DATA_KEY_PARSED_RESOURCE_SCHEMA = RefinedResourceSchema.class.getName()+".parsedResourceSchema"; - private static final String USER_DATA_KEY_REFINED_SCHEMA = RefinedResourceSchema.class.getName()+".refinedSchema"; - - private ResourceSchema originalResourceSchema; - - protected RefinedResourceSchema(PrismContext prismContext) { - super(prismContext); - } +public interface RefinedResourceSchema extends ResourceSchema, DebugDumpable { + List getRefinedDefinitions(); - private RefinedResourceSchema(ResourceType resourceType, ResourceSchema originalResourceSchema, PrismContext prismContext) { - super(ResourceTypeUtil.getResourceNamespace(resourceType), prismContext); - Validate.notNull(originalResourceSchema); - this.originalResourceSchema = originalResourceSchema; - } - - public List getRefinedDefinitions() { - List ocDefs = new ArrayList(); - for (Definition def: definitions) { - if (def instanceof RefinedObjectClassDefinition) { - RefinedObjectClassDefinition rOcDef = (RefinedObjectClassDefinition)def; - ocDefs.add(rOcDef); - } - } - return ocDefs; - } - - public Collection getRefinedDefinitions(ShadowKindType kind) { - Collection ocDefs = new ArrayList(); - for (Definition def: definitions) { - if ((def instanceof RefinedObjectClassDefinition) - && MiscSchemaUtil.matchesKind(kind, ((RefinedObjectClassDefinition) def).getKind())) { - RefinedObjectClassDefinition rOcDef = (RefinedObjectClassDefinition)def; - ocDefs.add(rOcDef); - } - } - return ocDefs; - } - - public ResourceSchema getOriginalResourceSchema() { - return originalResourceSchema; - } - - public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, ShadowType shadow) { + List getRefinedDefinitions(ShadowKindType kind); + + ResourceSchema getOriginalResourceSchema(); + + default RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, ShadowType shadow) { return getRefinedDefinition(kind, ShadowUtil.getIntent(shadow)); } - + /** * if null accountType is provided, default account definition is returned. */ - public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, String intent) { - for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { - if (intent == null && acctDef.isDefault()) { - return acctDef; - } - if (acctDef.getIntent() != null && acctDef.getIntent().equals(intent)) { - return acctDef; - } - if (acctDef.getIntent() == null && intent == null) { - return acctDef; - } - } - return null; - } - - public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(ResourceShadowDiscriminator discriminator) { - if (discriminator.getKind() == null && discriminator.getObjectClass() == null) { - return null; - } - RefinedObjectClassDefinition structuralObjectClassDefinition; - if (discriminator.getKind() == null && discriminator.getObjectClass() != null) { - structuralObjectClassDefinition = getRefinedDefinition(discriminator.getObjectClass()); - } else { - structuralObjectClassDefinition = getRefinedDefinition(discriminator.getKind(), discriminator.getIntent()); - } - if (structuralObjectClassDefinition == null) { - return null; - } - Collection auxiliaryObjectClassDefinitions = structuralObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); - return new CompositeRefinedObjectClassDefinition(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); - } - - public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(PrismObject shadow) throws SchemaException { - return determineCompositeObjectClassDefinition(shadow, null); - } - - public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(PrismObject shadow, - Collection additionalAuxiliaryObjectClassQNames) throws SchemaException { - ShadowType shadowType = shadow.asObjectable(); - - RefinedObjectClassDefinition structuralObjectClassDefinition = null; - ShadowKindType kind = shadowType.getKind(); - String intent = shadowType.getIntent(); - QName structuralObjectClassQName = shadowType.getObjectClass(); - - if (kind != null) { - structuralObjectClassDefinition = getRefinedDefinition(kind, intent); - } - - if (structuralObjectClassDefinition == null) { - // Fallback to objectclass only - if (structuralObjectClassQName == null) { - return null; - } - structuralObjectClassDefinition = getRefinedDefinition(structuralObjectClassQName); - } - - if (structuralObjectClassDefinition == null) { - return null; - } - List auxiliaryObjectClassQNames = shadowType.getAuxiliaryObjectClass(); - if (additionalAuxiliaryObjectClassQNames != null) { - auxiliaryObjectClassQNames.addAll(additionalAuxiliaryObjectClassQNames); - } - Collection auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); - for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { - RefinedObjectClassDefinition auxiliaryObjectClassDef = getRefinedDefinition(auxiliaryObjectClassQName); - if (auxiliaryObjectClassDef == null) { - throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+shadow+" does not exist"); - } - auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); - } - - return new CompositeRefinedObjectClassDefinition(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); - } - - public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(QName structuralObjectClassQName, ShadowKindType kind, String intent) { - RefinedObjectClassDefinition structuralObjectClassDefinition = null; - Collection auxiliaryObjectClassDefinitions; - if (kind != null) { - structuralObjectClassDefinition = getRefinedDefinition(kind, intent); - } - if (structuralObjectClassDefinition == null) { - // Fallback to objectclass only - if (structuralObjectClassQName == null) { - throw new IllegalArgumentException("No kind nor objectclass defined"); - } - structuralObjectClassDefinition = getRefinedDefinition(structuralObjectClassQName); - } - - if (structuralObjectClassDefinition == null) { - return null; - } + RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, String intent); - auxiliaryObjectClassDefinitions = structuralObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); - - return new CompositeRefinedObjectClassDefinition(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); - } + CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(ResourceShadowDiscriminator discriminator); - /** - * If no intents are provided, default account definition is returned. - * We check whether there is only one relevant rOCD. - */ - public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, Collection intents) throws SchemaException { - RefinedObjectClassDefinition found = null; - for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { - RefinedObjectClassDefinition foundCurrent = null; - if (intents == null || intents.isEmpty()) { - if (acctDef.isDefault()) { - foundCurrent = acctDef; - } - } else { - if (intents.contains(acctDef.getIntent())) { - foundCurrent = acctDef; - } - } - if (foundCurrent != null) { - if (found != null) { - if (!QNameUtil.match(found.getTypeName(), foundCurrent.getTypeName())) { - throw new SchemaException("More than one ObjectClass found for kind " + kind + ", intents: " + intents + ": " + found.getTypeName() + ", " + foundCurrent.getTypeName()); - } - } else { - found = foundCurrent; - } - } - } - return found; - } + CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(PrismObject shadow) throws + SchemaException; - public RefinedObjectClassDefinition getRefinedDefinition(QName objectClassName) { - for (Definition def: definitions) { - if ((def instanceof RefinedObjectClassDefinition) - && ((RefinedObjectClassDefinition)def).isDefault() - && (QNameUtil.match(def.getTypeName(), objectClassName))) { - //&& (def.getTypeName().equals(objectClassName))) { - return (RefinedObjectClassDefinition)def; - } - } - // No default for this object class, so just use the first one. - // This is not strictly correct .. but it is a "compatible bug" :-) - // TODO: remove this in next major revision - for (Definition def: definitions) { - if ((def instanceof RefinedObjectClassDefinition) - && (QNameUtil.match(def.getTypeName(), objectClassName))) { - //&& (def.getTypeName().equals(objectClassName))) { - return (RefinedObjectClassDefinition)def; - } - } - return null; - } - - public RefinedObjectClassDefinition getDefaultRefinedDefinition(ShadowKindType kind) { - return getRefinedDefinition(kind, (String)null); - } - - public PrismObjectDefinition getObjectDefinition(ShadowKindType kind, String intent) { - return getRefinedDefinition(kind, intent).getObjectDefinition(); - } - - public PrismObjectDefinition getObjectDefinition(ShadowKindType kind, ShadowType shadow) { - return getObjectDefinition(kind, ShadowUtil.getIntent(shadow)); - } - - private void add(RefinedObjectClassDefinition rOcDef) { - definitions.add(rOcDef); - } - - public RefinedObjectClassDefinition findRefinedDefinitionByObjectClassQName(ShadowKindType kind, QName objectClass) { - if (objectClass == null) { - return getDefaultRefinedDefinition(kind); - } - for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { - if (acctDef.isDefault() && QNameUtil.match(acctDef.getObjectClassDefinition().getTypeName(), objectClass)) { - return acctDef; - } - } - // No default for this object class, so just use the first one. - // This is not strictly correct .. but it is a "compatible bug" :-) - // TODO: remove this in next major revision - for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { - if (QNameUtil.match(acctDef.getObjectClassDefinition().getTypeName(), objectClass)) { - return acctDef; - } - } - return null; - } - - public ObjectClassComplexTypeDefinition findObjectClassDefinition(QName objectClassQName) { - return originalResourceSchema.findObjectClassDefinition(objectClassQName); - } - - public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType) throws SchemaException { - return getRefinedSchema(resourceType, resourceType.asPrismObject().getPrismContext()); - } - - public static LayerRefinedResourceSchema getRefinedSchema(ResourceType resourceType, LayerType layer) throws SchemaException { - return getRefinedSchema(resourceType, layer, resourceType.asPrismObject().getPrismContext()); - } + CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(PrismObject shadow, + Collection additionalAuxiliaryObjectClassQNames) throws SchemaException; - public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType, PrismContext prismContext) throws SchemaException { - PrismObject resource = resourceType.asPrismObject(); - return getRefinedSchema(resource, prismContext); - } - - public static LayerRefinedResourceSchema getRefinedSchema(ResourceType resourceType, LayerType layer, PrismContext prismContext) throws SchemaException { - PrismObject resource = resourceType.asPrismObject(); - return getRefinedSchema(resource, layer, prismContext); - } - - public static RefinedResourceSchema getRefinedSchema(PrismObject resource) throws SchemaException { - return getRefinedSchema(resource, resource.getPrismContext()); - } - - public static RefinedResourceSchema getRefinedSchema(PrismObject resource, PrismContext prismContext) throws SchemaException { - if (resource == null){ - throw new SchemaException("Could not get refined schema, resource does not exist."); - } - - Object userDataEntry = resource.getUserData(USER_DATA_KEY_REFINED_SCHEMA); - if (userDataEntry != null) { - if (userDataEntry instanceof RefinedResourceSchema) { - return (RefinedResourceSchema)userDataEntry; - } else { - throw new IllegalStateException("Expected RefinedResourceSchema under user data key "+USER_DATA_KEY_REFINED_SCHEMA+ - "in "+resource+", but got "+userDataEntry.getClass()); - } - } else { - RefinedResourceSchema refinedSchema = parse(resource, prismContext); - resource.setUserData(USER_DATA_KEY_REFINED_SCHEMA, refinedSchema); - return refinedSchema; - } - } - - public static LayerRefinedResourceSchema getRefinedSchema(PrismObject resource, LayerType layer, PrismContext prismContext) throws SchemaException { - RefinedResourceSchema refinedSchema = getRefinedSchema(resource, prismContext); - if (refinedSchema == null) { - return null; - } - return refinedSchema.forLayer(layer); - } - - public static boolean hasRefinedSchema(ResourceType resourceType) { - PrismObject resource = resourceType.asPrismObject(); - return resource.getUserData(USER_DATA_KEY_REFINED_SCHEMA) != null; - } - - public static ResourceSchema getResourceSchema(ResourceType resourceType, PrismContext prismContext) throws SchemaException { - PrismObject resource = resourceType.asPrismObject(); - return getResourceSchema(resource, prismContext); - } - - public static ResourceSchema getResourceSchema(PrismObject resource, PrismContext prismContext) throws SchemaException { - Element resourceXsdSchema = ResourceTypeUtil.getResourceXsdSchema(resource); - if (resourceXsdSchema == null) { - return null; - } - Object userDataEntry = resource.getUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA); - if (userDataEntry != null) { - if (userDataEntry instanceof ResourceSchema) { - return (ResourceSchema)userDataEntry; - } else { - throw new IllegalStateException("Expected ResourceSchema under user data key "+ - USER_DATA_KEY_PARSED_RESOURCE_SCHEMA+ "in "+resource+", but got "+userDataEntry.getClass()); - } - } else { - InternalMonitor.recordResourceSchemaParse(); - ResourceSchema parsedSchema = ResourceSchema.parse(resourceXsdSchema, "resource schema of "+resource, prismContext); - if (parsedSchema == null) { - throw new IllegalStateException("Parsed schema is null: most likely an internall error"); - } - resource.setUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA, parsedSchema); - return parsedSchema; - } - } - - public static void setParsedResourceSchemaConditional(ResourceType resourceType, ResourceSchema parsedSchema) { - if (hasParsedSchema(resourceType)) { - return; - } - PrismObject resource = resourceType.asPrismObject(); - resource.setUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA, parsedSchema); - } + CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(QName structuralObjectClassQName, + ShadowKindType kind, String intent); - public static boolean hasParsedSchema(ResourceType resourceType) { - PrismObject resource = resourceType.asPrismObject(); - return resource.getUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA) != null; - } + /** + * If no intents are provided, default account definition is returned. + * We check whether there is only one relevant rOCD. + */ + RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, Collection intents) throws SchemaException; - public static RefinedResourceSchema parse(PrismObject resource, PrismContext prismContext) throws SchemaException { - return parse(resource.asObjectable(), prismContext); - } - - public static RefinedResourceSchema parse(ResourceType resourceType, PrismContext prismContext) throws SchemaException { - - ResourceSchema originalResourceSchema = getResourceSchema(resourceType, prismContext); - if (originalResourceSchema == null) { - return null; - } - - String contextDescription = "definition of "+resourceType; - - RefinedResourceSchema rSchema = new RefinedResourceSchema(resourceType, originalResourceSchema, prismContext); - - SchemaHandlingType schemaHandling = resourceType.getSchemaHandling(); - if (schemaHandling != null) { - parseObjectTypeDefsFromSchemaHandling(rSchema, resourceType, schemaHandling, - schemaHandling.getObjectType(), null, prismContext, contextDescription); - } + RefinedObjectClassDefinition getRefinedDefinition(QName objectClassName); - parseObjectTypesFromSchema(rSchema, resourceType, prismContext, contextDescription); - - // We need to parse associations and auxiliary object classes in a second pass. We need to have all object classes parsed before correctly setting association - // targets - for (RefinedObjectClassDefinition rOcDef: rSchema.getRefinedDefinitions()) { - rOcDef.parseAssociations(rSchema); - rOcDef.parseAuxiliaryObjectClasses(rSchema); - } - - // We can parse attributes only after we have all the object class info parsed (including auxiliary object classes) - for (RefinedObjectClassDefinition rOcDef: rSchema.getRefinedDefinitions()) { - rOcDef.parseAttributes(rSchema, contextDescription); - } - - return rSchema; + default RefinedObjectClassDefinition getDefaultRefinedDefinition(ShadowKindType kind) { + return getRefinedDefinition(kind, (String)null); } - private static boolean hasAnyObjectTypeDef(SchemaHandlingType schemaHandling) { - if (schemaHandling == null) { - return false; - } - if (!schemaHandling.getObjectType().isEmpty()) { - return true; - } - return false; + default PrismObjectDefinition getObjectDefinition(ShadowKindType kind, String intent) { + return getRefinedDefinition(kind, intent).getObjectDefinition(); } - private static void parseObjectTypeDefsFromSchemaHandling(RefinedResourceSchema rSchema, ResourceType resourceType, - SchemaHandlingType schemaHandling, Collection resourceObjectTypeDefs, - ShadowKindType impliedKind, PrismContext prismContext, String contextDescription) throws SchemaException { - - if (resourceObjectTypeDefs == null) { - return; - } - - Map defaults = new HashMap(); - - for (ResourceObjectTypeDefinitionType accountTypeDefType: resourceObjectTypeDefs) { - RefinedObjectClassDefinition rOcDef = RefinedObjectClassDefinition.parse(accountTypeDefType, resourceType, rSchema, impliedKind, - prismContext, contextDescription); - - if (rOcDef.isDefault()) { - if (defaults.containsKey(rOcDef.getKind())) { - throw new SchemaException("More than one default "+rOcDef.getKind()+" definitions ("+defaults.get(rOcDef.getKind())+", "+rOcDef+") in " + contextDescription); - } else { - defaults.put(rOcDef.getKind(), rOcDef); - } - } - - rSchema.add(rOcDef); - } - } - -public static List getIntentsForKind(RefinedResourceSchema rSchema, ShadowKindType kind) { - List intents = new ArrayList<>(); - for (ObjectClassComplexTypeDefinition objClassDef : rSchema.getObjectClassDefinitions()) { - if (objClassDef.getKind() == kind){ - intents.add(objClassDef.getIntent()); - } - } - - return intents; - + default PrismObjectDefinition getObjectDefinition(ShadowKindType kind, ShadowType shadow) { + return getObjectDefinition(kind, ShadowUtil.getIntent(shadow)); } + RefinedObjectClassDefinition findRefinedDefinitionByObjectClassQName(ShadowKindType kind, QName objectClass); - private static void parseObjectTypesFromSchema(RefinedResourceSchema rSchema, ResourceType resourceType, - PrismContext prismContext, String contextDescription) throws SchemaException { + ObjectClassComplexTypeDefinition findObjectClassDefinition(QName objectClassQName); - RefinedObjectClassDefinition rAccountDefDefault = null; - for(ObjectClassComplexTypeDefinition objectClassDef: rSchema.getOriginalResourceSchema().getObjectClassDefinitions()) { - QName objectClassname = objectClassDef.getTypeName(); - if (rSchema.getRefinedDefinition(objectClassname) != null) { - continue; - } - RefinedObjectClassDefinition rOcDef = RefinedObjectClassDefinition.parseFromSchema(objectClassDef, resourceType, rSchema, prismContext, - "object class " + objectClassname + ", in " + contextDescription); - - if (objectClassDef.getKind() == ShadowKindType.ACCOUNT && rOcDef.isDefault()) { - if (rAccountDefDefault == null) { - rAccountDefDefault = rOcDef; - } else { - throw new SchemaException("More than one default account definitions ("+rAccountDefDefault+", "+rOcDef+") in " + contextDescription); - } - } - - rSchema.add(rOcDef); - } - } - - public LayerRefinedResourceSchema forLayer(LayerType layer) { - return LayerRefinedResourceSchema.wrap(this, layer); - } - - @Override - public String toString() { - return "rSchema(ns=" + namespace + ")"; + LayerRefinedResourceSchema forLayer(LayerType layer); + + static RefinedResourceSchema getRefinedSchema(PrismObject resource) throws SchemaException { + return RefinedResourceSchemaImpl.getRefinedSchema(resource); } + static ResourceSchema getResourceSchema(PrismObject resource, PrismContext prismContext) + throws SchemaException { + return RefinedResourceSchemaImpl.getRefinedSchema(resource, prismContext); + } } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchemaImpl.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchemaImpl.java new file mode 100644 index 00000000000..c49642b9f07 --- /dev/null +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchemaImpl.java @@ -0,0 +1,566 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.common.refinery; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; +import com.evolveum.midpoint.schema.internals.InternalMonitor; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceSchema; +import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.schema.util.ResourceTypeUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.namespace.QName; +import java.util.*; + +/** + * @author semancik + * + */ +public class RefinedResourceSchemaImpl implements RefinedResourceSchema { + + private static final String USER_DATA_KEY_PARSED_RESOURCE_SCHEMA = RefinedResourceSchema.class.getName()+".parsedResourceSchema"; + private static final String USER_DATA_KEY_REFINED_SCHEMA = RefinedResourceSchema.class.getName()+".refinedSchema"; + + // TODO really don't remember why we include originalResourceSchema here instead of simply extending ResourceSchemaImpl ... + // TODO Maybe that's because we need to create new RefinedResourceSchema(s) based on existing ResourceSchema(s)? + private ResourceSchema originalResourceSchema; + + private RefinedResourceSchemaImpl(@NotNull ResourceSchema originalResourceSchema) { + this.originalResourceSchema = originalResourceSchema; + } + + @Override + public List getRefinedDefinitions() { + return originalResourceSchema.getDefinitions(RefinedObjectClassDefinition.class); + } + + @Override + public List getRefinedDefinitions(ShadowKindType kind) { + List rv = new ArrayList<>(); + for (RefinedObjectClassDefinition def: getRefinedDefinitions()) { + if (MiscSchemaUtil.matchesKind(kind, def.getKind())) { + rv.add(def); + } + } + return rv; + } + + @Override + public ResourceSchema getOriginalResourceSchema() { + return originalResourceSchema; + } + + @Override + public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, String intent) { + for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { + if (intent == null && acctDef.isDefault()) { + return acctDef; + } + if (acctDef.getIntent() != null && acctDef.getIntent().equals(intent)) { + return acctDef; + } + if (acctDef.getIntent() == null && intent == null) { + return acctDef; + } + } + return null; + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(ResourceShadowDiscriminator discriminator) { + if (discriminator.getKind() == null && discriminator.getObjectClass() == null) { + return null; + } + RefinedObjectClassDefinition structuralObjectClassDefinition; + if (discriminator.getKind() == null && discriminator.getObjectClass() != null) { + structuralObjectClassDefinition = getRefinedDefinition(discriminator.getObjectClass()); + } else { + structuralObjectClassDefinition = getRefinedDefinition(discriminator.getKind(), discriminator.getIntent()); + } + if (structuralObjectClassDefinition == null) { + return null; + } + Collection auxiliaryObjectClassDefinitions = structuralObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); + return new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(PrismObject shadow) throws SchemaException { + return determineCompositeObjectClassDefinition(shadow, null); + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(PrismObject shadow, + Collection additionalAuxiliaryObjectClassQNames) throws SchemaException { + ShadowType shadowType = shadow.asObjectable(); + + RefinedObjectClassDefinition structuralObjectClassDefinition = null; + ShadowKindType kind = shadowType.getKind(); + String intent = shadowType.getIntent(); + QName structuralObjectClassQName = shadowType.getObjectClass(); + + if (kind != null) { + structuralObjectClassDefinition = getRefinedDefinition(kind, intent); + } + + if (structuralObjectClassDefinition == null) { + // Fallback to objectclass only + if (structuralObjectClassQName == null) { + return null; + } + structuralObjectClassDefinition = getRefinedDefinition(structuralObjectClassQName); + } + + if (structuralObjectClassDefinition == null) { + return null; + } + List auxiliaryObjectClassQNames = shadowType.getAuxiliaryObjectClass(); + if (additionalAuxiliaryObjectClassQNames != null) { + auxiliaryObjectClassQNames.addAll(additionalAuxiliaryObjectClassQNames); + } + Collection auxiliaryObjectClassDefinitions = new ArrayList<>(auxiliaryObjectClassQNames.size()); + for (QName auxiliaryObjectClassQName: auxiliaryObjectClassQNames) { + RefinedObjectClassDefinition auxiliaryObjectClassDef = getRefinedDefinition(auxiliaryObjectClassQName); + if (auxiliaryObjectClassDef == null) { + throw new SchemaException("Auxiliary object class "+auxiliaryObjectClassQName+" specified in "+shadow+" does not exist"); + } + auxiliaryObjectClassDefinitions.add(auxiliaryObjectClassDef); + } + + return new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); + } + + @Override + public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(QName structuralObjectClassQName, + ShadowKindType kind, String intent) { + RefinedObjectClassDefinition structuralObjectClassDefinition = null; + Collection auxiliaryObjectClassDefinitions; + if (kind != null) { + structuralObjectClassDefinition = getRefinedDefinition(kind, intent); + } + if (structuralObjectClassDefinition == null) { + // Fallback to objectclass only + if (structuralObjectClassQName == null) { + throw new IllegalArgumentException("No kind nor objectclass defined"); + } + structuralObjectClassDefinition = getRefinedDefinition(structuralObjectClassQName); + } + + if (structuralObjectClassDefinition == null) { + return null; + } + + auxiliaryObjectClassDefinitions = structuralObjectClassDefinition.getAuxiliaryObjectClassDefinitions(); + + return new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); + } + + @Override + public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, Collection intents) throws SchemaException { + RefinedObjectClassDefinition found = null; + for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { + RefinedObjectClassDefinition foundCurrent = null; + if (intents == null || intents.isEmpty()) { + if (acctDef.isDefault()) { + foundCurrent = acctDef; + } + } else { + if (intents.contains(acctDef.getIntent())) { + foundCurrent = acctDef; + } + } + if (foundCurrent != null) { + if (found != null) { + if (!QNameUtil.match(found.getTypeName(), foundCurrent.getTypeName())) { + throw new SchemaException("More than one ObjectClass found for kind " + kind + ", intents: " + intents + ": " + found.getTypeName() + ", " + foundCurrent.getTypeName()); + } + } else { + found = foundCurrent; + } + } + } + return found; + } + + @Override + public RefinedObjectClassDefinition getRefinedDefinition(QName objectClassName) { + for (RefinedObjectClassDefinition def: getRefinedDefinitions()) { + if (def.isDefault() && (QNameUtil.match(def.getTypeName(), objectClassName))) { + return def; + } + } + // No default for this object class, so just use the first one. + // This is not strictly correct .. but it is a "compatible bug" :-) + // TODO: remove this in next major revision + for (RefinedObjectClassDefinition def: getRefinedDefinitions()) { + if ((QNameUtil.match(def.getTypeName(), objectClassName))) { + return def; + } + } + return null; + } + + @Override + public RefinedObjectClassDefinition findRefinedDefinitionByObjectClassQName(ShadowKindType kind, QName objectClass) { + if (objectClass == null) { + return getDefaultRefinedDefinition(kind); + } + for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { + if (acctDef.isDefault() && QNameUtil.match(acctDef.getObjectClassDefinition().getTypeName(), objectClass)) { + return acctDef; + } + } + // No default for this object class, so just use the first one. + // This is not strictly correct .. but it is a "compatible bug" :-) + // TODO: remove this in next major revision + for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { + if (QNameUtil.match(acctDef.getObjectClassDefinition().getTypeName(), objectClass)) { + return acctDef; + } + } + return null; + } + + + @Override + public LayerRefinedResourceSchema forLayer(LayerType layer) { + return new LayerRefinedResourceSchemaImpl(this, layer); + } + + @Override + public String toString() { + return "rSchema(ns=" + getNamespace() + ")"; + } + + //region Static methods + public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType) throws SchemaException { + return getRefinedSchema(resourceType, resourceType.asPrismObject().getPrismContext()); + } + + public static LayerRefinedResourceSchema getRefinedSchema(ResourceType resourceType, LayerType layer) throws SchemaException { + return getRefinedSchema(resourceType, layer, resourceType.asPrismObject().getPrismContext()); + } + + public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType, PrismContext prismContext) throws SchemaException { + PrismObject resource = resourceType.asPrismObject(); + return getRefinedSchema(resource, prismContext); + } + + public static LayerRefinedResourceSchema getRefinedSchema(ResourceType resourceType, LayerType layer, PrismContext prismContext) throws SchemaException { + PrismObject resource = resourceType.asPrismObject(); + return getRefinedSchema(resource, layer, prismContext); + } + + public static RefinedResourceSchema getRefinedSchema(PrismObject resource) throws SchemaException { + return getRefinedSchema(resource, resource.getPrismContext()); + } + + public static RefinedResourceSchema getRefinedSchema(PrismObject resource, PrismContext prismContext) throws SchemaException { + if (resource == null){ + throw new SchemaException("Could not get refined schema, resource does not exist."); + } + + Object userDataEntry = resource.getUserData(USER_DATA_KEY_REFINED_SCHEMA); + if (userDataEntry != null) { + if (userDataEntry instanceof RefinedResourceSchema) { + return (RefinedResourceSchema)userDataEntry; + } else { + throw new IllegalStateException("Expected RefinedResourceSchema under user data key "+USER_DATA_KEY_REFINED_SCHEMA+ + "in "+resource+", but got "+userDataEntry.getClass()); + } + } else { + RefinedResourceSchema refinedSchema = parse(resource, prismContext); + resource.setUserData(USER_DATA_KEY_REFINED_SCHEMA, refinedSchema); + return refinedSchema; + } + } + + public static LayerRefinedResourceSchema getRefinedSchema(PrismObject resource, LayerType layer, PrismContext prismContext) throws SchemaException { + RefinedResourceSchema refinedSchema = getRefinedSchema(resource, prismContext); + if (refinedSchema == null) { + return null; + } + return refinedSchema.forLayer(layer); + } + + public static boolean hasRefinedSchema(ResourceType resourceType) { + PrismObject resource = resourceType.asPrismObject(); + return resource.getUserData(USER_DATA_KEY_REFINED_SCHEMA) != null; + } + + public static ResourceSchema getResourceSchema(ResourceType resourceType, PrismContext prismContext) throws SchemaException { + PrismObject resource = resourceType.asPrismObject(); + return getResourceSchema(resource, prismContext); + } + + public static ResourceSchema getResourceSchema(PrismObject resource, PrismContext prismContext) throws SchemaException { + Element resourceXsdSchema = ResourceTypeUtil.getResourceXsdSchema(resource); + if (resourceXsdSchema == null) { + return null; + } + Object userDataEntry = resource.getUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA); + if (userDataEntry != null) { + if (userDataEntry instanceof ResourceSchema) { + return (ResourceSchema)userDataEntry; + } else { + throw new IllegalStateException("Expected ResourceSchema under user data key "+ + USER_DATA_KEY_PARSED_RESOURCE_SCHEMA+ "in "+resource+", but got "+userDataEntry.getClass()); + } + } else { + InternalMonitor.recordResourceSchemaParse(); + ResourceSchemaImpl parsedSchema = ResourceSchemaImpl.parse(resourceXsdSchema, "resource schema of "+resource, prismContext); + if (parsedSchema == null) { + throw new IllegalStateException("Parsed schema is null: most likely an internall error"); + } + resource.setUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA, parsedSchema); + parsedSchema.setNamespace(ResourceTypeUtil.getResourceNamespace(resource)); + return parsedSchema; + } + } + + public static void setParsedResourceSchemaConditional(ResourceType resourceType, ResourceSchema parsedSchema) { + if (hasParsedSchema(resourceType)) { + return; + } + PrismObject resource = resourceType.asPrismObject(); + resource.setUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA, parsedSchema); + } + + public static boolean hasParsedSchema(ResourceType resourceType) { + PrismObject resource = resourceType.asPrismObject(); + return resource.getUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA) != null; + } + + public static RefinedResourceSchema parse(PrismObject resource, PrismContext prismContext) throws SchemaException { + return parse(resource.asObjectable(), prismContext); + } + + public static RefinedResourceSchema parse(ResourceType resourceType, PrismContext prismContext) throws SchemaException { + + ResourceSchema originalResourceSchema = getResourceSchema(resourceType, prismContext); + if (originalResourceSchema == null) { + return null; + } + + String contextDescription = "definition of "+resourceType; + + RefinedResourceSchemaImpl rSchema = new RefinedResourceSchemaImpl(originalResourceSchema); + + SchemaHandlingType schemaHandling = resourceType.getSchemaHandling(); + if (schemaHandling != null) { + parseObjectTypeDefsFromSchemaHandling(rSchema, resourceType, schemaHandling, + schemaHandling.getObjectType(), null, prismContext, contextDescription); + } + + parseObjectTypesFromSchema(rSchema, resourceType, prismContext, contextDescription); + + // We need to parse associations and auxiliary object classes in a second pass. We need to have all object classes parsed before correctly setting association + // targets + for (RefinedObjectClassDefinition rOcDef: rSchema.getRefinedDefinitions()) { + ((RefinedObjectClassDefinitionImpl) rOcDef).parseAssociations(rSchema); + ((RefinedObjectClassDefinitionImpl) rOcDef).parseAuxiliaryObjectClasses(rSchema); + } + + // We can parse attributes only after we have all the object class info parsed (including auxiliary object classes) + for (RefinedObjectClassDefinition rOcDef: rSchema.getRefinedDefinitions()) { + ((RefinedObjectClassDefinitionImpl) rOcDef).parseAttributes(rSchema, contextDescription); + } + + return rSchema; + } + +// private static boolean hasAnyObjectTypeDef(SchemaHandlingType schemaHandling) { +// if (schemaHandling == null) { +// return false; +// } +// if (!schemaHandling.getObjectType().isEmpty()) { +// return true; +// } +// return false; +// } + + private static void parseObjectTypeDefsFromSchemaHandling(RefinedResourceSchemaImpl rSchema, ResourceType resourceType, + SchemaHandlingType schemaHandling, Collection resourceObjectTypeDefs, + ShadowKindType impliedKind, PrismContext prismContext, String contextDescription) throws SchemaException { + + if (resourceObjectTypeDefs == null) { + return; + } + + Map defaults = new HashMap<>(); + + for (ResourceObjectTypeDefinitionType accountTypeDefType: resourceObjectTypeDefs) { + RefinedObjectClassDefinition rOcDef = RefinedObjectClassDefinitionImpl.parse(accountTypeDefType, resourceType, rSchema, impliedKind, + prismContext, contextDescription); + + if (rOcDef.isDefault()) { + if (defaults.containsKey(rOcDef.getKind())) { + throw new SchemaException("More than one default "+rOcDef.getKind()+" definitions ("+defaults.get(rOcDef.getKind())+", "+rOcDef+") in " + contextDescription); + } else { + defaults.put(rOcDef.getKind(), rOcDef); + } + } + + rSchema.add(rOcDef); + } + } + + public static List getIntentsForKind(RefinedResourceSchema rSchema, ShadowKindType kind) { + List intents = new ArrayList<>(); + for (ObjectClassComplexTypeDefinition objClassDef : rSchema.getObjectClassDefinitions()) { + if (objClassDef.getKind() == kind){ + intents.add(objClassDef.getIntent()); + } + } + + return intents; + + } + + + private static void parseObjectTypesFromSchema(RefinedResourceSchemaImpl rSchema, ResourceType resourceType, + PrismContext prismContext, String contextDescription) throws SchemaException { + + RefinedObjectClassDefinition rAccountDefDefault = null; + for(ObjectClassComplexTypeDefinition objectClassDef: rSchema.getOriginalResourceSchema().getObjectClassDefinitions()) { + QName objectClassname = objectClassDef.getTypeName(); + if (rSchema.getRefinedDefinition(objectClassname) != null) { + continue; + } + RefinedObjectClassDefinition rOcDef = RefinedObjectClassDefinitionImpl.parseFromSchema(objectClassDef, resourceType, rSchema, prismContext, + "object class " + objectClassname + ", in " + contextDescription); + + if (objectClassDef.getKind() == ShadowKindType.ACCOUNT && rOcDef.isDefault()) { + if (rAccountDefDefault == null) { + rAccountDefDefault = rOcDef; + } else { + throw new SchemaException("More than one default account definitions ("+rAccountDefDefault+", "+rOcDef+") in " + contextDescription); + } + } + + rSchema.add(rOcDef); + } + } + //endregion + + private void add(RefinedObjectClassDefinition rOcDef) { + ((ResourceSchemaImpl) originalResourceSchema).add(rOcDef); // TODO FIXME + } + + //region Delegations + @Override + public ObjectClassComplexTypeDefinition findObjectClassDefinition(QName objectClassQName) { + return originalResourceSchema.findObjectClassDefinition(objectClassQName); + } + + @Override + public ObjectClassComplexTypeDefinition findObjectClassDefinition(ShadowKindType kind, String intent) { + return originalResourceSchema.findObjectClassDefinition(kind, intent); + } + + @Override + public ObjectClassComplexTypeDefinition findDefaultObjectClassDefinition(ShadowKindType kind) { + return originalResourceSchema.findDefaultObjectClassDefinition(kind); + } + + @Override + public String getNamespace() { + return originalResourceSchema.getNamespace(); + } + + @Override + @NotNull + public Collection getDefinitions() { + return originalResourceSchema.getDefinitions(); + } + + @Override + @NotNull + public List getDefinitions(@NotNull Class type) { + return originalResourceSchema.getDefinitions(type); + } + + @Override + public PrismContext getPrismContext() { + return originalResourceSchema.getPrismContext(); + } + + @Override + @NotNull + public Document serializeToXsd() throws SchemaException { + return originalResourceSchema.serializeToXsd(); + } + + @Override + public boolean isEmpty() { + return originalResourceSchema.isEmpty(); + } + + @NotNull + @Override + public List findItemDefinitionsByCompileTimeClass( + @NotNull Class compileTimeClass, @NotNull Class definitionClass) { + return originalResourceSchema.findItemDefinitionsByCompileTimeClass(compileTimeClass, definitionClass); + } + + @Nullable + @Override + public TD findTypeDefinitionByCompileTimeClass(@NotNull Class compileTimeClass, @NotNull Class definitionClass) { + return originalResourceSchema.findTypeDefinitionByCompileTimeClass(compileTimeClass, definitionClass); + } + + @Override + @Nullable + public TD findTypeDefinitionByType(@NotNull QName typeName, @NotNull Class definitionClass) { + return originalResourceSchema.findTypeDefinitionByType(typeName, definitionClass); + } + + @Override + public String debugDump() { + return originalResourceSchema.debugDump(); + } + + @Override + public String debugDump(int indent) { + return originalResourceSchema.debugDump(indent); + } + + @Nullable + @Override + public ID findItemDefinitionByType( + @NotNull QName typeName, @NotNull Class definitionType) { + return originalResourceSchema.findItemDefinitionByType(typeName, definitionType); + } + + @Override + @NotNull + public List findItemDefinitionsByElementName(@NotNull QName elementName, + @NotNull Class definitionClass) { + return originalResourceSchema.findItemDefinitionsByElementName(elementName, definitionClass); + } + + //endregion + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java b/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java index 73db3a484eb..ccf32f61fef 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/validator/Validator.java @@ -102,7 +102,7 @@ private void initialize() { SchemaRegistry schemaRegistry = prismContext.getSchemaRegistry(); midPointJavaxSchema = schemaRegistry.getJavaxSchema(); xsdValidator = midPointJavaxSchema.newValidator(); - xsdValidator.setResourceResolver(schemaRegistry); + xsdValidator.setResourceResolver(prismContext.getEntityResolver()); } public EventHandler getHandler() { @@ -352,7 +352,7 @@ private EventResult validateObjectInternal(Element objectElement, OperationResul return EventResult.skipObject(); } - PrismObject object = prismContext.parseObject(objectElement); + PrismObject object = prismContext.parserFor(objectElement).parse(); try { object.checkConsistence(); diff --git a/infra/common/src/test/java/com/evolveum/midpoint/common/TestStaticValues.java b/infra/common/src/test/java/com/evolveum/midpoint/common/TestStaticValues.java index d01c4c95522..cdf296779d3 100644 --- a/infra/common/src/test/java/com/evolveum/midpoint/common/TestStaticValues.java +++ b/infra/common/src/test/java/com/evolveum/midpoint/common/TestStaticValues.java @@ -15,11 +15,7 @@ */ package com.evolveum.midpoint.common; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.constants.MidPointConstants; @@ -63,7 +59,7 @@ public void testValueElementsRoundtripString() throws Exception { // GIVEN PrismContext prismContext = PrismTestUtil.getPrismContext(); - PrismPropertyDefinition propDef = new PrismPropertyDefinition(PROP_NAME, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinitionImpl propDef = new PrismPropertyDefinitionImpl(PROP_NAME, DOMUtil.XSD_STRING, prismContext); propDef.setMaxOccurs(-1); PrismProperty origProperty = propDef.instantiate(); origProperty.addRealValue("FOO"); @@ -79,7 +75,7 @@ public void testValueElementsRoundtripInt() throws Exception { // GIVEN PrismContext prismContext = PrismTestUtil.getPrismContext(); - PrismPropertyDefinition propDef = new PrismPropertyDefinition(PROP_NAME, DOMUtil.XSD_INT, prismContext); + PrismPropertyDefinitionImpl propDef = new PrismPropertyDefinitionImpl(PROP_NAME, DOMUtil.XSD_INT, prismContext); propDef.setMaxOccurs(-1); PrismProperty origProperty = propDef.instantiate(); origProperty.addRealValue(42); diff --git a/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java b/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java index 0ae3dd27ed2..54a6d92445c 100644 --- a/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java +++ b/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java @@ -33,6 +33,7 @@ import com.evolveum.midpoint.prism.ConsistencyCheckScope; import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.processor.*; import org.testng.Assert; import org.testng.AssertJUnit; import org.testng.annotations.BeforeSuite; @@ -51,11 +52,6 @@ import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.constants.MidPointConstants; import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.SchemaTestConstants; import com.evolveum.midpoint.schema.util.ShadowUtil; @@ -104,7 +100,7 @@ public void testParseFromResourceComplex() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resourceType, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resourceType, prismContext); // THEN TestUtil.displayThen(TEST_NAME); @@ -142,7 +138,7 @@ public void testParseFromResourceSimple() throws JAXBException, SchemaException, ResourceType resourceType = resource.asObjectable(); // WHEN - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resourceType, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resourceType, prismContext); // THEN assertNotNull("Refined schema is null", rSchema); @@ -160,11 +156,11 @@ private void assertRefinedSchema(ResourceType resourceType, RefinedResourceSchem RefinedObjectClassDefinition rAccountDef = rSchema.getRefinedDefinition(ShadowKindType.ACCOUNT, (String)null); RefinedObjectClassDefinition accountDefByNullObjectclass = rSchema.findRefinedDefinitionByObjectClassQName(ShadowKindType.ACCOUNT, null); - assertTrue("findAccountDefinitionByObjectClass(null) returned wrong value", rAccountDef.equals(accountDefByNullObjectclass)); + assertEquals("findAccountDefinitionByObjectClass(null) returned wrong value", rAccountDef, accountDefByNullObjectclass); RefinedObjectClassDefinition accountDefByIcfAccountObjectclass = rSchema.findRefinedDefinitionByObjectClassQName(ShadowKindType.ACCOUNT, new QName(resourceType.getNamespace(), SchemaTestConstants.ICF_ACCOUNT_OBJECT_CLASS_LOCAL_NAME)); - assertTrue("findAccountDefinitionByObjectClass(ICF account) returned wrong value", rAccountDef.equals(accountDefByIcfAccountObjectclass)); + assertEquals("findAccountDefinitionByObjectClass(ICF account) returned wrong value", rAccountDef, accountDefByIcfAccountObjectclass); assertRObjectClassDef(rAccountDef, resourceType, sourceLayer, validationLayer); System.out.println("Refined account definitionn:"); @@ -210,7 +206,7 @@ private void assertRefinedSchema(ResourceType resourceType, RefinedResourceSchem assertNotNull("No entitlement displayNameAttribute", entDisplayNameAttributeDef); assertEquals("Wrong entitlement displayNameAttribute", new QName(resourceType.getNamespace(), "cn"), entDisplayNameAttributeDef.getName()); - assertEquals("Unexpected number of entitlement associations", 1, rAccountDef.getEntitlementAssociations().size()); + assertEquals("Unexpected number of entitlement associations", 1, rAccountDef.getEntitlementAssociationDefinitions().size()); } assertRefinedToLayer(rAccountDef, sourceLayer); @@ -282,7 +278,7 @@ public void testParseAccount() throws JAXBException, SchemaException, SAXExcepti PrismObject resource = prismContext.parseObject(RESOURCE_COMPLEX_FILE); ResourceType resourceType = resource.asObjectable(); - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resourceType, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resourceType, prismContext); RefinedObjectClassDefinition defaultAccountDefinition = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); assertNotNull("No refined default account definition in "+rSchema, defaultAccountDefinition); @@ -314,7 +310,7 @@ public void testApplyAttributeDefinition() throws JAXBException, SchemaException PrismObject resource = prismContext.parseObject(RESOURCE_COMPLEX_FILE); - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resource, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resource, prismContext); RefinedObjectClassDefinition defaultAccountDefinition = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); assertNotNull("No refined default account definition in "+rSchema, defaultAccountDefinition); System.out.println("Refined account definition:"); @@ -343,7 +339,7 @@ private void assertAccountShadow(PrismObject accObject, PrismObject< PrismAsserts.assertPropertyValue(accObject, ShadowType.F_INTENT, SchemaConstants.INTENT_DEFAULT); PrismContainer attributes = accObject.findOrCreateContainer(SchemaConstants.C_ATTRIBUTES); - assertEquals("Wrong type of definition in account", ResourceAttributeContainerDefinition.class, attributes.getDefinition().getClass()); + assertEquals("Wrong type of definition in account", ResourceAttributeContainerDefinitionImpl.class, attributes.getDefinition().getClass()); ResourceAttributeContainerDefinition attrDef = (ResourceAttributeContainerDefinition)attributes.getDefinition(); assertAttributeDefs(attrDef, resourceType, null, LayerType.MODEL); @@ -389,7 +385,7 @@ public void testCreateShadow() throws JAXBException, SchemaException, SAXExcepti PrismObject resource = prismContext.parseObject(RESOURCE_COMPLEX_FILE); ResourceType resourceType = resource.asObjectable(); - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resourceType, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resourceType, prismContext); assertNotNull("Refined schema is null", rSchema); assertFalse("No account definitions", rSchema.getRefinedDefinitions(ShadowKindType.ACCOUNT).isEmpty()); RefinedObjectClassDefinition rAccount = rSchema.getRefinedDefinition(ShadowKindType.ACCOUNT, (String)null); @@ -416,7 +412,7 @@ public void testProtectedAccount() throws JAXBException, SchemaException, SAXExc PrismContext prismContext = createInitializedPrismContext(); PrismObject resource = prismContext.parseObject(RESOURCE_COMPLEX_FILE); ResourceType resourceType = resource.asObjectable(); - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resourceType, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resourceType, prismContext); assertNotNull("Refined schema is null", rSchema); assertFalse("No account definitions", rSchema.getRefinedDefinitions(ShadowKindType.ACCOUNT).isEmpty()); RefinedObjectClassDefinition rAccount = rSchema.getRefinedDefinition(ShadowKindType.ACCOUNT, (String)null); @@ -437,7 +433,7 @@ private void assertAttributeDefs(ResourceAttributeContainerDefinition attrsDef, assertNotNull("Null account definition", attrsDef); assertEquals(SchemaConstants.INTENT_DEFAULT, attrsDef.getIntent()); assertEquals("AccountObjectClass", attrsDef.getComplexTypeDefinition().getTypeName().getLocalPart()); - assertEquals("Wrong objectclass in the definition of definition in account", RefinedObjectClassDefinition.class, attrsDef.getComplexTypeDefinition().getClass()); + assertEquals("Wrong objectclass in the definition of definition in account", RefinedObjectClassDefinitionImpl.class, attrsDef.getComplexTypeDefinition().getClass()); RefinedObjectClassDefinition rAccount = (RefinedObjectClassDefinition) attrsDef.getComplexTypeDefinition(); assertRObjectClassDef(rAccount, resourceType, sourceLayer, validationLayer); } @@ -528,7 +524,7 @@ private void assertDeprecatedProtectedAccount(String message, ResourceObjectPatt } private ResourceAttribute createStringAttribute(QName attrName, String value) { - ResourceAttributeDefinition testAttrDef = new ResourceAttributeDefinition(attrName, DOMUtil.XSD_STRING, getPrismContext()); + ResourceAttributeDefinition testAttrDef = new ResourceAttributeDefinitionImpl(attrName, DOMUtil.XSD_STRING, getPrismContext()); ResourceAttribute testAttr = testAttrDef.instantiate(); testAttr.setRealValue(value); return testAttr; @@ -547,7 +543,7 @@ public void testParseFromResourcePosix() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - RefinedResourceSchema rSchema = RefinedResourceSchema.parse(resourceType, prismContext); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.parse(resourceType, prismContext); // THEN TestUtil.displayThen(TEST_NAME); @@ -645,7 +641,7 @@ public void testParseFromResourcePosix() throws Exception { assertEquals("Wrong entitlement displayNameAttribute", new QName(ResourceTypeUtil.getResourceNamespace(resourceType), "dn"), entDisplayNameAttributeDef.getName()); - assertEquals("Unexpected number of entitlement associations", 1, rAccountDef.getEntitlementAssociations().size()); + assertEquals("Unexpected number of entitlement associations", 1, rAccountDef.getEntitlementAssociationDefinitions().size()); ResourceAttributeContainerDefinition resAttrContainerDef = rAccountDef.toResourceAttributeContainerDefinition(); assertNotNull("No ResourceAttributeContainerDefinition", resAttrContainerDef); diff --git a/infra/pom.xml b/infra/pom.xml index 4159fde093f..625367758cb 100644 --- a/infra/pom.xml +++ b/infra/pom.xml @@ -52,6 +52,7 @@ common test-util prism + prism-maven-plugin diff --git a/infra/prism-maven-plugin/pom.xml b/infra/prism-maven-plugin/pom.xml index ca4d9530ac8..fcd0eb5b18a 100644 --- a/infra/prism-maven-plugin/pom.xml +++ b/infra/prism-maven-plugin/pom.xml @@ -68,6 +68,10 @@ org.apache.velocity velocity + + org.jetbrains + annotations-java5 + diff --git a/infra/prism-maven-plugin/src/main/java/com/evolveum/midpoint/prism/maven/SchemaDocMojo.java b/infra/prism-maven-plugin/src/main/java/com/evolveum/midpoint/prism/maven/SchemaDocMojo.java index 507b88f6f97..a45ad079fca 100644 --- a/infra/prism-maven-plugin/src/main/java/com/evolveum/midpoint/prism/maven/SchemaDocMojo.java +++ b/infra/prism-maven-plugin/src/main/java/com/evolveum/midpoint/prism/maven/SchemaDocMojo.java @@ -18,10 +18,12 @@ import com.evolveum.midpoint.prism.ComplexTypeDefinition; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismContextImpl; import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.schema.PrismSchema; import com.evolveum.midpoint.prism.schema.SchemaDefinitionFactory; import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.schema.SchemaRegistryImpl; import com.evolveum.midpoint.prism.xml.GlobalDynamicNamespacePrefixMapper; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.SchemaException; @@ -35,6 +37,7 @@ import org.apache.velocity.app.VelocityEngine; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.zip.ZipArchiver; +import org.jetbrains.annotations.NotNull; import org.xml.sax.SAXException; import java.io.*; @@ -241,7 +244,7 @@ private File initializeOutDir() throws MojoFailureException { private PrismContext createInitializedPrismContext() throws MojoFailureException { try { - SchemaRegistry schemaRegistry = createSchemaRegistry(); + SchemaRegistryImpl schemaRegistry = createSchemaRegistry(); for (File schemaFile: schemaFiles) { getLog().info("SchemaDoc: registering schema file: "+schemaFile); @@ -261,7 +264,7 @@ private PrismContext createInitializedPrismContext() throws MojoFailureException schemaRegistry.setCatalogFiles(catalogFiles); } - PrismContext context = PrismContext.create(schemaRegistry); + PrismContextImpl context = PrismContextImpl.create(schemaRegistry); context.setDefinitionFactory(new SchemaDefinitionFactory()); context.initialize(); @@ -291,8 +294,9 @@ private void handleFailure(Exception e) throws MojoFailureException { throw new MojoFailureException(e.getMessage()); } - private SchemaRegistry createSchemaRegistry() throws SchemaException { - SchemaRegistry schemaRegistry = new SchemaRegistry(); + @NotNull + private SchemaRegistryImpl createSchemaRegistry() throws SchemaException { + SchemaRegistryImpl schemaRegistry = new SchemaRegistryImpl(); schemaRegistry.setNamespacePrefixMapper(new GlobalDynamicNamespacePrefixMapper()); return schemaRegistry; } diff --git a/infra/prism/pom.xml b/infra/prism/pom.xml index bbe17ffa94d..8b8a3d57eb9 100644 --- a/infra/prism/pom.xml +++ b/infra/prism/pom.xml @@ -38,6 +38,11 @@ util 3.5-SNAPSHOT + + + + + com.sun.xml.bind jaxb-xjc @@ -51,7 +56,16 @@ commons-lang commons-lang - + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-collections4 + 4.1 + + org.apache.santuario xmlsec @@ -83,6 +97,10 @@ com.fasterxml.jackson.core jackson-annotations + + org.yaml + snakeyaml + org.springframework spring-core diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Checkable.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Checkable.java new file mode 100644 index 00000000000..1e3b083b58a --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Checkable.java @@ -0,0 +1,9 @@ +package com.evolveum.midpoint.prism; + +/** + * @author mederly + */ +public interface Checkable { + + void checkConsistence(); +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinition.java index e5b6863d404..c240ed71e4d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinition.java @@ -16,104 +16,52 @@ package com.evolveum.midpoint.prism; -import com.evolveum.midpoint.prism.path.IdItemPathSegment; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.path.ItemPathSegment; -import com.evolveum.midpoint.prism.path.NameItemPathSegment; -import com.evolveum.midpoint.prism.path.ObjectReferencePathSegment; -import com.evolveum.midpoint.prism.path.ParentPathSegment; -import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.QNameUtil; -import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashMap; +import javax.xml.namespace.QName; import java.util.List; import java.util.Map; -import javax.xml.namespace.QName; - /** - * TODO - * - * @author Radovan Semancik - * + * Provides a definition for a complex type, i.e. type that prescribes inner items. + * It's instances may be container values or property values, depending on container/object + * markers presence. + * + * @author semancik + * @author mederly */ -public class ComplexTypeDefinition extends Definition { - private static final long serialVersionUID = 2655797837209175037L; - private List itemDefinitions; - private QName superType; - private boolean containerMarker; - private boolean objectMarker; - private boolean xsdAnyMarker; - private QName extensionForType; - private Class compileTimeClass; - - public ComplexTypeDefinition(QName typeName, PrismContext prismContext) { - super(typeName, prismContext); - itemDefinitions = new ArrayList(); - } - - public ComplexTypeDefinition(QName typeName, PrismContext prismContext, Class compileTimeClass) { - super(typeName, prismContext); - itemDefinitions = new ArrayList(); - this.compileTimeClass = compileTimeClass; - } +public interface ComplexTypeDefinition extends TypeDefinition, LocalDefinitionStore { - protected String getSchemaNamespace() { - return getTypeName().getNamespaceURI(); - } - /** - * Returns set of property definitions. - * - * The set contains all property definitions of all types that were parsed. - * Order of definitions is insignificant. - * - * @return set of definitions + * Returns definitions for all inner items. + * + * These are of type ItemDefinition. However, very often subtypes of this type are used, + * e.g. ResourceAttributeDefinition, RefinedAttributeDefinition, LayerRefinedAttributeDefinition, and so on. + * + * Although returned as a list, the order of definitions is insignificant. (TODO change to set?) + * + * The list is unmodifiable. */ - public List getDefinitions() { - if (itemDefinitions == null) { - itemDefinitions = new ArrayList(); - } - return itemDefinitions; - } - - public void addDefinition(ItemDefinition itemDef) { - itemDefinitions.add(itemDef); - } - - public Class getCompileTimeClass() { - return compileTimeClass; - } + @NotNull + List getDefinitions(); - public void setCompileTimeClass(Class compileTimeClass) { - this.compileTimeClass = compileTimeClass; - } - - public QName getExtensionForType() { - return extensionForType; - } + /** + * If not null, indicates that this type defines the structure of 'extension' element of a given type. + * E.g. getExtensionForType() == c:UserType means that this complex type defines structure of + * 'extension' elements of UserType objects. + */ + @Nullable + QName getExtensionForType(); - public void setExtensionForType(QName extensionForType) { - this.extensionForType = extensionForType; - } - /** * Flag indicating whether this type was marked as "container" * in the original schema. Does not provide any information to - * schema processing logic, just conveys the marker from oginal - * schema so we can serialized and deserialize the schema without + * schema processing logic, just conveys the marker from original + * schema so we can serialize and deserialize the schema without * loss of information. */ - public boolean isContainerMarker() { - return containerMarker; - } - - public void setContainerMarker(boolean containerMarker) { - this.containerMarker = containerMarker; - } + boolean isContainerMarker(); /** * Flag indicating whether this type was marked as "object" @@ -122,366 +70,53 @@ public void setContainerMarker(boolean containerMarker) { * schema so we can serialized and deserialize the schema without * loss of information. */ - public boolean isObjectMarker() { - return objectMarker; - } - - public boolean isXsdAnyMarker() { - return xsdAnyMarker; - } - - public void setXsdAnyMarker(boolean xsdAnyMarker) { - this.xsdAnyMarker = xsdAnyMarker; - } - - public QName getSuperType() { - return superType; - } - - public void setSuperType(QName superType) { - this.superType = superType; - } - - public void setObjectMarker(boolean objectMarker) { - this.objectMarker = objectMarker; - } + boolean isObjectMarker(); - public void add(ItemDefinition definition) { - itemDefinitions.add(definition); - } - - public PrismPropertyDefinition createPropertyDefinifion(QName name, QName typeName) { - PrismPropertyDefinition propDef = new PrismPropertyDefinition(name, typeName, prismContext); - itemDefinitions.add(propDef); - return propDef; - } - - // Creates reference to other schema - // TODO: maybe check if the name is in different namespace - // TODO: maybe create entirely new concept of property reference? - public PrismPropertyDefinition createPropertyDefinifion(QName name) { - PrismPropertyDefinition propDef = new PrismPropertyDefinition(name, null, prismContext); - itemDefinitions.add(propDef); - return propDef; - } - - public PrismPropertyDefinition createPropertyDefinition(String localName, QName typeName) { - QName name = new QName(getSchemaNamespace(),localName); - return createPropertyDefinifion(name, typeName); - } - - - public PrismPropertyDefinition createPropertyDefinifion(String localName, String localTypeName) { - QName name = new QName(getSchemaNamespace(),localName); - QName typeName = new QName(getSchemaNamespace(),localTypeName); - return createPropertyDefinifion(name, typeName); - } - /** - * Finds a PropertyDefinition by looking at the property name. - *

- * Returns null if nothing is found. - * - * @param name property definition name - * @return found property definition or null - */ - public PrismPropertyDefinition findPropertyDefinition(QName name) { - return findItemDefinition(name, PrismPropertyDefinition.class); - } - - public PrismPropertyDefinition findPropertyDefinition(ItemPath path) { - return findItemDefinition(path, PrismPropertyDefinition.class); - } - - public PrismContainerDefinition findContainerDefinition(QName name) { - return findItemDefinition(name, PrismContainerDefinition.class); - } - - public PrismContainerDefinition findContainerDefinition(ItemPath path) { - return findItemDefinition(path, PrismContainerDefinition.class); - } - - public T findItemDefinition(QName name, Class clazz) { - return findItemDefinition(name, clazz, false); - } - - public T findItemDefinition(QName name, Class clazz, boolean caseInsensitive) { - if (clazz == null) { - throw new IllegalArgumentException("type not specified while searching for " + name + " in " + this); - } - if (name == null) { - throw new IllegalArgumentException("name not specified while searching in " + this); - } - - for (ItemDefinition def : getDefinitions()) { - if (isItemValid(def, name, clazz, caseInsensitive)) { - return (T) def; - } - } - return null; - } - - public ID findItemDefinition(ItemPath path) { - return (ID)findItemDefinition(path, ItemDefinition.class); - } - - public ID findItemDefinition(ItemPath path, Class clazz) { - for (;;) { - if (path.isEmpty()) { - throw new IllegalArgumentException("Cannot resolve empty path on complex type definition "+this); - } - ItemPathSegment first = path.first(); - if (first instanceof NameItemPathSegment) { - QName firstName = ((NameItemPathSegment)first).getName(); - return findNamedItemDefinition(firstName, path.rest(), clazz); - } else if (first instanceof IdItemPathSegment) { - path = path.rest(); - } else if (first instanceof ParentPathSegment) { - ItemPath rest = path.rest(); - ComplexTypeDefinition parent = getSchemaRegistry().determineParentDefinition(this, rest); - if (rest.isEmpty()) { - // requires that the parent is defined as an item (container, object) - return (ID) getSchemaRegistry().findItemDefinitionByType(parent.getTypeName()); - } else { - return parent.findItemDefinition(rest, clazz); - } - } else if (first instanceof ObjectReferencePathSegment) { - throw new IllegalStateException("Couldn't use '@' path segment in this context. CTD=" + getTypeName() + ", path=" + path); - } else { - throw new IllegalStateException("Unexpected path segment: " + first + " in " + path); - } - } - } - - // path starts with NamedItemPathSegment - private ID findNamedItemDefinition(QName firstName, ItemPath rest, Class clazz) { - ID found = null; - for (ItemDefinition def : getDefinitions()) { - if (firstName != null && QNameUtil.match(firstName, def.getName())) { - if (found != null) { - throw new IllegalStateException("More definitions found for " + firstName + "/" + rest + " in " + this); - } - found = (ID) def.findItemDefinition(rest, clazz); - if (StringUtils.isNotEmpty(firstName.getNamespaceURI())) { - return found; // if qualified then there's no risk of matching more entries - } - } - } - return found; - } + * True if the complex type definition contains xsd:any (directly or indirectly). + */ + boolean isXsdAnyMarker(); - private boolean isItemValid(ItemDefinition def, QName name, Class clazz, boolean caseInsensitive) { - if (def == null) { - return false; - } - return def.isValidFor(name, clazz, caseInsensitive); - } - /** - * Merge provided definition into this definition. + * When resolving unqualified names for items contained in this CTD, what should be the default namespace + * to look into at first. Currently does NOT apply recursively (to inner CTDs). */ - public void merge(ComplexTypeDefinition otherComplexTypeDef) { - for (ItemDefinition otherItemDef: otherComplexTypeDef.getDefinitions()) { - add(otherItemDef.clone()); - } - } - - @Override - public void revive(PrismContext prismContext) { - if (this.prismContext != null) { - return; - } - this.prismContext = prismContext; - for (ItemDefinition def: itemDefinitions) { - def.revive(prismContext); - } - } + @Nullable + String getDefaultNamespace(); - public boolean isEmpty() { - return itemDefinitions.isEmpty(); - } - /** - * Shallow clone. + * When resolving unqualified names for items contained in this CTD, what namespace(s) should be ignored. + * Names in this list are interpreted as a namespace prefixes. + * Currently does NOT apply recursively (to inner CTDs). */ - public ComplexTypeDefinition clone() { - ComplexTypeDefinition clone = new ComplexTypeDefinition(this.typeName, prismContext); - copyDefinitionData(clone); - return clone; - } - - public ComplexTypeDefinition deepClone() { - return deepClone(new HashMap()); - } - - ComplexTypeDefinition deepClone(Map ctdMap) { - ComplexTypeDefinition clone; - if (ctdMap != null) { - clone = ctdMap.get(this.getTypeName()); - if (clone != null) { - return clone; // already cloned - } - } - clone = clone(); // shallow - if (ctdMap != null) { - ctdMap.put(this.getTypeName(), clone); - } - clone.itemDefinitions.clear(); - for (ItemDefinition itemDef: this.itemDefinitions) { - clone.itemDefinitions.add(itemDef.deepClone(ctdMap)); - } - return clone; - } - - protected void copyDefinitionData(ComplexTypeDefinition clone) { - super.copyDefinitionData(clone); - clone.superType = this.superType; - clone.containerMarker = this.containerMarker; - clone.objectMarker = this.objectMarker; - clone.xsdAnyMarker = this.xsdAnyMarker; - clone.extensionForType = this.extensionForType; - clone.compileTimeClass = this.compileTimeClass; - clone.itemDefinitions.addAll(this.itemDefinitions); - } - - public void replaceDefinition(QName propertyName, ItemDefinition newDefinition) { - for (int i=0; i getIgnoredNamespaces(); - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((compileTimeClass == null) ? 0 : compileTimeClass.hashCode()); - result = prime * result + (containerMarker ? 1231 : 1237); - result = prime * result + ((extensionForType == null) ? 0 : extensionForType.hashCode()); - result = prime * result + ((itemDefinitions == null) ? 0 : itemDefinitions.hashCode()); - result = prime * result + (objectMarker ? 1231 : 1237); - result = prime * result + ((superType == null) ? 0 : superType.hashCode()); - result = prime * result + (xsdAnyMarker ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ComplexTypeDefinition other = (ComplexTypeDefinition) obj; - if (compileTimeClass == null) { - if (other.compileTimeClass != null) { - return false; - } - } else if (!compileTimeClass.equals(other.compileTimeClass)) { - return false; - } - if (containerMarker != other.containerMarker) { - return false; - } - if (extensionForType == null) { - if (other.extensionForType != null) { - return false; - } - } else if (!extensionForType.equals(other.extensionForType)) { - return false; - } - if (itemDefinitions == null) { - if (other.itemDefinitions != null) { - return false; - } - } else if (!itemDefinitions.equals(other.itemDefinitions)) { - return false; - } - if (objectMarker != other.objectMarker) { - return false; - } - if (superType == null) { - if (other.superType != null) { - return false; - } - } else if (!superType.equals(other.superType)) { - return false; - } - if (xsdAnyMarker != other.xsdAnyMarker) { - return false; - } - return true; - } + /** + * Copies cloned definitions from the other type definition into this one. + * (TODO remove from the interface?) + */ + void merge(ComplexTypeDefinition otherComplexTypeDef); @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - for (int i=0; i ctdMap); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java new file mode 100644 index 00000000000..f2dcda112d8 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.path.IdItemPathSegment; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.path.ItemPathSegment; +import com.evolveum.midpoint.prism.path.NameItemPathSegment; +import com.evolveum.midpoint.prism.path.ObjectReferencePathSegment; +import com.evolveum.midpoint.prism.path.ParentPathSegment; +import com.evolveum.midpoint.util.DebugDumpable; +import com.evolveum.midpoint.util.PrettyPrinter; +import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.util.QNameUtil; +import org.apache.commons.lang.StringUtils; + +import java.util.*; + +import javax.xml.namespace.QName; + +/** + * TODO + * + * @author Radovan Semancik + * + */ +public class ComplexTypeDefinitionImpl extends TypeDefinitionImpl implements ComplexTypeDefinition { + + private static final long serialVersionUID = 2655797837209175037L; + @NotNull private final List itemDefinitions = new ArrayList<>(); + private boolean containerMarker; + private boolean objectMarker; + private boolean xsdAnyMarker; + private QName extensionForType; + + private String defaultNamespace; + + @NotNull private List ignoredNamespaces = new ArrayList<>(); + + public ComplexTypeDefinitionImpl(@NotNull QName typeName, @NotNull PrismContext prismContext) { + super(typeName, prismContext); + } + + //region Trivia + protected String getSchemaNamespace() { + return getTypeName().getNamespaceURI(); + } + + /** + * Returns set of item definitions. + * + * The set contains all item definitions of all types that were parsed. + * Order of definitions is insignificant. + * + * @return set of definitions + */ + @NotNull + @Override + public List getDefinitions() { + return Collections.unmodifiableList(itemDefinitions); + } + + public void add(ItemDefinition definition) { + itemDefinitions.add(definition); + } + + @Override + public QName getExtensionForType() { + return extensionForType; + } + + public void setExtensionForType(QName extensionForType) { + this.extensionForType = extensionForType; + } + + @Override + public boolean isContainerMarker() { + return containerMarker; + } + + public void setContainerMarker(boolean containerMarker) { + this.containerMarker = containerMarker; + } + + @Override + public boolean isObjectMarker() { + return objectMarker; + } + + @Override + public boolean isXsdAnyMarker() { + return xsdAnyMarker; + } + + public void setXsdAnyMarker(boolean xsdAnyMarker) { + this.xsdAnyMarker = xsdAnyMarker; + } + + @Override + public String getDefaultNamespace() { + return defaultNamespace; + } + + public void setDefaultNamespace(String defaultNamespace) { + this.defaultNamespace = defaultNamespace; + } + + @Override + @NotNull + public List getIgnoredNamespaces() { + return ignoredNamespaces; + } + + public void setIgnoredNamespaces(@NotNull List ignoredNamespaces) { + this.ignoredNamespaces = ignoredNamespaces; + } + + public void setObjectMarker(boolean objectMarker) { + this.objectMarker = objectMarker; + } + + //endregion + + //region Creating definitions + public PrismPropertyDefinitionImpl createPropertyDefinition(QName name, QName typeName) { + PrismPropertyDefinitionImpl propDef = new PrismPropertyDefinitionImpl(name, typeName, prismContext); + itemDefinitions.add(propDef); + return propDef; + } + + // Creates reference to other schema + // TODO: maybe check if the name is in different namespace + // TODO: maybe create entirely new concept of property reference? + public PrismPropertyDefinition createPropertyDefinition(QName name) { + PrismPropertyDefinition propDef = new PrismPropertyDefinitionImpl(name, null, prismContext); + itemDefinitions.add(propDef); + return propDef; + } + + public PrismPropertyDefinitionImpl createPropertyDefinition(String localName, QName typeName) { + QName name = new QName(getSchemaNamespace(), localName); + return createPropertyDefinition(name, typeName); + } + + public PrismPropertyDefinition createPropertyDefinition(String localName, String localTypeName) { + QName name = new QName(getSchemaNamespace(), localName); + QName typeName = new QName(getSchemaNamespace(), localTypeName); + return createPropertyDefinition(name, typeName); + } + //endregion + + //region Finding definitions + + // TODO deduplicate w.r.t. findNamedItemDefinition + @Override + public T findItemDefinition(@NotNull QName name, @NotNull Class clazz, boolean caseInsensitive) { + for (ItemDefinition def : getDefinitions()) { + if (def.isValidFor(name, clazz, caseInsensitive)) { + return (T) def; + } + } + return null; + } + + @Override + public ID findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + for (;;) { + if (path.isEmpty()) { + throw new IllegalArgumentException("Cannot resolve empty path on complex type definition "+this); + } + ItemPathSegment first = path.first(); + if (first instanceof NameItemPathSegment) { + QName firstName = ((NameItemPathSegment)first).getName(); + return findNamedItemDefinition(firstName, path.rest(), clazz); + } else if (first instanceof IdItemPathSegment) { + path = path.rest(); + } else if (first instanceof ParentPathSegment) { + ItemPath rest = path.rest(); + ComplexTypeDefinition parent = getSchemaRegistry().determineParentDefinition(this, rest); + if (rest.isEmpty()) { + // requires that the parent is defined as an item (container, object) + return (ID) getSchemaRegistry().findItemDefinitionByType(parent.getTypeName()); + } else { + return parent.findItemDefinition(rest, clazz); + } + } else if (first instanceof ObjectReferencePathSegment) { + throw new IllegalStateException("Couldn't use '@' path segment in this context. CTD=" + getTypeName() + ", path=" + path); + } else { + throw new IllegalStateException("Unexpected path segment: " + first + " in " + path); + } + } + } + + // path starts with NamedItemPathSegment + public ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, @NotNull Class clazz) { + ID found = null; + for (ItemDefinition def : getDefinitions()) { + if (def.isValidFor(firstName, clazz, false)) { + if (found != null) { + throw new IllegalStateException("More definitions found for " + firstName + "/" + rest + " in " + this); + } + found = (ID) def.findItemDefinition(rest, clazz); + if (QNameUtil.hasNamespace(firstName)) { + return found; // if qualified then there's no risk of matching more entries + } + } + } + return found; + } + //endregion + + /** + * Merge provided definition into this definition. + */ + @Override + public void merge(ComplexTypeDefinition otherComplexTypeDef) { + for (ItemDefinition otherItemDef: otherComplexTypeDef.getDefinitions()) { + add(otherItemDef.clone()); + } + } + + @Override + public void revive(PrismContext prismContext) { + if (this.prismContext != null) { + return; + } + this.prismContext = prismContext; + for (ItemDefinition def: itemDefinitions) { + def.revive(prismContext); + } + } + + @Override + public boolean isEmpty() { + return itemDefinitions.isEmpty(); + } + + @NotNull + @Override + public ComplexTypeDefinitionImpl clone() { + ComplexTypeDefinitionImpl clone = new ComplexTypeDefinitionImpl(this.typeName, prismContext); + copyDefinitionData(clone); + return clone; + } + + public ComplexTypeDefinition deepClone() { + return deepClone(new HashMap<>()); + } + + @NotNull + @Override + public ComplexTypeDefinition deepClone(Map ctdMap) { + if (ctdMap != null) { + ComplexTypeDefinition clone = ctdMap.get(this.getTypeName()); + if (clone != null) { + return clone; // already cloned + } + } + ComplexTypeDefinitionImpl clone = clone(); // shallow + if (ctdMap != null) { + ctdMap.put(this.getTypeName(), clone); + } + clone.itemDefinitions.clear(); + for (ItemDefinition itemDef: this.itemDefinitions) { + clone.itemDefinitions.add(itemDef.deepClone(ctdMap)); + } + return clone; + } + + protected void copyDefinitionData(ComplexTypeDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.containerMarker = this.containerMarker; + clone.objectMarker = this.objectMarker; + clone.xsdAnyMarker = this.xsdAnyMarker; + clone.extensionForType = this.extensionForType; + clone.defaultNamespace = this.defaultNamespace; + clone.ignoredNamespaces = this.ignoredNamespaces; + clone.itemDefinitions.addAll(this.itemDefinitions); + } + + public void replaceDefinition(QName propertyName, ItemDefinition newDefinition) { + for (int i=0; i def) { + // Do nothing + } + + /** + * Return a human readable name of this class suitable for logs. + */ + @Override + protected String getDebugDumpClassName() { + return "CTD"; + } + + @Override + public String getDocClassName() { + return "complex type"; + } + +// @Override +// public void accept(Visitor visitor) { +// super.accept(visitor); +// itemDefinitions.forEach(def -> def.accept(visitor)); +// } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Containerable.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Containerable.java index 50e34e1aeb1..67c05055f51 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Containerable.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Containerable.java @@ -24,13 +24,13 @@ public interface Containerable extends Serializable { - public PrismContainerValue asPrismContainerValue(); + PrismContainerValue asPrismContainerValue(); /** * Setup value to the containerable representation. This is used to after (empty) containerable is created to * initialize it with a correct prism container value. * Note: This method DOES NOT change the container value parent. */ - public void setupContainerValue(PrismContainerValue container); + void setupContainerValue(PrismContainerValue container); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Definition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Definition.java index dc375fa116e..6452d27c58a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Definition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Definition.java @@ -16,165 +16,108 @@ package com.evolveum.midpoint.prism; -import java.io.Serializable; - -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.PrettyPrinter; - import com.evolveum.midpoint.prism.schema.SchemaRegistry; -import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.util.DebugDumpable; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.io.Serializable; /** - * Abstract definition in the schema. - * - * This is supposed to be a superclass for all definitions. It defines common - * properties for all definitions. - * - * The definitions represent data structures of the schema. Therefore instances - * of Java objects from this class represent specific definitions from - * the schema, not specific properties or objects. E.g the definitions does not - * have any value. - * - * To transform definition to a real property or object use the explicit - * instantiate() methods provided in the definition classes. E.g. the - * instantiate() method will create instance of Property using appropriate - * PropertyDefinition. - * - * The convenience methods in Schema are using this abstract class to find - * appropriate definitions easily. - * - * @author Radovan Semancik - * + * @author mederly */ -public abstract class Definition implements Serializable, DebugDumpable, Revivable { - - private static final long serialVersionUID = -2643332934312107274L; - protected QName typeName; - protected boolean ignored = false; - protected boolean isAbstract = false; - protected String displayName; - protected Integer displayOrder; - protected String help; - protected String documentation; - protected boolean deprecated = false; - - /** - * whether an item is inherited from a supertype (experimental feature) - */ - protected boolean inherited = false; - - /** - * This means that the property container is not defined by fixed (compile-time) schema. - * This in fact means that we need to use getAny in a JAXB types. It does not influence the - * processing of DOM that much, as that does not really depend on compile-time/run-time distinction. - */ - protected boolean isRuntimeSchema; - - /** - * Set true for definitions that are more important than others and that should be emphasized - * during presentation. E.g. the emphasized definitions will always be displayed in the user - * interfaces (even if they are empty), they will always be included in the dumps, etc. - */ - protected boolean emphasized = false; - - protected transient PrismContext prismContext; - - Definition(QName typeName, PrismContext prismContext) { - if (typeName == null) { - throw new IllegalArgumentException("Type name can't be null."); - } - if (prismContext == null) { - throw new IllegalArgumentException("prismContext can't be null."); - } - this.typeName = typeName; - this.prismContext = prismContext; - } +public interface Definition extends Serializable, DebugDumpable, Revivable { /** - * Returns the name of the definition type. - * * Returns a name of the type for this definition. - * - * In XML representation that corresponds to the name of the XSD type. - * - * @return the typeName + * + * The type can be part of the compile-time schema or it can be defined at run time. + * + * Examples of the former case are types like c:UserType, xsd:string, or even flexible + * ones like c:ExtensionType or c:ShadowAttributesType. + * + * Examples of the latter case are types used in + * - custom extensions, like ext:LocationsType (where ext = e.g. http://example.com/extension), + * - resource schema, like ri:inetOrgPerson (ri = http://.../resource/instance-3), + * - connector schema, like TODO + * + * In XML representation that corresponds to the name of the XSD type. Although beware, the + * run-time types do not have statically defined structure. And the resource and connector-related + * types may even represent different kinds of objects within different contexts (e.g. two + * distinct resources both with ri:AccountObjectClass types). + * + * Also note that for complex type definitions, the type name serves as a unique identifier. + * On the other hand, for item definitions, it is just one of its attributes; primary key + * is item name in that case. + * + * The type name should be fully qualified. (TODO reconsider this) + * + * @return the type name */ - public QName getTypeName() { - return typeName; - } - - public void setTypeName(QName typeName) { - this.typeName = typeName; - } - - public boolean isIgnored() { - return ignored; - } - - public void setIgnored(boolean ignored) { - this.ignored = ignored; - } - - public boolean isAbstract() { - return isAbstract; - } - - public void setAbstract(boolean isAbstract) { - this.isAbstract = isAbstract; - } + @NotNull + QName getTypeName(); - public boolean isDeprecated() { - return deprecated; - } - - public void setDeprecated(boolean deprecated) { - this.deprecated = deprecated; - } + /** + * This means that the entities described by this schema (items, complex types) or their content + * is not defined by fixed (compile-time) schema. I.e. it is known only at run time. + * + * Some examples for "false" value: + * - c:user, c:UserType - statically defined type with statically defined content. + * + * Some examples for "true" value: + * - c:extension, c:ExtensionType - although the entity itself (item, type) are defined in + * the static schema, their content is not known at compile time; + * - c:attributes, c:ShadowAttributeType - the same as extension/ExtensionType; + * - ext:weapon (of type xsd:string) - even if the content is statically defined, + * the definition of the item itself is not known at compile time; + * - ri:inetOrgPerson, ext:LocationsType, ext:locations - both the entity + * and their content are known at run time only. + * + * TODO clarify the third point; provide some tests for the 3rd and 4th point + */ + boolean isRuntimeSchema(); - public boolean isInherited() { - return inherited; - } + /** + * Item definition that has this flag set should be ignored by any processing. + * The ignored item is still part of the schema. Item instances may appear in + * the serialized data formats (e.g. XML) or data store and the parser should + * not raise an error if it encounters them. But any high-level processing code + * should ignore presence of this item. E.g. it should not be displayed to the user, + * should not be present in transformed data structures, etc. + * + * Note that the same item can be ignored at higher layer (e.g. presentation) + * but not ignored at lower layer (e.g. model). This works by presenting different + * item definitions for these layers (see LayerRefinedAttributeDefinition). + * + * Semantics of this flag for complex type definitions is to be defined yet. + */ + boolean isIgnored(); - public void setInherited(boolean inherited) { - this.inherited = inherited; - } + boolean isAbstract(); - /** - * Set true for definitions that are more important than others and that should be emphasized - * during presentation. E.g. the emphasized definitions will always be displayed in the user - * interfaces (even if they are empty), they will always be included in the dumps, etc. - */ - public boolean isEmphasized() { - return emphasized; - } + boolean isDeprecated(); - public void setEmphasized(boolean emphasized) { - this.emphasized = emphasized; - } + /** + * True for definitions that are more important than others and that should be emphasized + * during presentation. E.g. the emphasized definitions will always be displayed in the user + * interfaces (even if they are empty), they will always be included in the dumps, etc. + */ + boolean isEmphasized(); /** * Returns display name. - * + * * Specifies the printable name of the object class or attribute. It must * contain a printable string. It may also contain a key to catalog file. - * + * * Returns null if no display name is set. - * + * * Corresponds to "displayName" XSD annotation. - * + * * @return display name string or catalog key */ - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - + String getDisplayName(); + /** * Specifies an order in which the item should be displayed relative to other items * at the same level. The items will be displayed by sorting them by the @@ -182,155 +125,43 @@ public void setDisplayName(String displayName) { * any displayOrder annotation will be displayed last. The ordering of * values with the same displayOrder is undefined and it may be arbitrary. */ - public Integer getDisplayOrder() { - return displayOrder; - } - - public void setDisplayOrder(Integer displayOrder) { - this.displayOrder = displayOrder; - } + Integer getDisplayOrder(); /** * Returns help string. - * + * * Specifies the help text or a key to catalog file for a help text. The * help text may be displayed in any suitable way by the GUI. It should * explain the meaning of an attribute or object class. - * + * * Returns null if no help string is set. - * + * * Corresponds to "help" XSD annotation. - * + * * @return help string or catalog key */ - public String getHelp() { - return help; - } - - public void setHelp(String help) { - this.help = help; - } + String getHelp(); - public String getDocumentation() { - return documentation; - } + String getDocumentation(); - public void setDocumentation(String documentation) { - this.documentation = documentation; - } + /** + * Returns only a first sentence of documentation. + */ + String getDocumentationPreview(); - /** - * Returns only a first sentence of documentation. - */ - public String getDocumentationPreview() { - if (documentation == null || documentation.isEmpty()) { - return documentation; - } - String plainDoc = MiscUtil.stripHtmlMarkup(documentation); - int i = plainDoc.indexOf('.'); - if (i<0) { - return plainDoc; - } - return plainDoc.substring(0,i+1); - } - public boolean isRuntimeSchema() { - return isRuntimeSchema; - } + PrismContext getPrismContext(); - public void setRuntimeSchema(boolean isRuntimeSchema) { - this.isRuntimeSchema = isRuntimeSchema; - } - - public PrismContext getPrismContext() { - return prismContext; - } - - protected SchemaRegistry getSchemaRegistry() { - return prismContext.getSchemaRegistry(); + default SchemaRegistry getSchemaRegistry() { + PrismContext prismContext = getPrismContext(); + return prismContext != null ? prismContext.getSchemaRegistry() : null; } - public Class getTypeClassIfKnown() { - return XsdTypeMapper.toJavaTypeIfKnown(getTypeName()); - } + // TODO fix this! + Class getTypeClassIfKnown(); - public Class getTypeClass() { - return XsdTypeMapper.toJavaType(getTypeName()); - } - - public abstract void revive(PrismContext prismContext); - - public abstract Definition clone(); - - protected void copyDefinitionData(Definition clone) { - clone.ignored = this.ignored; - clone.typeName = this.typeName; - clone.displayName = this.displayName; - clone.displayOrder = this.displayOrder; - clone.help = this.help; - clone.inherited = this.inherited; - clone.documentation = this.documentation; - clone.isAbstract = this.isAbstract; - clone.deprecated = this.deprecated; - clone.isRuntimeSchema = this.isRuntimeSchema; - clone.emphasized = this.emphasized; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (ignored ? 1231 : 1237); - result = prime * result + ((typeName == null) ? 0 : typeName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Definition other = (Definition) obj; - if (ignored != other.ignored) - return false; - if (typeName == null) { - if (other.typeName != null) - return false; - } else if (!typeName.equals(other.typeName)) - return false; - return true; - } - - @Override - public String toString() { - return getDebugDumpClassName() + " ("+PrettyPrinter.prettyPrint(getTypeName())+")"; - } - - @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - for (int i=0; idefinitions from + * the schema, not specific properties or objects. E.g the definitions does not + * have any value. + * + * To transform definition to a real property or object use the explicit + * instantiate() methods provided in the definition classes. E.g. the + * instantiate() method will create instance of Property using appropriate + * PropertyDefinition. + * + * The convenience methods in Schema are using this abstract class to find + * appropriate definitions easily. + * + * @author Radovan Semancik + * + */ +public abstract class DefinitionImpl implements Definition { + + private static final long serialVersionUID = -2643332934312107274L; + @NotNull protected QName typeName; + protected boolean ignored = false; + protected boolean isAbstract = false; + protected String displayName; + protected Integer displayOrder; + protected String help; + protected String documentation; + protected boolean deprecated = false; + + /** + * whether an item is inherited from a supertype (experimental feature) + */ + protected boolean inherited = false; + + /** + * This means that the item container is not defined by fixed (compile-time) schema. + * This in fact means that we need to use getAny in a JAXB types. It does not influence the + * processing of DOM that much, as that does not really depend on compile-time/run-time distinction. + */ + protected boolean isRuntimeSchema; + + /** + * Set true for definitions that are more important than others and that should be emphasized + * during presentation. E.g. the emphasized definitions will always be displayed in the user + * interfaces (even if they are empty), they will always be included in the dumps, etc. + */ + protected boolean emphasized = false; + + protected transient PrismContext prismContext; + + DefinitionImpl(@NotNull QName typeName, @NotNull PrismContext prismContext) { + this.typeName = typeName; + this.prismContext = prismContext; + } + + + @Override + @NotNull + public QName getTypeName() { + return typeName; + } + + public void setTypeName(@NotNull QName typeName) { + this.typeName = typeName; + } + + @Override + public boolean isIgnored() { + return ignored; + } + + public void setIgnored(boolean ignored) { + this.ignored = ignored; + } + + @Override + public boolean isAbstract() { + return isAbstract; + } + + public void setAbstract(boolean isAbstract) { + this.isAbstract = isAbstract; + } + + @Override + public boolean isDeprecated() { + return deprecated; + } + + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + public void setInherited(boolean inherited) { + this.inherited = inherited; + } + + @Override + public boolean isEmphasized() { + return emphasized; + } + + public void setEmphasized(boolean emphasized) { + this.emphasized = emphasized; + } + + @Override + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + @Override + public Integer getDisplayOrder() { + return displayOrder; + } + + public void setDisplayOrder(Integer displayOrder) { + this.displayOrder = displayOrder; + } + + @Override + public String getHelp() { + return help; + } + + public void setHelp(String help) { + this.help = help; + } + + @Override + public String getDocumentation() { + return documentation; + } + + public void setDocumentation(String documentation) { + this.documentation = documentation; + } + + @Override + public String getDocumentationPreview() { + if (documentation == null || documentation.isEmpty()) { + return documentation; + } + String plainDoc = MiscUtil.stripHtmlMarkup(documentation); + int i = plainDoc.indexOf('.'); + if (i<0) { + return plainDoc; + } + return plainDoc.substring(0,i+1); + } + + @Override + public boolean isRuntimeSchema() { + return isRuntimeSchema; + } + + public void setRuntimeSchema(boolean isRuntimeSchema) { + this.isRuntimeSchema = isRuntimeSchema; + } + + @Override + public PrismContext getPrismContext() { + return prismContext; + } + + @Override + public Class getTypeClassIfKnown() { + return XsdTypeMapper.toJavaTypeIfKnown(getTypeName()); + } + + @Override + public Class getTypeClass() { + return XsdTypeMapper.toJavaType(getTypeName()); + } + + public abstract void revive(PrismContext prismContext); + + protected void copyDefinitionData(DefinitionImpl clone) { + clone.ignored = this.ignored; + clone.typeName = this.typeName; + clone.displayName = this.displayName; + clone.displayOrder = this.displayOrder; + clone.help = this.help; + clone.inherited = this.inherited; + clone.documentation = this.documentation; + clone.isAbstract = this.isAbstract; + clone.deprecated = this.deprecated; + clone.isRuntimeSchema = this.isRuntimeSchema; + clone.emphasized = this.emphasized; + } + + @SuppressWarnings("ConstantConditions") + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (ignored ? 1231 : 1237); + result = prime * result + ((typeName == null) ? 0 : typeName.hashCode()); + return result; + } + + @SuppressWarnings("ConstantConditions") + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DefinitionImpl other = (DefinitionImpl) obj; + if (ignored != other.ignored) + return false; + if (typeName == null) { + if (other.typeName != null) + return false; + } else if (!typeName.equals(other.typeName)) + return false; + return true; + } + + @Override + public String toString() { + return getDebugDumpClassName() + " ("+PrettyPrinter.prettyPrint(getTypeName())+")"; + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + for (int i=0; i PartiallyResolvedItem findPartial(ItemPath path); + + boolean equals(PrismValue otherValue, boolean ignoreMetadata); + + Collection diff(PrismValue otherValue); + + Collection diff(PrismValue otherValue, boolean ignoreMetadata, boolean isLiteral); + + boolean match(PrismValue otherValue); + + /** + * Returns a short (one-line) representation of the real value stored in this object. + * The value is returned without any decorations or type demarcations (such as PPV, PRV, etc.) + */ + String toHumanReadableString(); + + boolean isImmutable(); +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java index 79be40a3c87..ade3d8f543e 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java @@ -24,19 +24,13 @@ import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; +import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; import java.io.Serializable; import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - +import java.util.*; /** * Item is a common abstraction of Property and PropertyContainer. @@ -58,8 +52,10 @@ public abstract class Item imple protected QName elementName; protected PrismValue parent; protected D definition; - private List values = new ArrayList(); + @NotNull private final List values = new ArrayList<>(); private transient Map userData = new HashMap<>();; + + protected boolean immutable; protected transient PrismContext prismContext; // beware, this one can easily be null @@ -134,9 +130,10 @@ public QName getElementName() { *

* The name is the QName of XML element in the XML representation. * - * @param name the name to set + * @param elementName the name to set */ public void setElementName(QName elementName) { + checkMutability(); this.elementName = elementName; } @@ -146,6 +143,7 @@ public void setElementName(QName elementName) { * @param definition the definition to set */ public void setDefinition(D definition) { + checkMutability(); checkDefinition(definition); this.definition = definition; } @@ -188,6 +186,11 @@ public PrismContext getPrismContext() { return null; } } + + // Primarily for testing + public PrismContext getPrismContextLocal() { + return prismContext; + } public void setPrismContext(PrismContext prismContext) { this.prismContext = prismContext; @@ -201,6 +204,8 @@ public void setParent(PrismValue parentValue) { if (this.parent != null && parentValue != null && this.parent != parentValue) { throw new IllegalStateException("Attempt to reset parent of item "+this+" from "+this.parent+" to "+parentValue); } + // Immutability check can be skipped, as setting the parent doesn't alter this object. + // However, if existing parent itself is immutable, adding/removing its child item will cause the exception. this.parent = parentValue; } @@ -215,17 +220,24 @@ public Map getUserData() { if (userData == null) { userData = new HashMap<>(); } - return userData; + if (immutable) { + return Collections.unmodifiableMap(userData); // TODO beware, objects in userData themselves are mutable + } else { + return userData; + } } public Object getUserData(String key) { + // TODO make returned data immutable (?) return getUserData().get(key); } public void setUserData(String key, Object value) { + checkMutability(); getUserData().put(key, value); } + @NotNull public List getValues() { return values; } @@ -370,6 +382,7 @@ public int size() { } public boolean addAll(Collection newValues) throws SchemaException { + checkMutability(); // TODO consider weaker condition, like testing if there's a real change boolean changed = false; for (V val: newValues) { if (add(val)) { @@ -384,6 +397,10 @@ public boolean add(V newValue) throws SchemaException { } public boolean add(V newValue, boolean checkUniqueness) throws SchemaException { + checkMutability(); + if (newValue.getPrismContext() == null) { + newValue.setPrismContext(prismContext); + } newValue.setParent(this); if (checkUniqueness && containsEquivalentValue(newValue)) { return false; @@ -395,6 +412,7 @@ public boolean add(V newValue, boolean checkUniqueness) throws SchemaException { } public boolean removeAll(Collection newValues) { + checkMutability(); // TODO consider if there is real change boolean changed = false; for (V val: newValues) { if (remove(val)) { @@ -405,6 +423,7 @@ public boolean removeAll(Collection newValues) { } public boolean remove(V newValue) { + checkMutability(); // TODO consider if there is real change boolean changed = false; Iterator iterator = values.iterator(); while (iterator.hasNext()) { @@ -418,26 +437,31 @@ public boolean remove(V newValue) { } public V remove(int index) { + checkMutability(); // TODO consider if there is real change return values.remove(index); } public void replaceAll(Collection newValues) throws SchemaException { + checkMutability(); // TODO consider if there is real change values.clear(); addAll(newValues); } public void replace(V newValue) { + checkMutability(); // TODO consider if there is real change values.clear(); newValue.setParent(this); values.add(newValue); } public void clear() { - values.clear(); + checkMutability(); // TODO consider if there is real change + values.clear(); } public void normalize() { - Iterator iterator = values.iterator(); + checkMutability(); // TODO consider if there is real change + Iterator iterator = values.iterator(); while (iterator.hasNext()) { V value = iterator.next(); value.normalize(); @@ -512,7 +536,7 @@ protected void diffInternal(Item other, Collection del // No need to process this value again iterator.remove(); break; - } + } } if (!found) { // We have the value and the other does not, this is delete of the entire value @@ -570,6 +594,7 @@ public void applyDefinition(D definition) throws SchemaException { } public void applyDefinition(D definition, boolean force) throws SchemaException { + checkMutability(); // TODO consider if there is real change if (definition != null) { checkDefinition(definition); } @@ -590,12 +615,10 @@ public void revive(PrismContext prismContext) throws SchemaException { definition.revive(prismContext); } } - if (values != null) { - for (V value: values) { - value.revive(prismContext); - } - } - } + for (V value: values) { + value.revive(prismContext); + } + } public abstract Item clone(); @@ -607,6 +630,7 @@ protected void copyValues(Item clone) { // another item clone.parent = null; clone.userData = MiscUtil.cloneMap(this.userData); + // Also do not copy 'immutable' flag so the clone is free to be modified } protected void propagateDeepCloneDefinition(boolean ultraDeep, D clonedDefinition) { @@ -742,7 +766,7 @@ public boolean hasRaw() { } public boolean isEmpty() { - return (getValues() == null || getValues().isEmpty()); + return getValues().isEmpty(); } @Override @@ -887,11 +911,27 @@ public String debugDump(int indent) { return sb.toString(); } - /** + /** * Return a human readable name of this class suitable for logs. */ protected String getDebugDumpClassName() { return "Item"; } - + + public boolean isImmutable() { + return immutable; + } + + public void setImmutable(boolean immutable) { + this.immutable = immutable; + for (V value : getValues()) { + value.setImmutable(immutable); + } + } + + protected void checkMutability() { + if (immutable) { + throw new IllegalStateException("An attempt to modify an immutable item: " + toString()); + } + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinition.java index d0571fbe7f1..845bbca2e01 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinition.java @@ -16,172 +16,43 @@ package com.evolveum.midpoint.prism; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.namespace.QName; - import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; -import org.apache.commons.lang.StringUtils; +import javax.xml.namespace.QName; +import java.io.Serializable; +import java.util.Map; /** - * Abstract item definition in the schema. - * - * This is supposed to be a superclass for all item definitions. Items are things - * that can appear in property containers, which generally means only a property - * and property container itself. Therefore this is in fact superclass for those - * two definitions. - * - * The definitions represent data structures of the schema. Therefore instances - * of Java objects from this class represent specific definitions from - * the schema, not specific properties or objects. E.g the definitions does not - * have any value. - * - * To transform definition to a real property or object use the explicit - * instantiate() methods provided in the definition classes. E.g. the - * instantiate() method will create instance of Property using appropriate - * PropertyDefinition. - * - * The convenience methods in Schema are using this abstract class to find - * appropriate definitions easily. - * - * @author Radovan Semancik - * + * @author mederly */ -public abstract class ItemDefinition extends Definition implements Serializable { +public interface ItemDefinition extends Definition { - private static final long serialVersionUID = -2643332934312107274L; - protected QName name; - private int minOccurs = 1; - private int maxOccurs = 1; - private boolean operational = false; - private boolean dynamic; - private boolean canAdd = true; - private boolean canRead = true; - private boolean canModify = true; - private PrismReferenceValue valueEnumerationRef; + @NotNull + QName getName(); - // TODO: annotations + String getNamespace(); - /** - * The constructors should be used only occasionally (if used at all). - * Use the factory methods in the ResourceObjectDefintion instead. - * - * @param name definition name (element Name) - * @param defaultName default element name - * @param typeName type name (XSD complex or simple type) - */ - ItemDefinition(QName elementName, QName typeName, PrismContext prismContext) { - super(typeName, prismContext); - this.name = elementName; - } + int getMinOccurs(); - /** - * Returns name of the defined entity. - * - * The name is a name of the entity instance if it is fixed by the schema. - * E.g. it may be a name of the property in the container that cannot be - * changed. - * - * The name corresponds to the XML element name in the XML representation of - * the schema. It does NOT correspond to a XSD type name. - * - * Name is optional. If name is not set the null value is returned. If name is - * not set the type is "abstract", does not correspond to the element. - * - * @return the name name of the entity or null. - */ - public QName getName() { - return name; - } + int getMaxOccurs(); - public void setName(QName name) { - this.name = name; - } - - public String getNamespace() { - return getName().getNamespaceURI(); - } - - /** - * Return the number of minimal value occurrences. - * - * @return the minOccurs - */ - public int getMinOccurs() { - return minOccurs; - } + boolean isSingleValue(); - public void setMinOccurs(int minOccurs) { - this.minOccurs = minOccurs; - } - - /** - * Return the number of maximal value occurrences. - *

- * Any negative number means "unbounded". - * - * @return the maxOccurs - */ - public int getMaxOccurs() { - return maxOccurs; - } + boolean isMultiValue(); - public void setMaxOccurs(int maxOccurs) { - this.maxOccurs = maxOccurs; - } - - /** - * Returns true if property is single-valued. - * - * @return true if property is single-valued. - */ - public boolean isSingleValue() { - int maxOccurs = getMaxOccurs(); - return maxOccurs >= 0 && maxOccurs <= 1; - } + boolean isMandatory(); - /** - * Returns true if property is multi-valued. - * - * @return true if property is multi-valued. - */ - public boolean isMultiValue() { - int maxOccurs = getMaxOccurs(); - return maxOccurs < 0 || maxOccurs > 1; - } + boolean isOptional(); - /** - * Returns true if property is mandatory. - * - * @return true if property is mandatory. - */ - public boolean isMandatory() { - return getMinOccurs() > 0; - } + boolean isOperational(); - /** - * Returns true if property is optional. - * - * @return true if property is optional. - */ - public boolean isOptional() { - return getMinOccurs() == 0; - } - - public boolean isOperational() { - return operational; - } - - public void setOperational(boolean operational) { - this.operational = operational; - } + /** + * Whether an item is inherited from a supertype. + */ + boolean isInherited(); /** * Returns true if definition was created during the runtime based on a dynamic information @@ -190,295 +61,48 @@ public void setOperational(boolean operational) { * part of any schema and therefore cannot be determined. It may even be different for every * instance of the associated item (element name). */ - public boolean isDynamic() { - return dynamic; - } - - public void setDynamic(boolean dynamic) { - this.dynamic = dynamic; - } - - /** - * Returns true if the property can be read. I.e. if it is returned in objects - * retrieved from "get", "search" and similar operations. - */ - public boolean canRead() { - return canRead; - } - - /** - * Returns true if the item can be modified. I.e. if it can be changed - * during a modification of existing object. - */ - public boolean canModify() { - return canModify; - } - - /** - * - */ - public void setReadOnly() { - canAdd = false; - canRead = true; - canModify = false; - } - - public void setCanRead(boolean read) { - this.canRead = read; - } + boolean isDynamic(); - public void setCanModify(boolean modify) { - this.canModify = modify; - } + boolean canRead(); - public void setCanAdd(boolean add) { - this.canAdd = add; - } + boolean canModify(); - /** - * Returns true if the item can be added. I.e. if it can be present - * in the object when a new object is created. - */ - public boolean canAdd() { - return canAdd; - } + boolean canAdd(); - /** - * Reference to an object that directly or indirectly represents possible values for - * this item. We do not define here what exactly the object has to be. It can be a lookup - * table, script that dynamically produces the values or anything similar. - * The object must produce the values of the correct type for this item otherwise an - * error occurs. - */ - public PrismReferenceValue getValueEnumerationRef() { - return valueEnumerationRef; - } + PrismReferenceValue getValueEnumerationRef(); - public void setValueEnumerationRef(PrismReferenceValue valueEnumerationRef) { - this.valueEnumerationRef = valueEnumerationRef; - } + boolean isValidFor(QName elementQName, Class clazz); - public boolean isValidFor(QName elementQName, Class clazz) { - return isValidFor(elementQName, clazz, false); - } + boolean isValidFor(@NotNull QName elementQName, @NotNull Class clazz, boolean caseInsensitive); - public boolean isValidFor(QName elementQName, Class clazz, boolean caseInsensitive) { - if (!clazz.isAssignableFrom(this.getClass())) { - return false; - } - if (QNameUtil.match(elementQName, getName(), caseInsensitive)) { - return true; - } - return false; - } - - public void adoptElementDefinitionFrom(ItemDefinition otherDef) { - if (otherDef == null) { - return; - } - setName(otherDef.getName()); - setMinOccurs(otherDef.getMinOccurs()); - setMaxOccurs(otherDef.getMaxOccurs()); - } + void adoptElementDefinitionFrom(ItemDefinition otherDef); /** * Create an item instance. Definition name or default name will * used as an element name for the instance. The instance will otherwise be empty. * @return created item instance */ - abstract public I instantiate() throws SchemaException; + I instantiate() throws SchemaException; /** * Create an item instance. Definition name will use provided name. * for the instance. The instance will otherwise be empty. * @return created item instance */ - abstract public I instantiate(QName name) throws SchemaException; + I instantiate(QName name) throws SchemaException; - // add namespace from the definition if it's safe to do so - protected QName addNamespaceIfApplicable(QName name) { - if (StringUtils.isEmpty(name.getNamespaceURI())) { - if (QNameUtil.match(name, this.name)) { - return this.name; - } - } - return name; - } + T findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz); - T findItemDefinition(ItemPath path, Class clazz) { - if (path.isEmpty()) { - if (clazz.isAssignableFrom(this.getClass())) { - return (T) this; - } else { - throw new IllegalArgumentException("Looking for definition of class " + clazz + " but found " + this); - } - } else { - throw new IllegalArgumentException("No definition for path " + path + " in " + this); - } - } - - abstract public ItemDelta createEmptyDelta(ItemPath path); - - abstract public ItemDefinition clone(); - - protected void copyDefinitionData(ItemDefinition clone) { - super.copyDefinitionData(clone); - clone.name = this.name; - clone.minOccurs = this.minOccurs; - clone.maxOccurs = this.maxOccurs; - clone.dynamic = this.dynamic; - clone.canAdd = this.canAdd; - clone.canRead = this.canRead; - clone.canModify = this.canModify; - clone.operational = this.operational; - clone.valueEnumerationRef = this.valueEnumerationRef; - } + ItemDelta createEmptyDelta(ItemPath path); - /** - * Make a deep clone, cloning all the sub-items and definitions. - * - * @param ultraDeep if set to true then even the objects that were same instance in the original will be - * cloned as separate instances in the clone. - * - */ - public ItemDefinition deepClone(boolean ultraDeep) { - if (ultraDeep) { - return deepClone(null); - } else { - return deepClone(new HashMap()); - } - } - - ItemDefinition deepClone(Map ctdMap) { - return clone(); - } - - @Override - public void revive(PrismContext prismContext) { - if (this.prismContext != null) { - return; - } - this.prismContext = prismContext; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + maxOccurs; - result = prime * result + minOccurs; - result = prime * result + (canAdd ? 1231 : 1237); - result = prime * result + (canRead ? 1231 : 1237); - result = prime * result + (canModify ? 1231 : 1237); - return result; - } + @NotNull + ItemDefinition clone(); - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - ItemDefinition other = (ItemDefinition) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (maxOccurs != other.maxOccurs) - return false; - if (minOccurs != other.minOccurs) - return false; - if (canAdd != other.canAdd) - return false; - if (canRead != other.canRead) - return false; - if (canModify != other.canModify) - return false; - return true; - } + ItemDefinition deepClone(boolean ultraDeep); - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getDebugDumpClassName()); - sb.append(":"); - sb.append(PrettyPrinter.prettyPrint(getName())); - sb.append(" "); - debugDumpShortToString(sb); - return sb.toString(); - } - - /** - * Used in debugDumping items. Does not need to have name in it as item already has it. Does not need - * to have class as that is just too much info that is almost anytime pretty obvious anyway. - */ - void debugDumpShortToString(StringBuilder sb) { - sb.append(PrettyPrinter.prettyPrint(getTypeName())); - debugMultiplicity(sb); - debugFlags(sb); - } + ItemDefinition deepClone(Map ctdMap); - private void debugMultiplicity(StringBuilder sb) { - sb.append("["); - sb.append(getMinOccurs()); - sb.append(","); - sb.append(getMaxOccurs()); - sb.append("]"); - } - - public String debugMultiplicity() { - StringBuilder sb = new StringBuilder(); - debugMultiplicity(sb); - return sb.toString(); - } - - private void debugFlags(StringBuilder sb) { - if (isIgnored()) { - sb.append(",ignored"); - } - if (isDynamic()) { - sb.append(",dyn"); - } - extendToString(sb); - } + @Override + void revive(PrismContext prismContext); - public String debugFlags() { - StringBuilder sb = new StringBuilder(); - debugFlags(sb); - // This starts with a collon, we do not want it here - if (sb.length() > 0) { - sb.deleteCharAt(0); - } - return sb.toString(); - } - - protected void extendToString(StringBuilder sb) { - sb.append(","); - if (canRead()) { - sb.append("R"); - } else { - sb.append("-"); - } - if (canAdd()) { - sb.append("A"); - } else { - sb.append("-"); - } - if (canModify()) { - sb.append("M"); - } else { - sb.append("-"); - } - if (isRuntimeSchema()) { - sb.append(",runtime"); - } - if (isOperational()) { - sb.append(",oper"); - } - } - } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinitionImpl.java new file mode 100644 index 00000000000..e50005ebec4 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemDefinitionImpl.java @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; + +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; + +/** + * Abstract item definition in the schema. + * + * This is supposed to be a superclass for all item definitions. Items are things + * that can appear in property containers, which generally means only a property + * and property container itself. Therefore this is in fact superclass for those + * two definitions. + * + * The definitions represent data structures of the schema. Therefore instances + * of Java objects from this class represent specific definitions from + * the schema, not specific properties or objects. E.g the definitions does not + * have any value. + * + * To transform definition to a real property or object use the explicit + * instantiate() methods provided in the definition classes. E.g. the + * instantiate() method will create instance of Property using appropriate + * PropertyDefinition. + * + * The convenience methods in Schema are using this abstract class to find + * appropriate definitions easily. + * + * @author Radovan Semancik + * + */ +public abstract class ItemDefinitionImpl extends DefinitionImpl implements ItemDefinition { + + private static final long serialVersionUID = -2643332934312107274L; + @NotNull protected QName name; + private int minOccurs = 1; + private int maxOccurs = 1; + private boolean operational = false; + private boolean dynamic; + private boolean canAdd = true; + private boolean canRead = true; + private boolean canModify = true; + private boolean inherited; + private PrismReferenceValue valueEnumerationRef; + + // TODO: annotations + + /** + * The constructors should be used only occasionally (if used at all). + * Use the factory methods in the ResourceObjectDefintion instead. + * + * @param name definition name (element Name) + * @param typeName type name (XSD complex or simple type) + */ + ItemDefinitionImpl(@NotNull QName name, @NotNull QName typeName, @NotNull PrismContext prismContext) { + super(typeName, prismContext); + this.name = name; + } + + /** + * Returns name of the defined entity. + * + * The name is a name of the entity instance if it is fixed by the schema. + * E.g. it may be a name of the property in the container that cannot be + * changed. + * + * The name corresponds to the XML element name in the XML representation of + * the schema. It does NOT correspond to a XSD type name. + * + * Name is optional. If name is not set the null value is returned. If name is + * not set the type is "abstract", does not correspond to the element. + * + * @return the name name of the entity or null. + */ + @Override + @NotNull + public QName getName() { + return name; + } + + public void setName(@NotNull QName name) { + this.name = name; + } + + @Override + public String getNamespace() { + return getName().getNamespaceURI(); + } + + /** + * Return the number of minimal value occurrences. + * + * @return the minOccurs + */ + @Override + public int getMinOccurs() { + return minOccurs; + } + + public void setMinOccurs(int minOccurs) { + this.minOccurs = minOccurs; + } + + /** + * Return the number of maximal value occurrences. + *

+ * Any negative number means "unbounded". + * + * @return the maxOccurs + */ + @Override + public int getMaxOccurs() { + return maxOccurs; + } + + public void setMaxOccurs(int maxOccurs) { + this.maxOccurs = maxOccurs; + } + + /** + * Returns true if property is single-valued. + * + * @return true if property is single-valued. + */ + @Override + public boolean isSingleValue() { + int maxOccurs = getMaxOccurs(); + return maxOccurs >= 0 && maxOccurs <= 1; + } + + /** + * Returns true if property is multi-valued. + * + * @return true if property is multi-valued. + */ + @Override + public boolean isMultiValue() { + int maxOccurs = getMaxOccurs(); + return maxOccurs < 0 || maxOccurs > 1; + } + + /** + * Returns true if property is mandatory. + * + * @return true if property is mandatory. + */ + @Override + public boolean isMandatory() { + return getMinOccurs() > 0; + } + + /** + * Returns true if property is optional. + * + * @return true if property is optional. + */ + @Override + public boolean isOptional() { + return getMinOccurs() == 0; + } + + @Override + public boolean isOperational() { + return operational; + } + + public void setOperational(boolean operational) { + this.operational = operational; + } + + @Override + public boolean isDynamic() { + return dynamic; + } + + public void setDynamic(boolean dynamic) { + this.dynamic = dynamic; + } + + /** + * Returns true if the property can be read. I.e. if it is returned in objects + * retrieved from "get", "search" and similar operations. + */ + @Override + public boolean canRead() { + return canRead; + } + + /** + * Returns true if the item can be modified. I.e. if it can be changed + * during a modification of existing object. + */ + @Override + public boolean canModify() { + return canModify; + } + + /** + * + */ + public void setReadOnly() { + canAdd = false; + canRead = true; + canModify = false; + } + + public void setCanRead(boolean read) { + this.canRead = read; + } + + public void setCanModify(boolean modify) { + this.canModify = modify; + } + + public void setCanAdd(boolean add) { + this.canAdd = add; + } + + /** + * Returns true if the item can be added. I.e. if it can be present + * in the object when a new object is created. + */ + @Override + public boolean canAdd() { + return canAdd; + } + + /** + * Reference to an object that directly or indirectly represents possible values for + * this item. We do not define here what exactly the object has to be. It can be a lookup + * table, script that dynamically produces the values or anything similar. + * The object must produce the values of the correct type for this item otherwise an + * error occurs. + */ + @Override + public PrismReferenceValue getValueEnumerationRef() { + return valueEnumerationRef; + } + + public void setValueEnumerationRef(PrismReferenceValue valueEnumerationRef) { + this.valueEnumerationRef = valueEnumerationRef; + } + + @Override + public boolean isValidFor(QName elementQName, Class clazz) { + return isValidFor(elementQName, clazz, false); + } + + @Override + public boolean isValidFor(@NotNull QName elementQName, @NotNull Class clazz, + boolean caseInsensitive) { + return clazz.isAssignableFrom(this.getClass()) + && QNameUtil.match(elementQName, getName(), caseInsensitive); + } + + @Override + public void adoptElementDefinitionFrom(ItemDefinition otherDef) { + if (otherDef == null) { + return; + } + setName(otherDef.getName()); + setMinOccurs(otherDef.getMinOccurs()); + setMaxOccurs(otherDef.getMaxOccurs()); + } + + // add namespace from the definition if it's safe to do so + protected QName addNamespaceIfApplicable(QName name) { + if (StringUtils.isEmpty(name.getNamespaceURI())) { + if (QNameUtil.match(name, this.name)) { + return this.name; + } + } + return name; + } + + @Override + public T findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + if (path.isEmpty()) { + if (clazz.isAssignableFrom(this.getClass())) { + return (T) this; + } else { + throw new IllegalArgumentException("Looking for definition of class " + clazz + " but found " + this); + } + } else { + throw new IllegalArgumentException("No definition for path " + path + " in " + this); + } + } + + @NotNull + @Override + public abstract ItemDefinition clone(); + + protected void copyDefinitionData(ItemDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.name = this.name; + clone.minOccurs = this.minOccurs; + clone.maxOccurs = this.maxOccurs; + clone.dynamic = this.dynamic; + clone.canAdd = this.canAdd; + clone.canRead = this.canRead; + clone.canModify = this.canModify; + clone.operational = this.operational; + clone.valueEnumerationRef = this.valueEnumerationRef; + } + + /** + * Make a deep clone, cloning all the sub-items and definitions. + * + * @param ultraDeep if set to true then even the objects that were same instance in the original will be + * cloned as separate instances in the clone. + * + */ + @Override + public ItemDefinition deepClone(boolean ultraDeep) { + if (ultraDeep) { + return deepClone(null); + } else { + return deepClone(new HashMap<>()); + } + } + + @Override + public ItemDefinition deepClone(Map ctdMap) { + return clone(); + } + + @Override + public void revive(PrismContext prismContext) { + if (this.prismContext != null) { + return; + } + this.prismContext = prismContext; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + maxOccurs; + result = prime * result + minOccurs; + result = prime * result + (canAdd ? 1231 : 1237); + result = prime * result + (canRead ? 1231 : 1237); + result = prime * result + (canModify ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ItemDefinitionImpl other = (ItemDefinitionImpl) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (maxOccurs != other.maxOccurs) + return false; + if (minOccurs != other.minOccurs) + return false; + if (canAdd != other.canAdd) + return false; + if (canRead != other.canRead) + return false; + if (canModify != other.canModify) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getDebugDumpClassName()); + sb.append(":"); + sb.append(PrettyPrinter.prettyPrint(getName())); + sb.append(" "); + debugDumpShortToString(sb); + return sb.toString(); + } + + /** + * Used in debugDumping items. Does not need to have name in it as item already has it. Does not need + * to have class as that is just too much info that is almost anytime pretty obvious anyway. + */ + void debugDumpShortToString(StringBuilder sb) { + sb.append(PrettyPrinter.prettyPrint(getTypeName())); + debugMultiplicity(sb); + debugFlags(sb); + } + + private void debugMultiplicity(StringBuilder sb) { + sb.append("["); + sb.append(getMinOccurs()); + sb.append(","); + sb.append(getMaxOccurs()); + sb.append("]"); + } + + public String debugMultiplicity() { + StringBuilder sb = new StringBuilder(); + debugMultiplicity(sb); + return sb.toString(); + } + + private void debugFlags(StringBuilder sb) { + if (isIgnored()) { + sb.append(",ignored"); + } + if (isDynamic()) { + sb.append(",dyn"); + } + extendToString(sb); + } + + public String debugFlags() { + StringBuilder sb = new StringBuilder(); + debugFlags(sb); + // This starts with a collon, we do not want it here + if (sb.length() > 0) { + sb.deleteCharAt(0); + } + return sb.toString(); + } + + protected void extendToString(StringBuilder sb) { + sb.append(","); + if (canRead()) { + sb.append("R"); + } else { + sb.append("-"); + } + if (canAdd()) { + sb.append("A"); + } else { + sb.append("-"); + } + if (canModify()) { + sb.append("M"); + } else { + sb.append("-"); + } + if (isRuntimeSchema()) { + sb.append(",runtime"); + } + if (isOperational()) { + sb.append(",oper"); + } + } + + @Override + public boolean isInherited() { + return inherited; + } + + @Override + public void setInherited(boolean inherited) { + this.inherited = inherited; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemNameQualificationStrategy.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemNameQualificationStrategy.java new file mode 100644 index 00000000000..e1c60c04c8e --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ItemNameQualificationStrategy.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +/** + * @author mederly + */ +public enum ItemNameQualificationStrategy { + + ALWAYS_USE_FULL_URI, + USE_NS_PROPERTY + //UNQUALIFIED_IF_NOT_AMBIGUOUS + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Itemable.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Itemable.java index 3697920dc6a..e48e00474a3 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Itemable.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Itemable.java @@ -24,18 +24,20 @@ * * Currently provides common abstraction on top of Item and ItemDelta, as both can hold values and * construct them in a similar way. + * + * Also used for ValueFilter, although semantics of e.g. getPath() is quite different in this case. * * @author Radovan Semancik * */ public interface Itemable { - public QName getElementName(); + QName getElementName(); - public ItemDefinition getDefinition(); + ItemDefinition getDefinition(); - public PrismContext getPrismContext(); + PrismContext getPrismContext(); - public ItemPath getPath(); + ItemPath getPath(); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/LocalDefinitionStore.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/LocalDefinitionStore.java new file mode 100644 index 00000000000..43688fb9b51 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/LocalDefinitionStore.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.path.ItemPath; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.namespace.QName; + +/** + * Used to retrieve definition from 'local definition store' - i.e. store that contains definition(s) related to one parent item. + * Such stores are prism containers and complex types. + * + * Before midPoint 3.5, some of these methods tried to resolve definitions globally (if the store could contain 'any' definitions). + * However, starting from 3.5, this is a responsibility of a client. It can call methods in SchemaRegistry to help with that. + * + * Note: Although these methods can return null, they are not marked as @Nullable. It is because we want avoid false warnings + * about possible NPEs when used e.g. to find definitions that certainly exist (like c:user etc). + * + * @author mederly + */ +public interface LocalDefinitionStore { + + // (1) single-name resolution + + // (1a) core + ID findItemDefinition(@NotNull QName name, @NotNull Class clazz, boolean caseInsensitive); + + // (1b) derived + @SuppressWarnings("unchecked") + default ID findItemDefinition(@NotNull QName name) { + return (ID) findItemDefinition(name, ItemDefinition.class); + } + + @SuppressWarnings("unchecked") + default PrismPropertyDefinition findPropertyDefinition(@NotNull QName name) { + return findItemDefinition(name, PrismPropertyDefinition.class); + } + + @SuppressWarnings("unchecked") + default PrismReferenceDefinition findReferenceDefinition(@NotNull QName name) { + return findItemDefinition(name, PrismReferenceDefinition.class); + } + + @SuppressWarnings("unchecked") + default PrismContainerDefinition findContainerDefinition(@NotNull QName name) { + return findItemDefinition(name, PrismContainerDefinition.class); + } + + @SuppressWarnings("unchecked") + default PrismContainerDefinition findContainerDefinition(@NotNull String name) { + return findItemDefinition(new QName(name), PrismContainerDefinition.class); + } + + default ID findItemDefinition(@NotNull QName name, @NotNull Class clazz) { + return findItemDefinition(name, clazz, false); + } + + // (2) path resolution + // (2a) core + + ID findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz); + + ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, @NotNull Class clazz); + + // (2b) derived + + @SuppressWarnings("unchecked") + default ID findItemDefinition(@NotNull ItemPath path) { + return (ID) findItemDefinition(path, ItemDefinition.class); + } + + @SuppressWarnings("unchecked") + default PrismPropertyDefinition findPropertyDefinition(@NotNull ItemPath path) { + return findItemDefinition(path, PrismPropertyDefinition.class); + } + + default PrismReferenceDefinition findReferenceDefinition(@NotNull ItemPath path) { + return findItemDefinition(path, PrismReferenceDefinition.class); + } + + @SuppressWarnings("unchecked") + default PrismContainerDefinition findContainerDefinition(@NotNull ItemPath path) { + return findItemDefinition(path, PrismContainerDefinition.class); + } + + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/NameQualificationStrategy.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/NameQualificationStrategy.java new file mode 100644 index 00000000000..ca495670a23 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/NameQualificationStrategy.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +/** + * @author mederly + */ +public enum NameQualificationStrategy { + ALWAYS, + IF_AMBIGUOUS, + IF_NOT_COMMON_OR_AMBIGUOUS; +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Objectable.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Objectable.java index e64cc672165..e6bad33f520 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Objectable.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Objectable.java @@ -23,21 +23,21 @@ */ public interface Objectable extends Containerable { - public String getOid(); + String getOid(); - public void setOid(String oid); + void setOid(String oid); - public String getVersion(); + String getVersion(); - public void setVersion(String version); + void setVersion(String version); - public PolyStringType getName(); + PolyStringType getName(); - public void setName(PolyStringType name); + void setName(PolyStringType name); - public String getDescription(); + String getDescription(); - public void setDescription(String description); + void setDescription(String description); /** * Returns short string representing identity of this object. @@ -45,7 +45,7 @@ public interface Objectable extends Containerable { * in a form suitable for log and diagnostic messages (understandable for * system administrator). */ - public String toDebugName(); + String toDebugName(); /** * Returns short string identification of object type. It should be in a form @@ -54,11 +54,11 @@ public interface Objectable extends Containerable { * QNames or URIs. * @return */ - public String toDebugType(); + String toDebugType(); - public PrismObject asPrismObject(); + PrismObject asPrismObject(); - public void setupContainer(PrismObject object); + void setupContainer(PrismObject object); // public PrismObject asPrismObject(); // diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserElementSource.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserElementSource.java new file mode 100644 index 00000000000..fab208d5b2c --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserElementSource.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @author mederly + */ +public class ParserElementSource implements ParserSource { + + @NotNull private final Element element; + + public ParserElementSource(@NotNull Element element) { + this.element = element; + } + + @NotNull + public Element getElement() { + return element; + } + + @NotNull + @Override + public InputStream getInputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean closeStreamAfterParsing() { + return true; + } + + @Override + public boolean throwsIOException() { + return false; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserFileSource.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserFileSource.java new file mode 100644 index 00000000000..53b02bd9109 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserFileSource.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + * @author mederly + */ +public class ParserFileSource implements ParserSource { + + @NotNull private final File file; + + public ParserFileSource(@NotNull File file) { + this.file = file; + } + + @NotNull + public File getFile() { + return file; + } + + @NotNull + @Override + public InputStream getInputStream() throws FileNotFoundException { + return new FileInputStream(file); + } + + @Override + public boolean closeStreamAfterParsing() { + return true; + } + + @Override + public boolean throwsIOException() { + return true; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserInputStreamSource.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserInputStreamSource.java new file mode 100644 index 00000000000..0f2151b0596 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserInputStreamSource.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.jetbrains.annotations.NotNull; + +import java.io.InputStream; + +/** + * @author mederly + */ +public class ParserInputStreamSource implements ParserSource { + + @NotNull private final InputStream inputStream; + + public ParserInputStreamSource(@NotNull InputStream inputStream) { + this.inputStream = inputStream; + } + + @NotNull + public InputStream getInputStream() { + return inputStream; + } + + @Override + public boolean closeStreamAfterParsing() { + return false; // TODO eventually make configurable + } + + @Override + public boolean throwsIOException() { + return true; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserSource.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserSource.java new file mode 100644 index 00000000000..cbfd80590b7 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserSource.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.jetbrains.annotations.NotNull; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Source for prism parser (file, input stream, string, DOM tree, ...). + * + * @author mederly + */ +public interface ParserSource { + + /** + * Presents the input data in the form of an InputStream. + * For some special cases might not be implemented, and the data could be accessed in another way. + */ + @NotNull + InputStream getInputStream() throws IOException; + + /** + * Should the stream be closed after parsing? Useful for sources that create/open the stream themselves. + */ + boolean closeStreamAfterParsing(); + + /** + * Is the source expected to throw IOExceptions? + */ + boolean throwsIOException(); +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserStringSource.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserStringSource.java new file mode 100644 index 00000000000..a3a09732c06 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserStringSource.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.apache.commons.io.IOUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @author mederly + */ +public class ParserStringSource implements ParserSource { + + @NotNull private final String data; + + public ParserStringSource(@NotNull String data) { + this.data = data; + } + + @NotNull + public String getData() { + return data; + } + + @NotNull + @Override + public InputStream getInputStream() throws IOException { + return IOUtils.toInputStream(data, "utf-8"); + } + + @Override + public boolean closeStreamAfterParsing() { + return true; + } + + @Override + public boolean throwsIOException() { + return false; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserXNodeSource.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserXNodeSource.java new file mode 100644 index 00000000000..1d15c00fe19 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParserXNodeSource.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @author mederly + */ +public class ParserXNodeSource implements ParserSource { + + @NotNull private final RootXNode xnode; + + public ParserXNodeSource(@NotNull RootXNode xnode) { + this.xnode = xnode; + } + + @NotNull + public RootXNode getXNode() { + return xnode; + } + + @NotNull + @Override + public InputStream getInputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean closeStreamAfterParsing() { + return true; + } + + @Override + public boolean throwsIOException() { + return false; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParsingContext.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParsingContext.java index be5f31f3a4b..eb3a9b580f0 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParsingContext.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ParsingContext.java @@ -16,7 +16,8 @@ package com.evolveum.midpoint.prism; -import com.evolveum.midpoint.prism.parser.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import java.util.ArrayList; @@ -25,7 +26,7 @@ /** * @author mederly */ -public class ParsingContext { +public class ParsingContext implements Cloneable { private XNodeProcessorEvaluationMode evaluationMode = XNodeProcessorEvaluationMode.STRICT; private boolean allowMissingRefTypes; @@ -79,6 +80,19 @@ public void warn(Trace logger, String message) { warn(message); } + public void warnOrThrow(Trace logger, String message) throws SchemaException { + warnOrThrow(logger, message, null); + } + + public void warnOrThrow(Trace logger, String message, Throwable t) throws SchemaException { + if (isCompat()) { + logger.warn("{}", message, t); + warn(message); + } else { + throw new SchemaException(message, t); + } + } + public void warn(String message) { warnings.add(message); } @@ -90,4 +104,27 @@ public List getWarnings() { public boolean hasWarnings() { return !warnings.isEmpty(); } + + public ParsingContext clone() { + ParsingContext clone; + try { + clone = (ParsingContext) super.clone(); + } catch (CloneNotSupportedException e) { + throw new IllegalStateException(e); + } + clone.evaluationMode = evaluationMode; + clone.allowMissingRefTypes = allowMissingRefTypes; + clone.warnings.addAll(warnings); + return clone; + } + + public ParsingContext strict() { + this.setEvaluationMode(XNodeProcessorEvaluationMode.STRICT); + return this; + } + + public ParsingContext compat() { + this.setEvaluationMode(XNodeProcessorEvaluationMode.COMPAT); + return this; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismConstants.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismConstants.java index f13ddec4a48..1eeb024899d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismConstants.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismConstants.java @@ -54,7 +54,9 @@ public class PrismConstants { public static final QName A_PROPERTY_CONTAINER = new QName(NS_ANNOTATION, "container"); public static final QName A_OBJECT = new QName(NS_ANNOTATION, "object"); - + public static final QName A_DEFAULT_NAMESPACE = new QName(NS_ANNOTATION, "defaultNamespace"); + public static final QName A_IGNORED_NAMESPACE = new QName(NS_ANNOTATION, "ignoredNamespace"); + public static final QName A_TYPE = new QName(NS_ANNOTATION, "type"); public static final QName A_DISPLAY_NAME = new QName(NS_ANNOTATION, "displayName"); public static final QName A_DISPLAY_ORDER = new QName(NS_ANNOTATION, "displayOrder"); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainer.java index 3ab0566ab94..7119dc8264c 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainer.java @@ -79,6 +79,13 @@ public PrismContainer(QName name, Class compileTimeClass) { public PrismContainer(QName name, Class compileTimeClass, PrismContext prismContext) { this(name, compileTimeClass); this.prismContext = prismContext; + if (prismContext != null) { + try { + prismContext.adopt(this); + } catch (SchemaException e) { + throw new SystemException("Schema exception when adopting freshly created PrismContainer: " + this); + } + } } @@ -105,11 +112,6 @@ public boolean canRepresent(Class compileTimeClass) { return (compileTimeClass.isAssignableFrom(getCompileTimeClass())); } - @Override - public List> getValues() { - return (List>) super.getValues(); - } - @Override public Collection getRealValues() { if (getValues() == null) { @@ -170,6 +172,7 @@ public PrismContainerValue getValue() { } public void setValue(PrismContainerValue value) throws SchemaException { + checkMutability(); if (getDefinition() != null) { if (getDefinition().isSingleValue()) { clear(); @@ -185,6 +188,7 @@ public void setValue(PrismContainerValue value) throws SchemaException { @Override public boolean add(PrismContainerValue newValue, boolean checkUniqueness) throws SchemaException { + checkMutability(); // when a context-less item is added to a contextful container, it is automatically adopted if (newValue.getPrismContext() == null && this.prismContext != null) { prismContext.adopt(newValue); @@ -232,6 +236,7 @@ public PrismContainerValue getValue(Long id) { } public void setPropertyRealValue(QName propertyName, Object realValue) throws SchemaException { + checkMutability(); PrismProperty property = findOrCreateProperty(propertyName); property.setRealValue(realValue); } @@ -252,11 +257,13 @@ public T getPropertyRealValue(ItemPath propertyPath, Class type) { * Convenience method. Works only on single-valued containers. */ public void add(Item item) throws SchemaException { + checkMutability(); getValue().add(item); } public PrismContainerValue createNewValue() { - PrismContainerValue pValue = new PrismContainerValue(prismContext); + checkMutability(); + PrismContainerValue pValue = new PrismContainerValue<>(prismContext); try { // No need to check uniqueness, we know that this value is new and therefore // it will change anyway and therefore the check is pointless. @@ -281,6 +288,7 @@ public void mergeValues(Collection> otherValues) throws S } public void mergeValue(PrismContainerValue otherValue) throws SchemaException { + checkMutability(); Iterator> iterator = getValues().iterator(); while (iterator.hasNext()) { PrismContainerValue thisValue = iterator.next(); @@ -304,10 +312,11 @@ public void mergeValue(PrismContainerValue otherValue) throws SchemaException * Remove all empty values */ public void trim() { - Iterator> iterator = getValues().iterator(); + Iterator> iterator = getValues().iterator(); while (iterator.hasNext()) { PrismContainerValue pval = iterator.next(); if (pval.isEmpty()) { + checkMutability(); iterator.remove(); } } @@ -331,18 +340,30 @@ public PrismContainerDefinition getDefinition() { * @param definition the definition to set */ public void setDefinition(PrismContainerDefinition definition) { - this.definition = definition; + checkMutability(); + if (definition != null) { + for (PrismContainerValue value : getValues()) { + // TODO reconsider this - sometimes we want to change CTDs, sometimes not + boolean safeToOverwrite = + value.getComplexTypeDefinition() == null + || this.definition == null // TODO highly dangerous (the definition might be simply unknown) + || this.definition.getComplexTypeDefinition() == null + || this.definition.getComplexTypeDefinition().getTypeName().equals(value.getComplexTypeDefinition().getTypeName()); + if (safeToOverwrite) { + value.replaceComplexTypeDefinition(definition.getComplexTypeDefinition()); + } + } + } + this.definition = definition; } @Override public void applyDefinition(PrismContainerDefinition definition) throws SchemaException { + checkMutability(); if (definition == null) { return; } - if (!(definition instanceof PrismContainerDefinition)) { - throw new IllegalArgumentException("Cannot apply "+definition+" to container " + this); - } - this.compileTimeClass = ((PrismContainerDefinition)definition).getCompileTimeClass(); + this.compileTimeClass = definition.getCompileTimeClass(); super.applyDefinition(definition); } @@ -644,8 +665,8 @@ public boolean isEmpty() { @Override protected void checkDefinition(PrismContainerDefinition def) { - if (!(def instanceof PrismContainerDefinition)) { - throw new IllegalArgumentException("Definition "+def+" cannot be applied to container "+this); + if (def == null) { + throw new IllegalArgumentException("Null definition cannot be applied to container "+this); } } @@ -840,7 +861,7 @@ public String debugDump(int indent) { sb.append(")"); } } - Iterator> i = getValues().iterator(); + Iterator> i = getValues().iterator(); if (i.hasNext()) { sb.append("\n"); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java index e056d0b3985..06cffa870b5 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java @@ -17,601 +17,45 @@ package com.evolveum.midpoint.prism; import com.evolveum.midpoint.prism.delta.ContainerDelta; -import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.path.ItemPathSegment; -import com.evolveum.midpoint.prism.path.NameItemPathSegment; -import com.evolveum.midpoint.prism.path.ObjectReferencePathSegment; -import com.evolveum.midpoint.prism.path.ParentPathSegment; -import com.evolveum.midpoint.prism.schema.PrismSchema; -import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; - -import org.apache.commons.lang.StringUtils; - -import java.util.*; +import java.util.List; /** - * Definition of a property container. - *

- * Property container groups properties into logical blocks. The reason for - * grouping may be as simple as better understandability of data structure. But - * the group usually means different meaning, source or structure of the data. - * For example, the property container is frequently used to hold properties - * that are dynamic, not fixed by a static schema. Such grouping also naturally - * translates to XML and helps to "quarantine" such properties to avoid Unique - * Particle Attribute problems. - *

- * Property Container contains a set of (potentially multi-valued) properties. - * The order of properties is not significant, regardless of the fact that it - * may be fixed in the XML representation. In the XML representation, each - * element inside Property Container must be either Property or a Property - * Container. - *

- * This class represents schema definition for property container. See - * {@link Definition} for more details. - * - * @author Radovan Semancik + * @author mederly */ -public class PrismContainerDefinition extends ItemDefinition> { - - private static final long serialVersionUID = -5068923696147960699L; - - protected ComplexTypeDefinition complexTypeDefinition; - protected Class compileTimeClass; - - /** - * The constructors should be used only occasionally (if used at all). - * Use the factory methods in the ResourceObjectDefintion instead. - */ - public PrismContainerDefinition(QName name, ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext) { - this(name, complexTypeDefinition, prismContext, null); - } - - public PrismContainerDefinition(QName name, ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext, - Class compileTimeClass) { - super(name, determineTypeName(complexTypeDefinition), prismContext); - this.complexTypeDefinition = complexTypeDefinition; - if (complexTypeDefinition == null) { - isRuntimeSchema = true; - super.setDynamic(true); - } else { - isRuntimeSchema = complexTypeDefinition.isXsdAnyMarker(); - super.setDynamic(isRuntimeSchema); - } - this.compileTimeClass = compileTimeClass; - } - - private static QName determineTypeName(ComplexTypeDefinition complexTypeDefinition) { - if (complexTypeDefinition == null) { - // Property container without type: xsd:any - // FIXME: this is kind of hack, but it works now - return DOMUtil.XSD_ANY; - } - return complexTypeDefinition.getTypeName(); - } - - public Class getCompileTimeClass() { - if (compileTimeClass != null) { - return compileTimeClass; - } - if (complexTypeDefinition == null) { - return null; - } - return (Class) complexTypeDefinition.getCompileTimeClass(); - } - - public void setCompileTimeClass(Class compileTimeClass) { - this.compileTimeClass = compileTimeClass; - } - - protected String getSchemaNamespace() { - return getName().getNamespaceURI(); - } - - public ComplexTypeDefinition getComplexTypeDefinition() { - return complexTypeDefinition; - } - - public void setComplexTypeDefinition(ComplexTypeDefinition complexTypeDefinition) { - this.complexTypeDefinition = complexTypeDefinition; - } - - @Override - public boolean isAbstract() { - if (super.isAbstract()) { - return true; - } - if (complexTypeDefinition != null && complexTypeDefinition.isAbstract()) { - return true; - } - return false; - } - - /** - * Returns true if the definition does not define specific items but it is just - * a "wildcard" for any kind of item (usually represented as xsd:any type). - */ - public boolean isWildcard() { - if (getTypeName().equals(DOMUtil.XSD_ANY)) { - return true; - } -// if (complexTypeDefinition != null && complexTypeDefinition.isXsdAnyMarker()) { -// return true; -// } - return false; - } - - @Override - public void revive(PrismContext prismContext) { - if (this.prismContext != null) { - return; - } - this.prismContext = prismContext; - if (complexTypeDefinition != null) { - complexTypeDefinition.revive(prismContext); - } - } - - /* - * TODO clean this up: There are three definition-finding algorithms: - * - findItemDefinition (QName ...) - * - findItemDefinition (ItemPath ...) - * - findPropertyDefinition (ItemPath ...) - * - * This has to be replaced by a single algorithm. - */ - public D findItemDefinition(QName name, Class clazz) { - return findItemDefinition(name, clazz, false); - } - - public D findItemDefinition(QName name, Class clazz, boolean caseInsensitive) { - if (clazz == null) { - throw new IllegalArgumentException("type not specified while searching for " + name + " in " + this); - } - if (name == null) { - throw new IllegalArgumentException("name not specified while searching in " + this); - } - - D itemDefinition; - if (complexTypeDefinition != null) { - itemDefinition = complexTypeDefinition.findItemDefinition(name, clazz, caseInsensitive); - } else { - // xsd:any and similar dynamic definitions - itemDefinition = null; - } - - if (itemDefinition == null && isRuntimeSchema()) { - itemDefinition = findRuntimeItemDefinition(name, null, clazz); // TODO what about case insensitive? - } - return itemDefinition; - } - - private D findRuntimeItemDefinition(QName firstName, ItemPath rest, Class clazz) { - if (prismContext == null) { - return null; // should not occur - } - ItemDefinition definition = prismContext.getSchemaRegistry().findItemDefinitionByElementName(firstName); - if (definition == null) { - return null; - } - if (rest != null && !rest.isEmpty()) { - return (D) definition.findItemDefinition(rest, clazz); - } - // this is the last step of search - if (clazz.isAssignableFrom(definition.getClass())) { - return (D) definition; - } else { - return null; - } - } - - public ID findItemDefinition(ItemPath path, Class clazz) { - for (;;) { - if (path.isEmpty()) { - if (clazz.isAssignableFrom(PrismContainerDefinition.class)) { - return (ID) this; - } else { - return null; - } - } - ItemPathSegment first = path.first(); - if (first instanceof NameItemPathSegment) { - QName firstName = ((NameItemPathSegment)first).getName(); - return findNamedItemDefinition(firstName, path.rest(), clazz); - } else if (first instanceof IdItemPathSegment) { - path = path.rest(); - } else if (first instanceof ParentPathSegment) { - ItemPath rest = path.rest(); - ComplexTypeDefinition parent = getSchemaRegistry().determineParentDefinition(getComplexTypeDefinition(), rest); - if (rest.isEmpty()) { - // requires that the parent is defined as an item (container, object) - return (ID) getSchemaRegistry().findItemDefinitionByType(parent.getTypeName()); - } else { - return parent.findItemDefinition(rest, clazz); - } - } else if (first instanceof ObjectReferencePathSegment) { - throw new IllegalStateException("Couldn't use '@' path segment in this context. PCD=" + getTypeName() + ", path=" + path); - } else { - throw new IllegalStateException("Unexpected path segment: " + first + " in " + path); - } - } - } - - public ID findNamedItemDefinition(QName firstName, ItemPath rest, Class clazz) { - - // we need to be compatible with older versions..soo if the path does - // not contains qnames with namespaces defined (but the prefix was - // specified) match definition according to the local name - if (StringUtils.isEmpty(firstName.getNamespaceURI())) { - for (ItemDefinition def : getDefinitions()){ - if (QNameUtil.match(firstName, def.getName())){ - return (ID) def.findItemDefinition(rest, clazz); - } - } - } - - for (ItemDefinition def : getDefinitions()) { - if (firstName.equals(def.getName())) { - return (ID) def.findItemDefinition(rest, clazz); - } - } - - if (isRuntimeSchema()) { - return findRuntimeItemDefinition(firstName, rest, clazz); - } - - return null; - } - - public ID findItemDefinition(QName name) { - return (ID)findItemDefinition(name, ItemDefinition.class); - } - - public ID findItemDefinition(ItemPath path) { - return (ID)findItemDefinition(path, ItemDefinition.class); - } - - /** - * Finds a PropertyDefinition by looking at the property name. - *

- * Returns null if nothing is found. - * - * @param name property definition name - * @return found property definition or null - */ - public PrismPropertyDefinition findPropertyDefinition(QName name) { - return findItemDefinition(name, PrismPropertyDefinition.class); - } - - public PrismPropertyDefinition findPropertyDefinition(ItemPath path) { - while (!path.isEmpty() && !(path.first() instanceof NameItemPathSegment)) { - path = path.rest(); - } - if (path.isEmpty()) { - throw new IllegalArgumentException("Property path is empty while searching for property definition in " + this); - } - QName firstName = ((NameItemPathSegment)path.first()).getName(); - if (path.size() == 1) { - return findPropertyDefinition(firstName); - } - PrismContainerDefinition pcd = findContainerDefinition(firstName); - if (pcd == null) { - throw new IllegalArgumentException("There is no " + firstName + " subcontainer in " + this); - } - return pcd.findPropertyDefinition(path.rest()); - } - - public PrismReferenceDefinition findReferenceDefinition(QName name) { - return findItemDefinition(name, PrismReferenceDefinition.class); - } - - public PrismReferenceDefinition findReferenceDefinition(ItemPath path) { - return findItemDefinition(path, PrismReferenceDefinition.class); - } - - /** - * Finds an inner PropertyContainerDefinition by looking at the property container name. - *

- * Returns null if nothing is found. - * - * @param name property container definition name - * @return found property container definition or null - */ - public PrismContainerDefinition findContainerDefinition(QName name) { - return findItemDefinition(name, PrismContainerDefinition.class); - } - - public PrismContainerDefinition findContainerDefinition(String name) { - return findContainerDefinition(new QName(getNamespace(), name)); - } - - /** - * Finds an inner PropertyContainerDefinition by following the property container path. - *

- * Returns null if nothing is found. - * - * @param path property container path - * @return found property container definition or null - */ - public PrismContainerDefinition findContainerDefinition(ItemPath path) { - return findItemDefinition(path, PrismContainerDefinition.class); - } - - /** - * Returns set of property definitions. - *

- * WARNING: This may return definitions from the associated complex type. - * Therefore changing the returned set may influence also the complex type definition. - *

- * The set contains all property definitions of all types that were parsed. - * Order of definitions is insignificant. - * - * @return set of definitions - */ - public List getDefinitions() { - if (complexTypeDefinition == null) { - // e.g. for xsd:any containers - // FIXME - return new ArrayList(); - } - return complexTypeDefinition.getDefinitions(); - } - - /** - * Returns set of property definitions. - *

- * The set contains all property definitions of all types that were parsed. - * Order of definitions is insignificant. - *

- * The returned set is immutable! All changes may be lost. - * - * @return set of definitions - */ - public List getPropertyDefinitions() { - List props = new ArrayList(); - for (ItemDefinition def : complexTypeDefinition.getDefinitions()) { - if (def instanceof PrismPropertyDefinition) { - props.add((PrismPropertyDefinition) def); - } - } - return props; - } - - /** - * Create property container instance with a default name. - *

- * This is a preferred way how to create property container. - */ - @Override - public PrismContainer instantiate() throws SchemaException { - return instantiate(getName()); - } - - /** - * Create property container instance with a specified name and element. - *

- * This is a preferred way how to create property container. - */ - @Override - public PrismContainer instantiate(QName elementName) throws SchemaException { - if (isAbstract()) { - throw new SchemaException("Cannot instantiate abstract definition "+this); - } - elementName = addNamespaceIfApplicable(elementName); - return new PrismContainer(elementName, this, prismContext); - } - - @Override - public ContainerDelta createEmptyDelta(ItemPath path) { - return new ContainerDelta(path, this, prismContext); - } - - /** - * Shallow clone - */ - @Override - public PrismContainerDefinition clone() { - PrismContainerDefinition clone = new PrismContainerDefinition(name, complexTypeDefinition, prismContext, compileTimeClass); - copyDefinitionData(clone); - return clone; - } +public interface PrismContainerDefinition extends ItemDefinition>, LocalDefinitionStore { - protected void copyDefinitionData(PrismContainerDefinition clone) { - super.copyDefinitionData(clone); - clone.complexTypeDefinition = this.complexTypeDefinition; - clone.compileTimeClass = this.compileTimeClass; - } - - @Override - ItemDefinition deepClone(Map ctdMap) { - PrismContainerDefinition clone = clone(); - ComplexTypeDefinition ctd = getComplexTypeDefinition(); - if (ctd != null) { - ctd = ctd.deepClone(ctdMap); - clone.setComplexTypeDefinition(ctd); - } - return clone; - } + Class getCompileTimeClass(); - public PrismContainerDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) { - PrismContainerDefinition clone = clone(); - ComplexTypeDefinition originalComplexTypeDefinition = getComplexTypeDefinition(); - ComplexTypeDefinition cloneComplexTypeDefinition = originalComplexTypeDefinition.clone(); - clone.setComplexTypeDefinition(cloneComplexTypeDefinition); - cloneComplexTypeDefinition.replaceDefinition(itemName, newDefinition); - return clone; - } + ComplexTypeDefinition getComplexTypeDefinition(); - /** - * Creates new instance of property definition and adds it to the container. - *

- * This is the preferred method of creating a new definition. - * - * @param name name of the property (element name) - * @param typeName XSD type of the property - * @return created property definition - */ - public PrismPropertyDefinition createPropertyDefinition(QName name, QName typeName) { - PrismPropertyDefinition propDef = new PrismPropertyDefinition(name, typeName, prismContext); - addDefinition(propDef); - return propDef; - } - - private void addDefinition(ItemDefinition itemDef) { - ((Collection)getDefinitions()).add(itemDef); - } + boolean isWildcard(); - /** - * Creates new instance of property definition and adds it to the container. - *

- * This is the preferred method of creating a new definition. - * - * @param name name of the property (element name) - * @param typeName XSD type of the property - * @param minOccurs minimal number of occurrences - * @param maxOccurs maximal number of occurrences (-1 means unbounded) - * @return created property definition - */ - public PrismPropertyDefinition createPropertyDefinition(QName name, QName typeName, - int minOccurs, int maxOccurs) { - PrismPropertyDefinition propDef = new PrismPropertyDefinition(name, typeName, prismContext); - propDef.setMinOccurs(minOccurs); - propDef.setMaxOccurs(maxOccurs); - addDefinition(propDef); - return propDef; - } + @Override + void revive(PrismContext prismContext); - // Creates reference to other schema - // TODO: maybe check if the name is in different namespace - // TODO: maybe create entirely new concept of property reference? - public PrismPropertyDefinition createPropertyDefinition(QName name) { - PrismPropertyDefinition propDef = new PrismPropertyDefinition(name, null, prismContext); - addDefinition(propDef); - return propDef; - } + String getDefaultNamespace(); - /** - * Creates new instance of property definition and adds it to the container. - *

- * This is the preferred method of creating a new definition. - * - * @param localName name of the property (element name) relative to the schema namespace - * @param typeName XSD type of the property - * @return created property definition - */ - public PrismPropertyDefinition createPropertyDefinition(String localName, QName typeName) { - QName name = new QName(getSchemaNamespace(), localName); - return createPropertyDefinition(name, typeName); - } + List getIgnoredNamespaces(); - /** - * Creates new instance of property definition and adds it to the container. - *

- * This is the preferred method of creating a new definition. - * - * @param localName name of the property (element name) relative to the schema namespace - * @param localTypeName XSD type of the property - * @return created property definition - */ - public PrismPropertyDefinition createPropertyDefinition(String localName, String localTypeName) { - QName name = new QName(getSchemaNamespace(), localName); - QName typeName = new QName(getSchemaNamespace(), localTypeName); - return createPropertyDefinition(name, typeName); - } + List getDefinitions(); - /** - * Creates new instance of property definition and adds it to the container. - *

- * This is the preferred method of creating a new definition. - * - * @param localName name of the property (element name) relative to the schema namespace - * @param localTypeName XSD type of the property - * @param minOccurs minimal number of occurrences - * @param maxOccurs maximal number of occurrences (-1 means unbounded) - * @return created property definition - */ - public PrismPropertyDefinition createPropertyDefinition(String localName, String localTypeName, - int minOccurs, int maxOccurs) { - QName name = new QName(getSchemaNamespace(), localName); - QName typeName = new QName(getSchemaNamespace(), localTypeName); - PrismPropertyDefinition propertyDefinition = createPropertyDefinition(name, typeName); - propertyDefinition.setMinOccurs(minOccurs); - propertyDefinition.setMaxOccurs(maxOccurs); - return propertyDefinition; - } - - public PrismContainerDefinition createContainerDefinition(QName name, QName typeName) { - return createContainerDefinition(name, typeName, 1, 1); - } - - public PrismContainerDefinition createContainerDefinition(QName name, QName typeName, - int minOccurs, int maxOccurs) { - PrismSchema typeSchema = prismContext.getSchemaRegistry().findSchemaByNamespace(typeName.getNamespaceURI()); - if (typeSchema == null) { - throw new IllegalArgumentException("Schema for namespace "+typeName.getNamespaceURI()+" is not known in the prism context"); - } - ComplexTypeDefinition typeDefinition = typeSchema.findComplexTypeDefinition(typeName); - if (typeDefinition == null) { - throw new IllegalArgumentException("Type "+typeName+" is not known in the schema"); - } - return createContainerDefinition(name, typeDefinition, minOccurs, maxOccurs); - } - - public PrismContainerDefinition createContainerDefinition(QName name, ComplexTypeDefinition complexTypeDefinition, - int minOccurs, int maxOccurs) { - PrismContainerDefinition def = new PrismContainerDefinition(name, complexTypeDefinition, prismContext); - def.setMinOccurs(minOccurs); - def.setMaxOccurs(maxOccurs); - addDefinition(def); - return def; - } - - public PrismContainerValue createValue() { - return new PrismContainerValue(prismContext); - } + List getPropertyDefinitions(); - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - DebugUtil.indentDebugDump(sb, indent); - sb.append(toString()); - if (isRuntimeSchema()) { - sb.append(" dynamic"); - } - for (Definition def : getDefinitions()) { - sb.append("\n"); - if (def == this) { - // Not perfect loop protection, but works for now - DebugUtil.indentDebugDump(sb, indent); - sb.append(""); - } else { - sb.append(def.debugDump(indent + 1)); - } - } - return sb.toString(); - } + @Override + ContainerDelta createEmptyDelta(ItemPath path); + @NotNull + @Override + PrismContainerDefinition clone(); - public boolean isEmpty() { - return complexTypeDefinition.isEmpty(); - } - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "PCD"; - } + PrismContainerDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition); - @Override - public String getDocClassName() { - return "container"; - } + PrismContainerValue createValue(); + boolean isEmpty(); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinitionImpl.java new file mode 100644 index 00000000000..60b3b6a8923 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinitionImpl.java @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.delta.ContainerDelta; +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.path.IdItemPathSegment; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.path.ItemPathSegment; +import com.evolveum.midpoint.prism.path.NameItemPathSegment; +import com.evolveum.midpoint.prism.path.ObjectReferencePathSegment; +import com.evolveum.midpoint.prism.path.ParentPathSegment; +import com.evolveum.midpoint.prism.schema.PrismSchema; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.DebugDumpable; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * Definition of a property container. + *

+ * Property container groups properties into logical blocks. The reason for + * grouping may be as simple as better understandability of data structure. But + * the group usually means different meaning, source or structure of the data. + * For example, the property container is frequently used to hold properties + * that are dynamic, not fixed by a static schema. Such grouping also naturally + * translates to XML and helps to "quarantine" such properties to avoid Unique + * Particle Attribute problems. + *

+ * Property Container contains a set of (potentially multi-valued) properties. + * The order of properties is not significant, regardless of the fact that it + * may be fixed in the XML representation. In the XML representation, each + * element inside Property Container must be either Property or a Property + * Container. + *

+ * This class represents schema definition for property container. See + * {@link Definition} for more details. + * + * @author Radovan Semancik + */ +public class PrismContainerDefinitionImpl extends ItemDefinitionImpl> + implements PrismContainerDefinition { + + private static final long serialVersionUID = -5068923696147960699L; + + // There are situations where CTD is (maybe) null but class is defined. + // TODO clean up this. + protected ComplexTypeDefinition complexTypeDefinition; + protected Class compileTimeClass; + + /** + * The constructors should be used only occasionally (if used at all). + * Use the factory methods in the ResourceObjectDefintion instead. + */ + public PrismContainerDefinitionImpl(@NotNull QName name, ComplexTypeDefinition complexTypeDefinition, @NotNull PrismContext prismContext) { + this(name, complexTypeDefinition, prismContext, null); + } + + public PrismContainerDefinitionImpl(@NotNull QName name, ComplexTypeDefinition complexTypeDefinition, @NotNull PrismContext prismContext, + Class compileTimeClass) { + super(name, determineTypeName(complexTypeDefinition), prismContext); + this.complexTypeDefinition = complexTypeDefinition; + if (complexTypeDefinition == null) { + isRuntimeSchema = true; + super.setDynamic(true); + } else { + isRuntimeSchema = complexTypeDefinition.isXsdAnyMarker(); + super.setDynamic(isRuntimeSchema); + } + this.compileTimeClass = compileTimeClass; + } + + private static QName determineTypeName(ComplexTypeDefinition complexTypeDefinition) { + if (complexTypeDefinition == null) { + // Property container without type: xsd:any + // FIXME: this is kind of hack, but it works now + return DOMUtil.XSD_ANY; + } + return complexTypeDefinition.getTypeName(); + } + + @Override + public Class getCompileTimeClass() { + if (compileTimeClass != null) { + return compileTimeClass; + } + if (complexTypeDefinition == null) { + return null; + } + return (Class) complexTypeDefinition.getCompileTimeClass(); + } + + public void setCompileTimeClass(Class compileTimeClass) { + this.compileTimeClass = compileTimeClass; + } + + protected String getSchemaNamespace() { + return getName().getNamespaceURI(); + } + + @Override + public ComplexTypeDefinition getComplexTypeDefinition() { + return complexTypeDefinition; + } + + public void setComplexTypeDefinition(ComplexTypeDefinition complexTypeDefinition) { + this.complexTypeDefinition = complexTypeDefinition; + } + + @Override + public boolean isAbstract() { + if (super.isAbstract()) { + return true; + } + return complexTypeDefinition != null && complexTypeDefinition.isAbstract(); + } + + /** + * Returns true if the definition does not define specific items but it is just + * a "wildcard" for any kind of item (usually represented as xsd:any type). + */ + @Override + public boolean isWildcard() { + if (getTypeName().equals(DOMUtil.XSD_ANY)) { + return true; + } +// if (complexTypeDefinition != null && complexTypeDefinition.isXsdAnyMarker()) { +// return true; +// } + return false; + } + + @Override + public void revive(PrismContext prismContext) { + if (this.prismContext != null) { + return; + } + this.prismContext = prismContext; + if (complexTypeDefinition != null) { + complexTypeDefinition.revive(prismContext); + } + } + + @Override + public D findItemDefinition(@NotNull QName name, @NotNull Class clazz, boolean caseInsensitive) { + if (complexTypeDefinition != null) { + return complexTypeDefinition.findItemDefinition(name, clazz, caseInsensitive); + } else { + return null; // xsd:any and similar dynamic definitions + } + } + + @Override + public String getDefaultNamespace() { + return complexTypeDefinition != null ? complexTypeDefinition.getDefaultNamespace() : null; + } + + @Override + public List getIgnoredNamespaces() { + return complexTypeDefinition != null ? complexTypeDefinition.getIgnoredNamespaces() : null; + } + + public ID findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + for (;;) { + if (path.isEmpty()) { + if (clazz.isAssignableFrom(PrismContainerDefinition.class)) { + return (ID) this; + } else { + return null; + } + } + ItemPathSegment first = path.first(); + if (first instanceof NameItemPathSegment) { + QName firstName = ((NameItemPathSegment)first).getName(); + return findNamedItemDefinition(firstName, path.rest(), clazz); + } else if (first instanceof IdItemPathSegment) { + path = path.rest(); + } else if (first instanceof ParentPathSegment) { + ItemPath rest = path.rest(); + ComplexTypeDefinition parent = getSchemaRegistry().determineParentDefinition(getComplexTypeDefinition(), rest); + if (rest.isEmpty()) { + // requires that the parent is defined as an item (container, object) + return (ID) getSchemaRegistry().findItemDefinitionByType(parent.getTypeName()); + } else { + return parent.findItemDefinition(rest, clazz); + } + } else if (first instanceof ObjectReferencePathSegment) { + throw new IllegalStateException("Couldn't use '@' path segment in this context. PCD=" + getTypeName() + ", path=" + path); + } else { + throw new IllegalStateException("Unexpected path segment: " + first + " in " + path); + } + } + } + + @Override + public ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, @NotNull Class clazz) { + + // we need to be compatible with older versions..soo if the path does + // not contains qnames with namespaces defined (but the prefix was + // specified) match definition according to the local name + if (StringUtils.isEmpty(firstName.getNamespaceURI())) { + for (ItemDefinition def : getDefinitions()){ + if (QNameUtil.match(firstName, def.getName())){ + return (ID) def.findItemDefinition(rest, clazz); + } + } + } + + for (ItemDefinition def : getDefinitions()) { + if (firstName.equals(def.getName())) { + return (ID) def.findItemDefinition(rest, clazz); + } + } + +// if (isRuntimeSchema()) { +// return findRuntimeItemDefinition(firstName, rest, clazz); +// } + + return null; + } + +// @Override +// public PrismPropertyDefinition findPropertyDefinition(ItemPath path) { +// while (!path.isEmpty() && !(path.first() instanceof NameItemPathSegment)) { +// path = path.rest(); +// } +// if (path.isEmpty()) { +// throw new IllegalArgumentException("Property path is empty while searching for property definition in " + this); +// } +// QName firstName = ((NameItemPathSegment)path.first()).getName(); +// if (path.size() == 1) { +// return findPropertyDefinition(firstName); +// } +// PrismContainerDefinition pcd = findContainerDefinition(firstName); +// if (pcd == null) { +// throw new IllegalArgumentException("There is no " + firstName + " subcontainer in " + this); +// } +// return pcd.findPropertyDefinition(path.rest()); +// } + + /** + * Returns set of property definitions. + *

+ * WARNING: This may return definitions from the associated complex type. + * Therefore changing the returned set may influence also the complex type definition. + *

+ * The set contains all property definitions of all types that were parsed. + * Order of definitions is insignificant. + * + * @return set of definitions + */ + @Override + public List getDefinitions() { + if (complexTypeDefinition == null) { + // e.g. for xsd:any containers + // FIXME + return new ArrayList<>(); + } + return complexTypeDefinition.getDefinitions(); + } + + /** + * Returns set of property definitions. + *

+ * The set contains all property definitions of all types that were parsed. + * Order of definitions is insignificant. + *

+ * The returned set is immutable! All changes may be lost. + * + * @return set of definitions + */ + @Override + public List getPropertyDefinitions() { + List props = new ArrayList(); + for (ItemDefinition def : complexTypeDefinition.getDefinitions()) { + if (def instanceof PrismPropertyDefinition) { + props.add((PrismPropertyDefinition) def); + } + } + return props; + } + + @Override + public PrismContainer instantiate() throws SchemaException { + return instantiate(getName()); + } + + @Override + public PrismContainer instantiate(QName elementName) throws SchemaException { + if (isAbstract()) { + throw new SchemaException("Cannot instantiate abstract definition "+this); + } + elementName = addNamespaceIfApplicable(elementName); + return new PrismContainer(elementName, this, prismContext); + } + + @Override + public ContainerDelta createEmptyDelta(ItemPath path) { + return new ContainerDelta(path, this, prismContext); + } + + /** + * Shallow clone + */ + @NotNull + @Override + public PrismContainerDefinitionImpl clone() { + PrismContainerDefinitionImpl clone = new PrismContainerDefinitionImpl(name, complexTypeDefinition, prismContext, compileTimeClass); + copyDefinitionData(clone); + return clone; + } + + protected void copyDefinitionData(PrismContainerDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.complexTypeDefinition = this.complexTypeDefinition; + clone.compileTimeClass = this.compileTimeClass; + } + + @Override + public ItemDefinition deepClone(Map ctdMap) { + PrismContainerDefinitionImpl clone = clone(); + ComplexTypeDefinition ctd = getComplexTypeDefinition(); + if (ctd != null) { + ctd = ctd.deepClone(ctdMap); + clone.setComplexTypeDefinition(ctd); + } + return clone; + } + + @Override + public PrismContainerDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) { + PrismContainerDefinitionImpl clone = clone(); + ComplexTypeDefinition originalComplexTypeDefinition = getComplexTypeDefinition(); + ComplexTypeDefinition cloneComplexTypeDefinition = originalComplexTypeDefinition.clone(); + clone.setComplexTypeDefinition(cloneComplexTypeDefinition); + ((ComplexTypeDefinitionImpl) cloneComplexTypeDefinition).replaceDefinition(itemName, newDefinition); + return clone; + } + + /** + * Creates new instance of property definition and adds it to the container. + *

+ * This is the preferred method of creating a new definition. + * + * @param name name of the property (element name) + * @param typeName XSD type of the property + * @return created property definition + */ + public PrismPropertyDefinitionImpl createPropertyDefinition(QName name, QName typeName) { + PrismPropertyDefinitionImpl propDef = new PrismPropertyDefinitionImpl(name, typeName, prismContext); + addDefinition(propDef); + return propDef; + } + + private void addDefinition(ItemDefinition itemDef) { + if (complexTypeDefinition == null) { + throw new UnsupportedOperationException("Cannot add an item definition because there's no complex type definition"); + } else if (!(complexTypeDefinition instanceof ComplexTypeDefinitionImpl)) { + throw new UnsupportedOperationException("Cannot add an item definition into complex type definition of type " + complexTypeDefinition.getClass().getName()); + } else { + ((ComplexTypeDefinitionImpl) complexTypeDefinition).add(itemDef); + } + } + + /** + * Creates new instance of property definition and adds it to the container. + *

+ * This is the preferred method of creating a new definition. + * + * @param name name of the property (element name) + * @param typeName XSD type of the property + * @param minOccurs minimal number of occurrences + * @param maxOccurs maximal number of occurrences (-1 means unbounded) + * @return created property definition + */ + public PrismPropertyDefinition createPropertyDefinition(QName name, QName typeName, + int minOccurs, int maxOccurs) { + PrismPropertyDefinitionImpl propDef = new PrismPropertyDefinitionImpl(name, typeName, prismContext); + propDef.setMinOccurs(minOccurs); + propDef.setMaxOccurs(maxOccurs); + addDefinition(propDef); + return propDef; + } + + // Creates reference to other schema + // TODO: maybe check if the name is in different namespace + // TODO: maybe create entirely new concept of property reference? + public PrismPropertyDefinition createPropertyDefinition(QName name) { + PrismPropertyDefinition propDef = new PrismPropertyDefinitionImpl(name, null, prismContext); + addDefinition(propDef); + return propDef; + } + + /** + * Creates new instance of property definition and adds it to the container. + *

+ * This is the preferred method of creating a new definition. + * + * @param localName name of the property (element name) relative to the schema namespace + * @param typeName XSD type of the property + * @return created property definition + */ + public PrismPropertyDefinition createPropertyDefinition(String localName, QName typeName) { + QName name = new QName(getSchemaNamespace(), localName); + return createPropertyDefinition(name, typeName); + } + + /** + * Creates new instance of property definition and adds it to the container. + *

+ * This is the preferred method of creating a new definition. + * + * @param localName name of the property (element name) relative to the schema namespace + * @param localTypeName XSD type of the property + * @return created property definition + */ + public PrismPropertyDefinition createPropertyDefinition(String localName, String localTypeName) { + QName name = new QName(getSchemaNamespace(), localName); + QName typeName = new QName(getSchemaNamespace(), localTypeName); + return createPropertyDefinition(name, typeName); + } + + /** + * Creates new instance of property definition and adds it to the container. + *

+ * This is the preferred method of creating a new definition. + * + * @param localName name of the property (element name) relative to the schema namespace + * @param localTypeName XSD type of the property + * @param minOccurs minimal number of occurrences + * @param maxOccurs maximal number of occurrences (-1 means unbounded) + * @return created property definition + */ + public PrismPropertyDefinition createPropertyDefinition(String localName, String localTypeName, + int minOccurs, int maxOccurs) { + QName name = new QName(getSchemaNamespace(), localName); + QName typeName = new QName(getSchemaNamespace(), localTypeName); + PrismPropertyDefinitionImpl propertyDefinition = createPropertyDefinition(name, typeName); + propertyDefinition.setMinOccurs(minOccurs); + propertyDefinition.setMaxOccurs(maxOccurs); + return propertyDefinition; + } + + public PrismContainerDefinition createContainerDefinition(QName name, QName typeName) { + return createContainerDefinition(name, typeName, 1, 1); + } + + public PrismContainerDefinition createContainerDefinition(QName name, QName typeName, + int minOccurs, int maxOccurs) { + PrismSchema typeSchema = prismContext.getSchemaRegistry().findSchemaByNamespace(typeName.getNamespaceURI()); + if (typeSchema == null) { + throw new IllegalArgumentException("Schema for namespace "+typeName.getNamespaceURI()+" is not known in the prism context"); + } + ComplexTypeDefinition typeDefinition = typeSchema.findComplexTypeDefinition(typeName); + if (typeDefinition == null) { + throw new IllegalArgumentException("Type "+typeName+" is not known in the schema"); + } + return createContainerDefinition(name, typeDefinition, minOccurs, maxOccurs); + } + + public PrismContainerDefinition createContainerDefinition(QName name, ComplexTypeDefinition complexTypeDefinition, + int minOccurs, int maxOccurs) { + PrismContainerDefinitionImpl def = new PrismContainerDefinitionImpl(name, complexTypeDefinition, prismContext); + def.setMinOccurs(minOccurs); + def.setMaxOccurs(maxOccurs); + addDefinition(def); + return def; + } + + @Override + public PrismContainerValue createValue() { + return new PrismContainerValue<>(prismContext); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append(toString()); + if (isRuntimeSchema()) { + sb.append(" dynamic"); + } + for (Definition def : getDefinitions()) { + sb.append("\n"); + if (def == this) { + // Not perfect loop protection, but works for now + DebugUtil.indentDebugDump(sb, indent); + sb.append(""); + } else { + sb.append(def.debugDump(indent + 1)); + } + } + return sb.toString(); + } + + + @Override + public boolean isEmpty() { + return complexTypeDefinition.isEmpty(); + } + + /** + * Return a human readable name of this class suitable for logs. + */ + @Override + protected String getDebugDumpClassName() { + return "PCD"; + } + + @Override + public String getDocClassName() { + return "container"; + } + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java index b4dd94e90eb..8e9c1fca8c7 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java @@ -16,24 +16,16 @@ package com.evolveum.midpoint.prism; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.parser.JaxbDomHack; -import com.evolveum.midpoint.prism.parser.XNodeProcessor; +import com.evolveum.midpoint.prism.marshaller.JaxbDomHack; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.ItemPathSegment; import com.evolveum.midpoint.prism.path.NameItemPathSegment; -import com.evolveum.midpoint.prism.xnode.MapXNode; -import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.MiscUtil; @@ -46,6 +38,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author semancik @@ -60,61 +54,45 @@ public class PrismContainerValue extends PrismValue imp private List> items = null; private Long id; - // XNode map of all sub-elements in this container value. - private MapXNode rawXNode = null; - // The elements are set during a schema-less parsing, e.g. during a dumb JAXB parsing of the object - // We can't do anything smarter, as we don't have definition nor prism context. We cannot even convert - // this to XNode because no prism context means no parser. - // So we store the raw elements here and process them later (e.g. during applyDefinition). - private List rawElements = null; - private C containerable = null; - /** - * Concrete type of the containerable value. It is the declared container type or any of its subtypes. - * If null, it is considered to be the declared type itself. - * - * (It is advisable to keep it null when the concrete type is the same as declared type - * in order to prevent the serialized form from having unnecessary type QName declaration, - * as currently this information is directly serialized into value's MapXNode representation - * as type attribute.) - * - * Currently this feature is "half-baked" and experimental. If you need it, you have to set it up explicitly - * when creating your container value. - */ - private QName concreteType = null; - - private PrismContainerDefinition concreteTypeDefinition = null; // lazily evaluated + // Definition of this value. Usually it is the same as CTD declared in the parent container. + // However, in order to support polymorphism (as well as parent-less values) we distinguish between PC and PCV type definition. + private ComplexTypeDefinition complexTypeDefinition = null; - transient private PrismContext prismContext; + public PrismContainerValue() { + } - public PrismContainerValue() { - super(); - // Nothing to do + public PrismContainerValue(C containerable) { + this(containerable, null, null); } - public PrismContainerValue(PrismContext prismContext) { - this(); - setPrismContext(prismContext); - } + public PrismContainerValue(PrismContext prismContext) { + this(null, null, prismContext); + } - private void setPrismContext(PrismContext prismContext) { - //Validate.notNull(prismContext, "No prismContext in PrismContainerValue"); // not yet - //if (prismContext == null) { - // LOGGER.warn("No prismContext in PrismContainerValue"); - //} - this.prismContext = prismContext; - } - - private PrismContainerValue(OriginType type, Objectable source, PrismContainerable container, Long id, QName concreteType) { - super(type, source, container); - this.id = id; - this.concreteType = concreteType; + public PrismContainerValue(ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext) { + this(null, complexTypeDefinition, prismContext); + } + + public PrismContainerValue(C containerable, PrismContext prismContext) { + this(containerable, null, prismContext); + } + + public PrismContainerValue(C containerable, ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext) { + super(prismContext); + this.containerable = containerable; + this.complexTypeDefinition = complexTypeDefinition; + + if (complexTypeDefinition == null && prismContext != null) { + getComplexTypeDefinition(); // to determine CTD + } } - public PrismContainerValue(OriginType type, Objectable source, PrismContainerable container, Long id, QName concreteType, PrismContext prismContext) { - this(type, source, container, id, concreteType); - setPrismContext(prismContext); + public PrismContainerValue(OriginType type, Objectable source, PrismContainerable container, Long id, ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext) { + super(prismContext, type, source, container); + this.id = id; + this.complexTypeDefinition = complexTypeDefinition; } @Override @@ -122,13 +100,21 @@ public PrismContext getPrismContext() { if (prismContext != null) { return prismContext; } + if (complexTypeDefinition != null && complexTypeDefinition.getPrismContext() != null) { + return complexTypeDefinition.getPrismContext(); + } if (getParent() != null) { return getParent().getPrismContext(); } return null; } - /** + // Primarily for testing + public PrismContext getPrismContextLocal() { + return prismContext; + } + + /** * Returns a set of items that the property container contains. The items may be properties or inner property containers. *

* The set may be null. In case there are no properties an empty set is @@ -140,11 +126,15 @@ public PrismContext getPrismContext() { */ public List> getItems() { - return items; + if (isImmutable()) { + return Collections.unmodifiableList(items); + } else { + return items; + } } public Item getNextItem(Item referenceItem) { - if (items == null){ + if (items == null) { return null; } Iterator> iterator = items.iterator(); @@ -167,7 +157,8 @@ public Item getPreviousItem(Item referenceItem) { } Item lastItem = null; Iterator> iterator = items.iterator(); - while (iterator.hasNext()) { + //noinspection WhileLoopReplaceableByForEach + while (iterator.hasNext()) { Item item = iterator.next(); if (item == referenceItem) { return lastItem; @@ -205,6 +196,7 @@ public Long getId() { } public void setId(Long id) { + checkMutability(); this.id = id; } @@ -221,10 +213,6 @@ public PrismContainerable getParent() { return (PrismContainerable)parent; } - void setParent(PrismContainerable container) { - super.setParent(container); - } - @SuppressWarnings("unchecked") public PrismContainer getContainer() { Itemable parent = super.getParent(); @@ -238,10 +226,7 @@ public PrismContainer getContainer() { return (PrismContainer)super.getParent(); } - void setParent(PrismContainer container) { - super.setParent(container); - } - + @NotNull public ItemPath getPath() { Itemable parent = getParent(); ItemPath parentPath = ItemPath.EMPTY_PATH; @@ -259,65 +244,67 @@ public ItemPath getPath() { public C getValue() { return asContainerable(); } - - private List createElement() { - return new ArrayList(); - } + @SuppressWarnings("unchecked") public C asContainerable() { - PrismContainerable parent = getParent(); - if (parent == null) { - throw new IllegalStateException("Cannot represent container value without a parent as containerable; value: "+this); + if (containerable != null) { + return containerable; } - - Class clazz = null; - if (concreteType != null) { - clazz = resolveConcreteClass(parent); - } - if (clazz == null) { - clazz = parent.getCompileTimeClass(); - } - if (clazz == null) { - throw new SystemException("Unknown compile time class of container '" + parent.getElementName() + "'."); - } - if (Modifier.isAbstract(clazz.getModifiers())) { - throw new SystemException("Can't create instance of class '" + clazz.getSimpleName() + "', it's abstract."); - } - return asContainerableInternal(clazz); + if (getParent() == null && complexTypeDefinition == null) { + throw new IllegalStateException("Cannot represent container value without a parent and complex type definition as containerable; value: " + this); + } + return asContainerableInternal(resolveClass(null)); } - private Class resolveConcreteClass(PrismContainerable parent) { - Class clazz; - PrismContainerDefinition containerDefinition = parent.getPrismContext().getSchemaRegistry().findContainerDefinitionByType(concreteType); - if (containerDefinition == null) { - throw new IllegalStateException("A definition for an explicit type " + concreteType + " of a container " + parent.getElementName() + " value couldn't be found"); - } - clazz = containerDefinition.getCompileTimeClass(); - if (clazz == null) { - throw new IllegalStateException("A definition for an explicit type " + concreteType + " of a container " + parent.getElementName() + " value has no compile-time class specified"); - } - return clazz; + // returned class must be of type 'requiredClass' (or any of its subtypes) + public C asContainerable(Class requiredClass) { + if (containerable != null) { + return containerable; + } + return asContainerableInternal(resolveClass(requiredClass)); } - public C asContainerable(Class defaultClazz) { - Class clazz = defaultClazz; - if (concreteType != null) { - PrismContainerable parent = getParent(); - if (parent != null) { - clazz = resolveConcreteClass(parent); - } else { - throw new IllegalStateException("Cannot determine compile-time class for concrete type " + concreteType + " because the respective prism container value has no parent"); - } - } - return asContainerableInternal(clazz); - } + private Class resolveClass(@Nullable Class requiredClass) { + if (complexTypeDefinition != null && complexTypeDefinition.getCompileTimeClass() != null) { + Class actualClass = complexTypeDefinition.getCompileTimeClass(); + if (requiredClass != null && !requiredClass.isAssignableFrom(actualClass)) { + throw new IllegalStateException("asContainerable was called to produce " + requiredClass + + ", but the actual class in PCV is " + actualClass); + } else { + return (Class) actualClass; + } + } else { + PrismContainerable parent = getParent(); + if (parent != null) { + Class parentClass = parent.getCompileTimeClass(); + if (parentClass != null) { + if (requiredClass != null && !requiredClass.isAssignableFrom(parentClass)) { + // mismatch; but this can occur (see ShadowAttributesType vs ShadowIdentifiersType in ShadowAssociationType) + // but TODO maybe this is only a workaround and the problem is in the schema itself (?) + return requiredClass; + } else { + return (Class) parentClass; + } + } + } + } + return requiredClass; + } - private C asContainerableInternal(Class clazz) { - if (containerable != null) { - return containerable ; - } + private C asContainerableInternal(Class clazz) { + if (clazz == null) { + String elementName = getParent() != null ? String.valueOf(getParent().getElementName()) : String.valueOf(this); + throw new SystemException("Unknown compile time class of container value of '" + elementName + "'."); + } + if (Modifier.isAbstract(clazz.getModifiers())) { + throw new SystemException("Can't create instance of class '" + clazz.getSimpleName() + "', it's abstract."); + } try { - containerable = clazz.newInstance(); + if (prismContext != null) { + containerable = clazz.getConstructor(PrismContext.class).newInstance(prismContext); + } else { + containerable = clazz.newInstance(); + } containerable.setupContainerValue(this); return containerable; } catch (SystemException ex) { @@ -328,7 +315,7 @@ private C asContainerableInternal(Class clazz) { } public Collection getPropertyNames() { - Collection names = new HashSet(); + Collection names = new HashSet<>(); for (PrismProperty prop: getProperties()) { names.add(prop.getElementName()); } @@ -346,11 +333,12 @@ public boolean add(Item * @throws SchemaException * @throws IllegalArgumentException an attempt to add value that already exists */ - public boolean add(Item item, boolean checkUniquness) throws SchemaException { + public boolean add(Item item, boolean checkUniqueness) throws SchemaException { + checkMutability(); if (item.getElementName() == null) { throw new IllegalArgumentException("Cannot add item without a name to value of container "+getParent()); } - if (checkUniquness && findItem(item.getElementName(), Item.class) != null) { + if (checkUniqueness && findItem(item.getElementName(), Item.class) != null) { throw new IllegalArgumentException("Item " + item.getElementName() + " is already present in " + this.getClass().getSimpleName()); } item.setParent(this); @@ -358,11 +346,11 @@ public boolean add(Item if (prismContext != null) { item.setPrismContext(prismContext); } - if (getActualDefinition() != null && item.getDefinition() == null) { - item.applyDefinition((ID)determineItemDefinition(item.getElementName(), getActualDefinition()), false); + if (getComplexTypeDefinition() != null && item.getDefinition() == null) { + item.applyDefinition((ID)determineItemDefinition(item.getElementName(), getComplexTypeDefinition()), false); } if (items == null) { - items = new ArrayList>(); + items = new ArrayList<>(); } return items.add(item); } @@ -372,13 +360,14 @@ public boolean add(Item * Returns true if new item or value was added. */ public boolean merge(Item item) throws SchemaException { - Item exisingItem = findItem(item.getElementName(), Item.class); - if (exisingItem == null) { + checkMutability(); + Item existingItem = findItem(item.getElementName(), Item.class); + if (existingItem == null) { return add(item); } else { boolean changed = false; for (IV newVal: item.getValues()) { - if (exisingItem.add((IV) newVal.clone())) { + if (existingItem.add((IV) newVal.clone())) { changed = true; } } @@ -387,18 +376,19 @@ public boolean merge(Item boolean substract(Item item) throws SchemaException { - Item exisingItem = findItem(item.getElementName(), Item.class); - if (exisingItem == null) { + public boolean subtract(Item item) throws SchemaException { + checkMutability(); + Item existingItem = findItem(item.getElementName(), Item.class); + if (existingItem == null) { return false; } else { boolean changed = false; for (IV newVal: item.getValues()) { - if (exisingItem.remove(newVal)) { + if (existingItem.remove(newVal)) { changed = true; } } @@ -412,7 +402,8 @@ public boolean substract(Item< * @param item item to add. */ public void addReplaceExisting(Item item) throws SchemaException { - if (item == null){ + checkMutability(); + if (item == null) { return; } Item existingItem = findItem(item.getElementName(), Item.class); @@ -425,8 +416,9 @@ public void addReplaceExisting public void remove(Item item) { Validate.notNull(item, "Item must not be null."); + checkMutability(); - Item existingItem = findItem(item.getElementName(), Item.class); + Item existingItem = findItem(item.getElementName(), Item.class); if (existingItem != null && items != null) { items.remove(existingItem); existingItem.setParent(null); @@ -434,6 +426,7 @@ public void remove(Item } public void removeAll() { + checkMutability(); if (items == null){ return; } @@ -463,6 +456,7 @@ public void addAll(Collection> itemsToAdd) throws SchemaExce * @param itemsToAdd items to add */ public void addAllReplaceExisting(Collection> itemsToAdd) throws SchemaException { + checkMutability(); // Check for conflicts, remove conflicting values for (Item item : itemsToAdd) { Item existingItem = findItem(item.getElementName(), Item.class); @@ -478,33 +472,16 @@ public void replace(Item list) { -// if (items != null) { -// for (Item item: items) { -// if (item instanceof PrismProperty) { -// list.add(basePath.subPath(item.getElementName())); -// } else if (item instanceof PrismContainer) { -// ((PrismContainer)item).addItemPathsToList(basePath, list); -// } -// } -// } -// } - public void clear() { + checkMutability(); if (items != null) { items.clear(); } } public boolean contains(Item item) { - if (items != null) { - return items.contains(item); - } - return false; - } + return items != null && items.contains(item); + } public boolean contains(QName itemName) { return findItem(itemName) != null; @@ -730,12 +707,14 @@ private Item findItemBy } private > I createSubItem(QName name, Class type, ID itemDefinition) throws SchemaException { + checkMutability(); // the item with specified name does not exist, create it now I newItem = null; - if (itemDefinition == null && getActualDefinition() != null) { - itemDefinition = determineItemDefinition(name, getActualDefinition()); - if (itemDefinition == null) { + if (itemDefinition == null) { + ComplexTypeDefinition ctd = getComplexTypeDefinition(); + itemDefinition = determineItemDefinition(name, ctd); + if (ctd != null && itemDefinition == null) { throw new SchemaException("No definition for item "+name+" in "+getParent()); } } @@ -815,12 +794,14 @@ public PrismProperty findOrCreateProperty(PrismPropertyDefinition propert // } public PrismContainer createContainer(QName containerName) throws SchemaException { - if (getActualDefinition() == null) { + checkMutability(); + ComplexTypeDefinition complexTypeDefinition = getComplexTypeDefinition(); + if (complexTypeDefinition == null) { throw new IllegalStateException("No definition of container "+containerName); } - PrismContainerDefinition containerDefinition = getActualDefinition().findContainerDefinition(containerName); + PrismContainerDefinition containerDefinition = complexTypeDefinition.findContainerDefinition(containerName); if (containerDefinition == null) { - throw new IllegalArgumentException("No definition of container '" + containerName + "' in " + getActualDefinition()); + throw new IllegalArgumentException("No definition of container '" + containerName + "' in " + complexTypeDefinition); } PrismContainer container = containerDefinition.instantiate(); add(container); @@ -828,24 +809,18 @@ public PrismContainer createContainer(QName contain } public PrismProperty createProperty(QName propertyName) throws SchemaException { - PrismPropertyDefinition propertyDefinition = null; - if (getActualDefinition() != null) { - propertyDefinition = getActualDefinition().findPropertyDefinition(propertyName); - if (propertyDefinition == null) { - // container has definition, but there is no property definition. This is either runtime schema - // or an error - if (getParent().getDefinition().isRuntimeSchema) { - // TODO: create opportunistic runtime definition - //propertyDefinition = new PrismPropertyDefinition(propertyName, propertyName, typeName, container.prismContext); - } else { - throw new IllegalArgumentException("No definition for property "+propertyName+" in "+getActualDefinition()); - } - } - } - PrismProperty property = null; + checkMutability(); + PrismPropertyDefinition propertyDefinition = determineItemDefinition(propertyName, getComplexTypeDefinition()); + if (propertyDefinition == null) { + // container has definition, but there is no property definition. This is either runtime schema + // or an error + if (getParent() != null && getDefinition() != null && !getDefinition().isRuntimeSchema()) { // TODO clean this up + throw new IllegalArgumentException("No definition for property "+propertyName+" in "+complexTypeDefinition); + } + } + PrismProperty property; if (propertyDefinition == null) { - // Definitionless - property = new PrismProperty(propertyName, prismContext); + property = new PrismProperty(propertyName, prismContext); // Definitionless } else { property = propertyDefinition.instantiate(); } @@ -885,6 +860,7 @@ public void removeReference(ItemPath path) { // Expects that "self" path is NOT present in propPath > void removeItem(ItemPath propPath, Class itemType) { + checkMutability(); if (items == null){ return; } @@ -914,6 +890,7 @@ > void rem } public void setPropertyRealValue(QName propertyName, Object realValue, PrismContext prismContext) throws SchemaException { + checkMutability(); PrismProperty property = findOrCreateProperty(propertyName); property.setRealValue(realValue); if (property.getPrismContext() == null) { @@ -990,9 +967,10 @@ public boolean representsSameValue(PrismValue other) { } } - public boolean representsSameValue(PrismContainerValue other) { + @SuppressWarnings("Duplicates") + private boolean representsSameValue(PrismContainerValue other) { if (getParent() != null) { - PrismContainerDefinition definition = getActualDefinition(); + PrismContainerDefinition definition = getDefinition(); if (definition != null) { if (definition.isSingleValue()) { // There is only one value, therefore it always represents the same thing @@ -1001,7 +979,7 @@ public boolean representsSameValue(PrismContainerValue other) { } } if (other.getParent() != null) { - PrismContainerDefinition definition = other.getActualDefinition(); + PrismContainerDefinition definition = other.getDefinition(); if (definition != null) { if (definition.isSingleValue()) { // There is only one value, therefore it always represents the same thing @@ -1028,47 +1006,19 @@ void diffMatchingRepresentation(PrismValue otherValue, void diffRepresentation(PrismContainerValue otherValue, Collection deltas, boolean ignoreMetadata, boolean isLiteral) { - PrismContainerValue thisValue = this; - if (this.isRaw() || otherValue.isRaw()) { - try { - if (this.isRaw()) { - otherValue = parseRawElementsToNewValue(otherValue, thisValue); - } else if (otherValue.isRaw()) { - thisValue = parseRawElementsToNewValue(thisValue, otherValue); - } - } catch (SchemaException e) { - // TODO: Maybe just return false? - throw new IllegalArgumentException("Error parsing the value of container "+getParent()+" using the 'other' definition "+ - "during a compare: "+e.getMessage(),e); - } - } - diffItems(thisValue, otherValue, deltas, ignoreMetadata, isLiteral); + diffItems(this, otherValue, deltas, ignoreMetadata, isLiteral); } @Override public boolean isRaw() { - return rawXNode != null || rawElements != null; + return false; } - public MapXNode getRawXNode() { - return rawXNode; - } - - public List getRawElements() { - return rawElements; - } - public boolean addRawElement(Object element) throws SchemaException { + checkMutability(); PrismContainerDefinition definition = getDefinition(); if (definition == null) { - // We cannot do much better. We do not even have prism context here. - if (rawElements == null) { - if (items != null && !items.isEmpty()) { - throw new IllegalStateException("Attempt to add raw element to prism container value which already has items: "+this); - } - rawElements = new ArrayList(); - } - return rawElements.add(element); + throw new UnsupportedOperationException("Definition-less containers are not supported any more."); } else { // We have definition here, we can parse it right now Item subitem = parseRawElement(element, definition); @@ -1077,23 +1027,21 @@ public boolean addRawElement(Object element) throws SchemaException { } public boolean deleteRawElement(Object element) throws SchemaException { + checkMutability(); PrismContainerDefinition definition = getDefinition(); if (definition == null) { - // We cannot do much better. We do not even have prism context here. - if (rawElements == null) { - rawElements = new ArrayList(); - } - return rawElements.add(element); + throw new UnsupportedOperationException("Definition-less containers are not supported any more."); } else { // We have definition here, we can parse it right now Item subitem = parseRawElement(element, definition); - return substract(subitem); + return subtract(subitem); } } public boolean removeRawElement(Object element) { - return rawElements.remove(element); + checkMutability(); + throw new UnsupportedOperationException("Definition-less containers are not supported any more."); } private Item parseRawElement(Object element, PrismContainerDefinition definition) throws SchemaException { @@ -1102,30 +1050,7 @@ private Item parseRawEl } private PrismContainerValue parseRawElementsToNewValue(PrismContainerValue origCVal, PrismContainerValue definitionSource) throws SchemaException { - if (definitionSource.getParent() == null || definitionSource.getActualDefinition() == null) { - throw new IllegalArgumentException("Attempt to use container " + origCVal.getParent() + - " values in a raw parsing state (raw elements) with parsed value that has no definition"); - } - PrismContainerDefinition definition = definitionSource.getActualDefinition(); - - XNode origRawXnode = origCVal.rawXNode; - if (origRawXnode != null) { - XNodeProcessor xnodeProcessor = definition.getPrismContext().getXnodeProcessor(); - PrismContainerValue newCVal = xnodeProcessor.parsePrismContainerValue(origRawXnode, definition, ParsingContext.createDefault()); - return newCVal; - } - - List origRawElements = origCVal.rawElements; - if (origRawElements != null) { - PrismContainerValue newCVal = new PrismContainerValue(prismContext); - for (Object rawElement: origRawElements) { - Item subitem = parseRawElement(rawElement, definition); - newCVal.merge(subitem); - } - return newCVal; - } - - return null; + throw new UnsupportedOperationException("Definition-less containers are not supported any more."); } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -1162,48 +1087,35 @@ protected PrismContainerDefinition getDefinition() { @Override public void applyDefinition(ItemDefinition definition, boolean force) throws SchemaException { + checkMutability(); if (!(definition instanceof PrismContainerDefinition)) { throw new IllegalArgumentException("Cannot apply "+definition+" to container " + this); } applyDefinition((PrismContainerDefinition)definition, force); } - public void applyDefinition(PrismContainerDefinition containerDef, boolean force) throws SchemaException { - PrismContainerDefinition valueDefinition = getConcreteTypeDefinition(); - if (valueDefinition == null) { - valueDefinition = containerDef; - } - if (valueDefinition.isWildcard()) { - // No point in aplying this. Nothing will change and there may be phantom errors. - return; - } - if (rawElements != null) { - for (Object rawElement: rawElements) { - Item subitem = parseRawElement(rawElement, valueDefinition); - merge(subitem); - } - rawElements = null; + public void applyDefinition(@NotNull PrismContainerDefinition containerDef, boolean force) throws SchemaException { + checkMutability(); + if (complexTypeDefinition != null && !force) { + return; // there's a definition already } - if (rawXNode != null) { - PrismContext prismContext = valueDefinition.getPrismContext(); - XNodeProcessor xnodeProcessor = prismContext.getXnodeProcessor(); - PrismContainerValue newCVal = xnodeProcessor.parsePrismContainerValue(rawXNode, valueDefinition, ParsingContext.createDefault()); - // Maybe we need to manually reset parent on items? - addAll(newCVal.getItems()); - rawXNode = null; + replaceComplexTypeDefinition(containerDef.getComplexTypeDefinition()); + if (complexTypeDefinition == null || complexTypeDefinition.isXsdAnyMarker()) { + // No point in applying this. Nothing will change and there may be phantom errors. + return; } if (items != null) { - for (Item item: items) { + for (Item item : items) { if (item.getDefinition() != null && !force) { // Item has a definition already, no need to apply it continue; } - ItemDefinition itemDefinition = determineItemDefinition(item.getElementName(), valueDefinition); + ItemDefinition itemDefinition = determineItemDefinition(item.getElementName(), complexTypeDefinition); if (itemDefinition == null && item.getDefinition() != null && item.getDefinition().isDynamic()) { // We will not apply the null definition here. The item has a dynamic definition that we don't // want to destroy as it cannot be reconstructed later. } else { - item.applyDefinition(itemDefinition); + item.applyDefinition(itemDefinition, force); } } } @@ -1213,21 +1125,23 @@ public void applyDefinition(PrismContainerDefinition containerDef, boolean fo * This method can both return null and throws exception. It returns null in case there is no definition * but it is OK (e.g. runtime schema). It throws exception if there is no definition and it is not OK. */ - private ID determineItemDefinition(QName itemName, PrismContainerDefinition containerDefinition) throws SchemaException { - ID itemDefinition = containerDefinition.findItemDefinition(itemName); - if (itemDefinition == null) { - if (containerDefinition.isRuntimeSchema()) { - // If we have prism context, try to locate global definition. But even if that is not - // found it is still OK. This is runtime container. We tolerate quite a lot here. - PrismContext prismContext = getPrismContext(); - if (prismContext != null) { - itemDefinition = (ID) prismContext.getSchemaRegistry().resolveGlobalItemDefinition(itemName); - } + private ID determineItemDefinition(QName itemName, @Nullable ComplexTypeDefinition ctd) throws SchemaException { + ID itemDefinition = ctd != null ? ctd.findItemDefinition(itemName) : null; + if (itemDefinition != null) { + return itemDefinition; + } + if (ctd == null || ctd.isXsdAnyMarker() || ctd.isRuntimeSchema()) { + // If we have prism context, try to locate global definition. But even if that is not + // found it is still OK. This is runtime container. We tolerate quite a lot here. + PrismContext prismContext = getPrismContext(); + if (prismContext != null) { + return (ID) prismContext.getSchemaRegistry().resolveGlobalItemDefinition(itemName, ctd); } else { - throw new SchemaException("No definition for item " + itemName + " in " + getParent()); + return null; } + } else { + throw new SchemaException("No definition for item " + itemName + " in " + getParent()); } - return itemDefinition; } @Override @@ -1256,6 +1170,7 @@ public boolean isEmpty() { @Override public void normalize() { + checkMutability(); if (items != null) { Iterator> iterator = items.iterator(); while (iterator.hasNext()) { @@ -1271,18 +1186,9 @@ public void normalize() { @Override public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) { ItemPath myPath = getPath(); - if (scope.isThorough()) { - if (prohibitRaw && isRaw()) { - throw new IllegalStateException("Raw elements in container value "+this+" ("+myPath+" in "+rootItem+")"); - } - if (items == null && !isRaw()) { - // This is normal empty container, isn't it? -// throw new IllegalStateException("Neither items nor raw elements specified in container value "+this+" ("+myPath+" in "+rootItem+")"); - } - if (items != null && isRaw()) { - throw new IllegalStateException("Both items and raw elements specified in container value "+this+" ("+myPath+" in "+rootItem+")"); - } - } + if (getDefinition() == null) { + throw new IllegalStateException("Definition-less container value " + this +" ("+myPath+" in "+rootItem+")"); + } if (items != null) { for (Item item: items) { if (scope.isThorough()) { @@ -1315,8 +1221,8 @@ public void assertDefinitions(boolean tolerateRaw, String sourceDescription) thr } } - public PrismContainerValue clone() { - PrismContainerValue clone = new PrismContainerValue(getOriginType(), getOriginObject(), getParent(), getId(), this.concreteType, this.prismContext); + public PrismContainerValue clone() { // TODO resolve also the definition? + PrismContainerValue clone = new PrismContainerValue(getOriginType(), getOriginObject(), getParent(), getId(), this.complexTypeDefinition, this.prismContext); copyValues(clone); return clone; } @@ -1334,9 +1240,6 @@ protected void copyValues(PrismContainerValue clone) { clone.items.add(clonedItem); } } - // TODO: deep clonning? - clone.rawXNode = this.rawXNode; - clone.rawElements = this.rawElements; } protected void deepCloneDefinition(boolean ultraDeep, PrismContainerDefinition clonedContainerDef) { @@ -1358,8 +1261,18 @@ private > } else { clonedItemDef = (ID) oldItemDef.deepClone(ultraDeep); } - item.propagateDeepCloneDefinition(ultraDeep, clonedItemDef); - item.setDefinition(clonedItemDef); + + // special treatment of CTD (we must not simply overwrite it with clonedPCD.CTD!) + PrismContainerable parent = getParent(); + if (parent != null && complexTypeDefinition != null) { + if (complexTypeDefinition == parent.getComplexTypeDefinition()) { + replaceComplexTypeDefinition(clonedContainerDef.getComplexTypeDefinition()); + } else { + replaceComplexTypeDefinition(complexTypeDefinition.deepClone(ultraDeep ? null : new HashMap<>() )); // OK? + } + } + item.propagateDeepCloneDefinition(ultraDeep, clonedItemDef); // propagate to items in values + item.setDefinition(clonedItemDef); // sets CTD in values only if null! } @Override @@ -1433,9 +1346,6 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("PCV("); sb.append(getId()); - if (isRaw()) { - sb.append(", raw"); - } sb.append("):"); sb.append(getItems()); return sb.toString(); @@ -1469,7 +1379,7 @@ public String debugDump(int indent) { sb.append("id=").append(PrettyPrinter.prettyPrint(getId())); } appendOriginDump(sb); - List> items = getItems(); + List> items = getItems(); if (items != null) { Iterator> i = getItems().iterator(); if (wasIndent && i.hasNext()) { @@ -1482,14 +1392,6 @@ public String debugDump(int indent) { sb.append("\n"); } } - } else { - if (isRaw()) { - if (wasIndent) { - sb.append("\n"); - } - DebugUtil.indentDebugDump(sb, indent + 1); - sb.append("(raw)"); - } } return sb.toString(); } @@ -1512,68 +1414,63 @@ public String toHumanReadableString() { // no information on corresponding element name) // // todo review usefulness and appropriateness of this method and its placement - public static void copyDefinition(Containerable aClone, Containerable original) { + @Deprecated + public static void copyDefinition(Containerable aClone, Containerable original, PrismContext prismContext) { try { Validate.notNull(original.asPrismContainerValue().getParent(), "original PrismContainerValue has no parent"); - PrismContainerDefinition definition = original.asPrismContainerValue().getActualDefinition(); + ComplexTypeDefinition definition = original.asPrismContainerValue().getComplexTypeDefinition(); Validate.notNull(definition, "original PrismContainer definition is null"); - PrismContainer aCloneParent = definition.instantiate(); + PrismContainer aCloneParent = prismContext.getSchemaRegistry() + .findContainerDefinitionByCompileTimeClass((Class) definition.getCompileTimeClass()) + .instantiate(); aCloneParent.add(aClone.asPrismContainerValue()); } catch (SchemaException e) { throw new SystemException("Unexpected SchemaException when copying definition from original object to its clone", e); } } - public QName getConcreteType() { - return concreteType; + public QName getTypeName() { + return getComplexTypeDefinition() != null ? getComplexTypeDefinition().getTypeName() : null; } - public void setConcreteType(QName concreteType) { - this.concreteType = concreteType; - this.concreteTypeDefinition = null; - } + @Nullable + public ComplexTypeDefinition getComplexTypeDefinition() { + if (complexTypeDefinition == null) { + complexTypeDefinition = determineComplexTypeDefinition(); + } + return complexTypeDefinition; + } - // TODO change from PrismContainerDefinition to ComplexTypeDefinition - // because in current state there should be an element definition for each subtype that is to be resolvable in this way - public PrismContainerDefinition getConcreteTypeDefinition() { - if (concreteTypeDefinition != null) { - return concreteTypeDefinition; - } - if (concreteType != null) { - // First of all, if we have parent definition and it is applicable, just use that - // (Besides performance aspects, the parent definition might be already converted - // to contain ResourceAttributeContainerDefinition instead of PrismContainerDefinition - // - in case of ShadowType.) - if (getParent() != null && getParent().getDefinition() != null && concreteType.equals(getParent().getDefinition().getTypeName())) { - concreteTypeDefinition = getParent().getDefinition(); - } else { - PrismContext prismContext = getPrismContext(); - if (prismContext != null) { - concreteTypeDefinition = prismContext.getSchemaRegistry().findContainerDefinitionByType(concreteType); - if (concreteTypeDefinition == null) { - throw new IllegalStateException("Couldn't find a definition for concrete type " + concreteType); - } - } - } - } - return concreteTypeDefinition; // may still be null at this moment - } + // will correctly work only if argument is not null (otherwise the CTD will be determined on next call to getCTD) + void replaceComplexTypeDefinition(ComplexTypeDefinition complexTypeDefinition) { +// if (this.complexTypeDefinition != null && complexTypeDefinition != null && !this.complexTypeDefinition.getTypeName().equals(complexTypeDefinition.getTypeName())) { +// System.out.println("Dangerous!"); +// } + this.complexTypeDefinition = complexTypeDefinition; + } - private PrismContainerDefinition getActualDefinition() { - if (getParent() != null) { - PrismContainerDefinition concreteDef = getConcreteTypeDefinition(); - if (concreteDef != null) { - return concreteDef; - } else { - return getParent().getDefinition(); - } - } else { - return null; - } - } + private ComplexTypeDefinition determineComplexTypeDefinition() { + PrismContainerable parent = getParent(); + ComplexTypeDefinition parentCTD = parent != null && parent.getDefinition() != null ? + parent.getDefinition().getComplexTypeDefinition() : null; + if (containerable == null) { + return parentCTD; + } + if (prismContext == null) { + // check if parentCTD matches containerable + if (parentCTD != null && containerable.getClass().equals(parentCTD.getCompileTimeClass())) { + return parentCTD; + } else { + //throw new IllegalStateException("Cannot determine complexTypeDefinition for PrismContainerValue because prismContext is missing; PCV = " + this); + return null; + } + } + ComplexTypeDefinition def = prismContext.getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(containerable.getClass()); + return def; // may be null at this place + } public static List> toPcvList(List beans) { List> rv = new ArrayList<>(beans.size()); @@ -1582,5 +1479,47 @@ public static List> toPcvList(L } return rv; } - + + @Override + public void setImmutable(boolean immutable) { + super.setImmutable(immutable); + if (items != null) { + for (Item item : items) { + item.setImmutable(immutable); + } + } + } + + @Override + public Class getRealClass() { + if (containerable != null) { + return containerable.getClass(); + } + return resolveClass(null); + } + + @SuppressWarnings("unchecked") + @Nullable + @Override + public T getRealValue() { + return (T) asContainerable(); + } + + /** + * Returns a single-valued container (with a single-valued definition) holding just this value. + * @param itemName Item name for newly-created container. + * @return + */ + public PrismContainer asSingleValuedContainer(@NotNull QName itemName) throws SchemaException { + PrismContext prismContext = getPrismContext(); + Validate.notNull(prismContext, "Prism context is null"); + + PrismContainerDefinitionImpl definition = new PrismContainerDefinitionImpl<>(itemName, + getComplexTypeDefinition(), prismContext); + definition.setMaxOccurs(1); + + PrismContainer pc = definition.instantiate(); + pc.add(clone()); + return pc; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerable.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerable.java index 2cbb66216c0..00da6e2079b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerable.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerable.java @@ -26,4 +26,8 @@ public interface PrismContainerable extends Itemable { public Class getCompileTimeClass(); + default ComplexTypeDefinition getComplexTypeDefinition() { + PrismContainerDefinition def = getDefinition(); + return def != null ? def.getComplexTypeDefinition() : null; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java index acfc196b77a..0a2f9125919 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java @@ -13,668 +13,222 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.evolveum.midpoint.prism; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.parser.*; +import com.evolveum.midpoint.prism.marshaller.JaxbDomHack; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; -import com.evolveum.midpoint.prism.polystring.PrismDefaultPolyStringNormalizer; -import com.evolveum.midpoint.prism.schema.SchemaDefinitionFactory; import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.prism.util.PrismMonitor; import com.evolveum.midpoint.prism.xnode.RootXNode; -import com.evolveum.midpoint.prism.xnode.XNode; -import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.prism.xml.ns._public.types_3.RawType; -import org.springframework.beans.factory.annotation.Autowired; -import org.w3c.dom.Document; +import org.jetbrains.annotations.NotNull; import org.w3c.dom.Element; import org.xml.sax.SAXException; -import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.*; -import java.util.Map.Entry; /** - * @author semancik * + * @author semancik + * @author mederly */ -public class PrismContext { - - public static final String LANG_XML = "xml"; - public static final String LANG_JSON = "json"; - public static final String LANG_YAML = "yaml"; - - private static final Trace LOGGER = TraceManager.getTrace(PrismContext.class); - - private static boolean allowSchemalessSerialization = true; - - private SchemaRegistry schemaRegistry; - private XNodeProcessor xnodeProcessor; - private PrismBeanConverter beanConverter; - private SchemaDefinitionFactory definitionFactory; - private PolyStringNormalizer defaultPolyStringNormalizer; - private Map parserMap; - private PrismMonitor monitor = null; - - @Autowired - private Protector defaultProtector; - - // We need to keep this because of deprecated methods and various hacks - private DomParser parserDom; - private JaxbDomHack jaxbDomHack; - - //region Standard overhead - private PrismContext() { - // empty - } +public interface PrismContext { - public static PrismContext create(SchemaRegistry schemaRegistry) { - PrismContext prismContext = new PrismContext(); - prismContext.schemaRegistry = schemaRegistry; - schemaRegistry.setPrismContext(prismContext); - - prismContext.xnodeProcessor = new XNodeProcessor(prismContext); - PrismBeanInspector inspector = new PrismBeanInspector(prismContext); - prismContext.beanConverter = new PrismBeanConverter(prismContext, inspector); - - prismContext.parserMap = new HashMap(); - DomParser parserDom = new DomParser(schemaRegistry); - prismContext.parserMap.put(LANG_XML, parserDom); - JsonParser parserJson = new JsonParser(); - prismContext.parserMap.put(LANG_JSON, parserJson); - YamlParser parserYaml = new YamlParser(); - prismContext.parserMap.put(LANG_YAML, parserYaml); - prismContext.parserDom = parserDom; - - prismContext.jaxbDomHack = new JaxbDomHack(parserDom, prismContext); - - return prismContext; - } - - public static PrismContext createEmptyContext(SchemaRegistry schemaRegistry){ - PrismContext prismContext = new PrismContext(); - prismContext.schemaRegistry = schemaRegistry; - schemaRegistry.setPrismContext(prismContext); + String LANG_XML = "xml"; + String LANG_JSON = "json"; + String LANG_YAML = "yaml"; - return prismContext; - } + /** + * Initializes the prism context, e.g. loads and parses all the schemas. + */ + void initialize() throws SchemaException, SAXException, IOException; - public void initialize() throws SchemaException, SAXException, IOException { - schemaRegistry.initialize(); - if (defaultPolyStringNormalizer == null) { - defaultPolyStringNormalizer = new PrismDefaultPolyStringNormalizer(); - } - } + /** + * Returns the schema registry. + */ + @NotNull + SchemaRegistry getSchemaRegistry(); - public static boolean isAllowSchemalessSerialization() { - return allowSchemalessSerialization; - } + /** + * Returns the default PolyString normalizer. + */ + @NotNull + PolyStringNormalizer getDefaultPolyStringNormalizer(); - public static void setAllowSchemalessSerialization(boolean allowSchemalessSerialization) { - PrismContext.allowSchemalessSerialization = allowSchemalessSerialization; - } + /** + * Returns the default protector. (TODO) + */ + Protector getDefaultProtector(); - public SchemaRegistry getSchemaRegistry() { - return schemaRegistry; - } + //region Parsing + /** + * Creates a parser ready to process the given file. + * @param file File to be parsed. + * @return Parser that can be invoked to retrieve the (parsed) content of the file. + */ + @NotNull + PrismParser parserFor(@NotNull File file); - public void setSchemaRegistry(SchemaRegistry schemaRegistry) { - this.schemaRegistry = schemaRegistry; - } + /** + * Creates a parser ready to process data from the given input stream. + * @param stream Input stream to be parsed. + * @return Parser that can be invoked to retrieve the (parsed) content of the input stream. + */ + @NotNull + PrismParser parserFor(@NotNull InputStream stream); - public XNodeProcessor getXnodeProcessor() { - return xnodeProcessor; - } + /** + * Creates a parser ready to process data from the given string. + * @param data String with the data to be parsed. It has be in UTF-8 encoding. + * (For other encodings please use InputStream or File source.) + * @return Parser that can be invoked to retrieve the (parsed) content. + */ + @NotNull + PrismParserNoIO parserFor(@NotNull String data); /** - * WARNING! This is not really public method. It should NOT not used outside the prism implementation. + * Creates a parser ready to process data from the given XNode tree. + * @param xnode XNode tree with the data to be parsed. + * @return Parser that can be invoked to retrieve the (parsed) content. */ - public DomParser getParserDom() { - return parserDom; - } + @NotNull + PrismParserNoIO parserFor(@NotNull RootXNode xnode); - public PrismBeanConverter getBeanConverter() { - return beanConverter; - } + /** + * Creates a parser ready to process data from the given DOM element. + * @param element Element with the data to be parsed. + * @return Parser that can be invoked to retrieve the (parsed) content. + */ + @NotNull + PrismParserNoIO parserFor(@NotNull Element element); - public JaxbDomHack getJaxbDomHack() { - return jaxbDomHack; + default PrismObject parseObject(File file) throws SchemaException, IOException { + return parserFor(file).parse(); } - public SchemaDefinitionFactory getDefinitionFactory() { - if (definitionFactory == null) { - definitionFactory = new SchemaDefinitionFactory(); - } - return definitionFactory; + default PrismObject parseObject(String dataString) throws SchemaException { + return parserFor(dataString).parse(); } + //endregion - public void setDefinitionFactory(SchemaDefinitionFactory definitionFactory) { - this.definitionFactory = definitionFactory; - } + //region Adopt methods + void adopt(PrismContainer object, Class declaredType) throws SchemaException; - public PolyStringNormalizer getDefaultPolyStringNormalizer() { - return defaultPolyStringNormalizer; - } + void adopt(PrismContainer object) throws SchemaException; - public void setDefaultPolyStringNormalizer(PolyStringNormalizer defaultPolyStringNormalizer) { - this.defaultPolyStringNormalizer = defaultPolyStringNormalizer; - } + void adopt(Objectable objectable) throws SchemaException; - private Parser getParser(String language) { - return parserMap.get(language); - } + void adopt(Containerable containerable) throws SchemaException; - private Parser getParserNotNull(String language) { - Parser parser = getParser(language); - if (parser == null) { - throw new SystemException("No parser for language '"+language+"'"); - } - return parser; - } - - public Protector getDefaultProtector() { - return defaultProtector; - } - - public void setDefaultProtector(Protector defaultProtector) { - this.defaultProtector = defaultProtector; - } + void adopt(PrismContainerValue value) throws SchemaException; - public PrismMonitor getMonitor() { - return monitor; - } + void adopt(ObjectDelta delta) throws SchemaException; - public void setMonitor(PrismMonitor monitor) { - this.monitor = monitor; - } + void adopt(C containerable, Class type, ItemPath path) throws SchemaException; + + void adopt(PrismContainerValue prismContainerValue, Class type, + ItemPath path) throws SchemaException; - //endregion + void adopt(PrismContainerValue prismContainerValue, QName typeName, + ItemPath path) throws SchemaException; + //endregion - //region Parsing Prism objects + //region Serializing /** - * Parses a file and creates a prism from it. Autodetect language. - * @throws IOException + * Creates a serializer for the given language. + * @param language Language (like xml, json, yaml). + * @return The serializer. */ - public PrismObject parseObject(File file) throws SchemaException, IOException { - Parser parser = findParser(file); - XNode xnode = parser.parse(file); - return xnodeProcessor.parseObject(xnode, newParsingContext()); - } - - public PrismObject parseObject(File file, ParsingContext context) throws SchemaException, IOException { - Parser parser = findParser(file); - XNode xnode = parser.parse(file); - return xnodeProcessor.parseObject(xnode, context); - } + @NotNull + PrismSerializer serializerFor(@NotNull String language); /** - * Parses a file and creates a prism from it. + * Creates a serializer for XML language. + * @return The serializer. */ - public PrismObject parseObject(File file, String language) throws SchemaException, IOException { - XNode xnode = parseToXNode(file, language); - return xnodeProcessor.parseObject(xnode, newParsingContext()); - } + @NotNull + PrismSerializer xmlSerializer(); - /** - * Parses data from an input stream and creates a prism from it. - */ - public PrismObject parseObject(InputStream stream, String language) throws SchemaException, IOException { - XNode xnode = parseToXNode(stream, language); - return xnodeProcessor.parseObject(xnode, newParsingContext()); - } - - /** - * Parses a string and creates a prism from it. Autodetect language. - * Used mostly for testing, but can also be used for built-in editors, etc. - */ - public PrismObject parseObject(String dataString) throws SchemaException { - Parser parser = findParser(dataString); - XNode xnode = parser.parse(dataString); - return xnodeProcessor.parseObject(xnode, newParsingContext()); - } - /** - * Parses a string and creates a prism from it. Autodetect language. - * Used mostly for testing, but can also be used for built-in editors, etc. + * Creates a serializer for JSON language. + * @return The serializer. */ - public PrismObject parseObject(String dataString, XNodeProcessorEvaluationMode mode) throws SchemaException { - Parser parser = findParser(dataString); - XNode xnode = parser.parse(dataString); - XNodeProcessor myXnodeProcessor = new XNodeProcessor(this); - return myXnodeProcessor.parseObject(xnode, ParsingContext.forMode(mode)); - } + @NotNull + PrismSerializer jsonSerializer(); - public PrismObject parseObject(String dataString, ParsingContext parsingContext) throws SchemaException { - Parser parser = findParser(dataString); - XNode xnode = parser.parse(dataString); - XNodeProcessor myXnodeProcessor = new XNodeProcessor(this); - return myXnodeProcessor.parseObject(xnode, parsingContext); - } - /** - * Parses a string and creates a prism from it. Used mostly for testing, but can also be used for built-in editors, etc. + * Creates a serializer for YAML language. + * @return The serializer. */ - public PrismObject parseObject(String dataString, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseObject(xnode, newParsingContext()); - } - - /** - * Parses a DOM object and creates a prism from it. - */ - @Deprecated - public PrismObject parseObject(Element objectElement) throws SchemaException { - RootXNode xroot = parserDom.parseElementAsRoot(objectElement); - return xnodeProcessor.parseObject(xroot, newParsingContext()); - } - - public List> parseObjects(File file) throws SchemaException, IOException { - Parser parser = findParser(file); - Collection nodes = parser.parseCollection(file); - Iterator nodesIterator = nodes.iterator(); - List> objects = new ArrayList<>(); - while (nodesIterator.hasNext()){ - XNode node = nodesIterator.next(); - PrismObject object = xnodeProcessor.parseObject(node, newParsingContext()); - objects.add(object); - } - return objects; - } - - public Collection parseObjects(InputStream stream, String language) throws SchemaException, IOException { - Parser parser = getParserNotNull(language); - Collection nodes = parser.parseCollection(stream); - return nodes; -// Iterator nodesIterator = nodes.iterator(); -// List> objects = new ArrayList>(); -// while (nodesIterator.hasNext()){ -// XNode node = nodesIterator.next(); -// PrismObject object = xnodeProcessor.parseObject(node); -// objects.add(object); -// } -// return objects; - } - //endregion - - //region Parsing prism containers - public PrismContainer parseContainer(File file, Class type, String language) throws SchemaException, IOException { - XNode xnode = parseToXNode(file, language); - return xnodeProcessor.parseContainer(xnode, type, newParsingContext()); - } + @NotNull + PrismSerializer yamlSerializer(); - public PrismContainer parseContainer(File file, PrismContainerDefinition containerDef, String language) throws SchemaException, IOException { - XNode xnode = parseToXNode(file, language); - return xnodeProcessor.parseContainer(xnode, containerDef, newParsingContext()); - } - - public PrismContainer parseContainer(String dataString, Class type, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseContainer(xnode, type, newParsingContext()); - } - - public PrismContainer parseContainer(String dataString, PrismContainerDefinition containerDef, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseContainer(xnode, containerDef, newParsingContext()); - } + /** + * Creates a serializer for DOM. The difference from XML serializer is that XML produces String output + * whereas this one produces a DOM Element. + * @return The serializer. + */ + @NotNull + PrismSerializer domSerializer(); - /** - * Parses prism container, trying to autodetect the definition from the root node name (if present) or from node type. - * Both single and multivalued containers are supported. - * - * @param dataString String to be parsed. - * @param language Language to be used. - * @return - * @throws SchemaException - */ - public PrismContainer parseContainer(String dataString, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseContainer(xnode, newParsingContext()); - } - //endregion - - //region Parsing atomic values (properties values) - /** - * Parses an atomic value - i.e. something that could present a property value, if such a property would exist. - */ - public T parseAtomicValue(String dataString, QName typeName, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseAtomicValue(xnode, typeName, newParsingContext()); - } - - public T parseAtomicValue(String dataString, QName typeName) throws SchemaException { - XNode xnode = parseToXNode(dataString); - return xnodeProcessor.parseAtomicValue(xnode, typeName, newParsingContext()); - } - - public T parseAtomicValue(File file, QName typeName, String language) throws SchemaException, IOException { - XNode xnode = parseToXNode(file, language); - return xnodeProcessor.parseAtomicValue(xnode, typeName, newParsingContext()); - } - - public T parseAtomicValue(File file, QName typeName) throws SchemaException, IOException { - XNode xnode = parseToXNode(file); - return xnodeProcessor.parseAtomicValue(xnode, typeName, newParsingContext()); - } - - //endregion - - //region Parsing anything (without knowing the definition up-front) - /** - * Parses (almost) anything: either an item with a definition, or an atomic (i.e. property-like) value. - * Does not care for schemaless items! - * - * CAUTION: EXPERIMENTAL - Avoid using this method if at all possible. - * Its result is not well defined, namely, whether it returns Item or a value. - * - * @return either Item or an unmarshalled bean value - * @throws SchemaException - */ - public Object parseAnyData(String dataString, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseAnyData(xnode, newParsingContext()); - } - - public Object parseAnyData(File file) throws SchemaException, IOException { - XNode xnode = parseToXNode(file); - return xnodeProcessor.parseAnyData(xnode, newParsingContext()); - } - /** - * Emulates JAXB unmarshal method. - * - * TODO - * - * @return - * @throws SchemaException - */ - public T parseAnyValue(File file) throws SchemaException, IOException { - XNode xnode = parseToXNode(file); - return xnodeProcessor.parseAnyValue(xnode, newParsingContext()); - } - - public T parseAnyValue(Element element) throws SchemaException { - XNode xnode = parseToXNode(element); - return xnodeProcessor.parseAnyValue(xnode, newParsingContext()); - } - - public T parseAnyValue(InputStream inputStream, String language) throws SchemaException, IOException { - XNode xnode = parseToXNode(inputStream, language); - return xnodeProcessor.parseAnyValue(xnode, newParsingContext()); - } - - public T parseAnyValue(String dataString, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseAnyValue(xnode, newParsingContext()); - } - - // experimental! - public JAXBElement parseAnyValueAsJAXBElement(String dataString, String language) throws SchemaException { - XNode xnode = parseToXNode(dataString, language); - return xnodeProcessor.parseAnyValueAsJAXBElement(xnode, newParsingContext()); - } - //endregion - - //region Parsing to XNode - private XNode parseToXNode(String dataString) throws SchemaException { - Parser parser = findParser(dataString); - return parser.parse(dataString); - } - - public XNode parseToXNode(String dataString, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - return parser.parse(dataString); - } - - private XNode parseToXNode(File file) throws SchemaException, IOException { - Parser parser = findParser(file); - return parser.parse(file); - } - - private XNode parseToXNode(File file, String language) throws SchemaException, IOException { - Parser parser = getParserNotNull(language); - return parser.parse(file); - } - - private XNode parseToXNode(InputStream stream, String language) throws SchemaException, IOException { - Parser parser = getParserNotNull(language); - return parser.parse(stream); - } - - private XNode parseToXNode(Element domElement) throws SchemaException { - return parserDom.parse(domElement); - } - - public String serializeXNodeToString(RootXNode xroot, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - return parser.serializeToString(xroot); - } - - private Parser findParser(File file) throws IOException{ - Parser parser = null; - for (Entry entry: parserMap.entrySet()) { - Parser aParser = entry.getValue(); - if (aParser.canParse(file)) { - parser = aParser; - break; - } - } - if (parser == null) { - throw new SystemException("No parser for file '"+file+"' (autodetect)"); - } - return parser; - } - - private Parser findParser(String data){ - Parser parser = null; - for (Entry entry: parserMap.entrySet()) { - Parser aParser = entry.getValue(); - if (aParser.canParse(data)) { - parser = aParser; - break; - } - } - if (parser == null) { - throw new SystemException("No parser for data '"+DebugUtil.excerpt(data,16)+"' (autodetect)"); - } - return parser; - } - //endregion - - //region adopt(...) methods - /** - * Set up the specified object with prism context instance and schema definition. + /** + * Creates a serializer for XNode. The output of this serializer is intermediate XNode representation. + * @return The serializer. */ - public void adopt(PrismObject object, Class declaredType) throws SchemaException { - object.revive(this); - getSchemaRegistry().applyDefinition(object, declaredType, false); - } - - public void adopt(PrismObject object) throws SchemaException { - adopt(object, object.getCompileTimeClass()); - } + @NotNull + PrismSerializer xnodeSerializer(); - public void adopt(Objectable objectable) throws SchemaException { - adopt(objectable.asPrismObject(), objectable.getClass()); - } + @Deprecated // use serializerFor + serialize instead + String serializeObjectToString(PrismObject object, String language) throws SchemaException; - public void adopt(Containerable containerable) throws SchemaException { - containerable.asPrismContainerValue().revive(this); - } + /** + * TODO + * @param value + * @return + */ + boolean canSerialize(Object value); + //endregion - public void adopt(PrismContainerValue value) throws SchemaException { - value.revive(this); - } + /** + * Creates a new PrismObject of a given static type. + * @param clazz Static type of the object to be created. + * @return New PrismObject. + * @throws SchemaException If a definition for the given class couldn't be found. + */ + @NotNull + PrismObject createObject(@NotNull Class clazz) throws SchemaException; - public void adopt(ObjectDelta delta) throws SchemaException { - delta.revive(this); - getSchemaRegistry().applyDefinition(delta, delta.getObjectTypeClass(), false); - } - - public void adopt(C containerable, Class type, ItemPath path) throws SchemaException { - PrismContainerValue prismContainerValue = containerable.asPrismContainerValue(); - adopt(prismContainerValue, type, path); - } + /** + * Creates a new Objectable of a given static type. + * @param clazz Static type of the object to be created. + * @return New PrismObject's objectable content. + * @throws SchemaException If a definition for the given class couldn't be found. + */ + @NotNull + O createObjectable(@NotNull Class clazz) throws SchemaException; - public void adopt(PrismContainerValue prismContainerValue, Class type, ItemPath path) throws SchemaException { - prismContainerValue.revive(this); - getSchemaRegistry().applyDefinition(prismContainerValue, type, path, false); - } - - public void adopt(PrismContainerValue prismContainerValue, QName typeName, ItemPath path) throws SchemaException { - prismContainerValue.revive(this); - getSchemaRegistry().applyDefinition(prismContainerValue, typeName, path, false); - } - //endregion + /** + * TODO hide this from PrismContext interface? + */ + XmlEntityResolver getEntityResolver(); - //region Serializing objects, containers, atomic values (properties) - public String serializeObjectToString(PrismObject object, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - RootXNode xroot = xnodeProcessor.serializeObject(object); - return parser.serializeToString(xroot); - } - - public String serializeContainerValueToString(PrismContainerValue cval, QName elementName, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - - RootXNode xroot = xnodeProcessor.serializeItemValueAsRoot(cval, elementName); - //System.out.println("serialized to xnode: " + xroot.debugDump()); - return parser.serializeToString(xroot); - } + /** + * TODO eliminate this method + */ + @NotNull + @Deprecated + JaxbDomHack getJaxbDomHack(); - /** - * Serializes an atomic value - i.e. something that fits into a prism property (if such a property would exist). - * - * @param value Value to be serialized. - * @param elementName Element name to be used. - * @param language - * @return - * @throws SchemaException - * - * BEWARE, currently works only for values that can be processed via PrismBeanConvertor - i.e. not for special - * cases like PolyStringType, ProtectedStringType, etc. - */ - public String serializeAtomicValue(Object value, QName elementName, String language) throws SchemaException { - return serializeAtomicValue(value, elementName, language, null); - } - - public String serializeAtomicValue(Object value, QName elementName, String language, SerializationOptions serializationOptions) throws SchemaException { - Parser parser = getParserNotNull(language); - RootXNode xnode = xnodeProcessor.serializeAtomicValue(value, elementName, new SerializationContext(serializationOptions)); - return parser.serializeToString(xnode); - } + PrismMonitor getMonitor(); - public String serializeAtomicValue(JAXBElement element, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - RootXNode xnode = xnodeProcessor.serializeAtomicValue(element); - return parser.serializeToString(xnode); - } - - - /** - * Serializes any data - i.e. either Item or an atomic value. - * Does not support PrismValues: TODO: implement that! - * - * @param object - * @param language - * @return - * @throws SchemaException - */ - - public String serializeAnyData(Object object, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - RootXNode xnode = xnodeProcessor.serializeAnyData(object, null); - return parser.serializeToString(xnode); - } - - public String serializeAnyData(Object object, QName defaultRootElementName, String language) throws SchemaException { - Parser parser = getParserNotNull(language); - RootXNode xnode = xnodeProcessor.serializeAnyData(object, defaultRootElementName, null); - return parser.serializeToString(xnode); - } - - public Element serializeAnyDataToElement(Object object, QName defaultRootElementName) throws SchemaException { - RootXNode xnode = xnodeProcessor.serializeAnyData(object, defaultRootElementName, null); - return parserDom.serializeXRootToElement(xnode); - } - - public Element serializeAnyDataToElement(Object object, QName defaultRootElementName, SerializationContext ctx) throws SchemaException { - RootXNode xnode = xnodeProcessor.serializeAnyData(object, defaultRootElementName, ctx); - return parserDom.serializeXRootToElement(xnode); - } - - public boolean canSerialize(Object value) { - return xnodeProcessor.canSerialize(value); - } - - -// public String serializeAtomicValues(QName elementName, String language, T... values) throws SchemaException { -// Parser parser = getParserNotNull(language); -// PrismPropertyDefinition definition = schemaRegistry.findPropertyDefinitionByElementName(elementName); -// if (definition == null) { -// throw new SchemaException("Prism property with name " + elementName + " couldn't be found"); -// } -// PrismProperty property = definition.instantiate(); -// for (T value : values) { -// property.addRealValue(value); -// } -// RootXNode xroot = xnodeProcessor.serializeItemAsRoot(property); -// return parser.serializeToString(xroot); -// } - - @Deprecated - public Element serializeToDom(PrismObject object) throws SchemaException { - RootXNode xroot = xnodeProcessor.serializeObject(object); - return parserDom.serializeXRootToElement(xroot); - } + void setMonitor(PrismMonitor monitor); - @Deprecated - public Element serializeValueToDom(PrismValue pval, QName elementName) throws SchemaException { - RootXNode xroot = xnodeProcessor.serializeItemValueAsRoot(pval, elementName); - return parserDom.serializeXRootToElement(xroot); - } - - @Deprecated - public Element serializeValueToDom(PrismValue pval, QName elementName, Document document) throws SchemaException { - RootXNode xroot = xnodeProcessor.serializeItemValueAsRoot(pval, elementName); - return parserDom.serializeXRootToElement(xroot, document); - } - - - //endregion - - /** - * A bit of hack: serializes any Item into a RawType. - * Currently used for serializing script output, until a better method is devised. - * @return - */ - public RawType toRawType(Item item) throws SchemaException { - RootXNode rootXNode = xnodeProcessor.serializeItemAsRoot(item); - return new RawType(rootXNode, this); - } - - public PrismObject createObject(Class clazz) throws SchemaException { - PrismObjectDefinition definition = schemaRegistry.findObjectDefinitionByCompileTimeClass(clazz); - if (definition == null) { - throw new SchemaException("Definition for prism object holding " + clazz + " couldn't be found"); - } - return definition.instantiate(); - } - - public T createObjectable(Class clazz) throws SchemaException { - return createObject(clazz).asObjectable(); - } - protected ParsingContext newParsingContext() { - return ParsingContext.createDefault(); - } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java new file mode 100644 index 00000000000..495f3194fb8 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.crypto.Protector; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.marshaller.*; +import com.evolveum.midpoint.prism.lex.LexicalProcessor; +import com.evolveum.midpoint.prism.lex.LexicalProcessorRegistry; +import com.evolveum.midpoint.prism.lex.dom.DomLexicalProcessor; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; +import com.evolveum.midpoint.prism.polystring.PrismDefaultPolyStringNormalizer; +import com.evolveum.midpoint.prism.schema.SchemaDefinitionFactory; +import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.schema.SchemaRegistryImpl; +import com.evolveum.midpoint.prism.util.PrismMonitor; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author semancik + * + */ +public class PrismContextImpl implements PrismContext { + + private static final Trace LOGGER = TraceManager.getTrace(PrismContextImpl.class); + + private static boolean allowSchemalessSerialization = true; + private static boolean extraValidation = false; // TODO replace by something serious + + @NotNull private final SchemaRegistryImpl schemaRegistry; + @NotNull private final LexicalProcessorRegistry lexicalProcessorRegistry; + @NotNull private final PolyStringNormalizer defaultPolyStringNormalizer; // TODO make non-final when needed + @NotNull private final PrismUnmarshaller prismUnmarshaller; + @NotNull private final PrismMarshaller prismMarshaller; + @NotNull private final BeanMarshaller beanMarshaller; + @NotNull private final BeanUnmarshaller beanUnmarshaller; + private PrismMonitor monitor = null; + + private SchemaDefinitionFactory definitionFactory; + + @Autowired // TODO is this really applied? + private Protector defaultProtector; + + // We need to keep this because of deprecated methods and various hacks + @NotNull private final JaxbDomHack jaxbDomHack; + + //region Standard overhead + private PrismContextImpl(@NotNull SchemaRegistryImpl schemaRegistry) { + this.schemaRegistry = schemaRegistry; + schemaRegistry.setPrismContext(this); + this.lexicalProcessorRegistry = new LexicalProcessorRegistry(schemaRegistry); + this.prismUnmarshaller = new PrismUnmarshaller(this); + PrismBeanInspector inspector = new PrismBeanInspector(this); + this.beanMarshaller = new BeanMarshaller(this, inspector); + this.beanUnmarshaller = new BeanUnmarshaller(this, inspector); + this.prismMarshaller = new PrismMarshaller(beanMarshaller); + this.jaxbDomHack = new JaxbDomHack(lexicalProcessorRegistry.domProcessor(), this); + + defaultPolyStringNormalizer = new PrismDefaultPolyStringNormalizer(); + } + + public static PrismContextImpl create(@NotNull SchemaRegistryImpl schemaRegistry) { + return new PrismContextImpl(schemaRegistry); + } + + public static PrismContextImpl createEmptyContext(@NotNull SchemaRegistryImpl schemaRegistry) { + return new PrismContextImpl(schemaRegistry); + } + + @Override + public void initialize() throws SchemaException, SAXException, IOException { + schemaRegistry.initialize(); + } + + public static boolean isAllowSchemalessSerialization() { + return allowSchemalessSerialization; + } + + public static void setAllowSchemalessSerialization(boolean allowSchemalessSerialization) { + PrismContextImpl.allowSchemalessSerialization = allowSchemalessSerialization; + } + + public static boolean isExtraValidation() { + return extraValidation; + } + + public static void setExtraValidation(boolean extraValidation) { + PrismContextImpl.extraValidation = extraValidation; + } + + @Override + public XmlEntityResolver getEntityResolver() { + return schemaRegistry.getEntityResolver(); + } + + @NotNull + @Override + public SchemaRegistry getSchemaRegistry() { + return schemaRegistry; + } + + /** + * WARNING! This is not really public method. It should NOT not used outside the prism implementation. + */ + public PrismUnmarshaller getPrismUnmarshaller() { + return prismUnmarshaller; + } + + @NotNull + public PrismMarshaller getPrismMarshaller() { + return prismMarshaller; + } + + /** + * WARNING! This is not really public method. It should NOT not used outside the prism implementation. + */ + public DomLexicalProcessor getParserDom() { + return lexicalProcessorRegistry.domProcessor(); + } + + /** + * WARNING! This is not really public method. It should NOT not used outside the prism implementation. + */ + @NotNull + public BeanMarshaller getBeanMarshaller() { + return beanMarshaller; + } + + @NotNull + public BeanUnmarshaller getBeanUnmarshaller() { + return beanUnmarshaller; + } + + @NotNull + @Override + public JaxbDomHack getJaxbDomHack() { + return jaxbDomHack; + } + + @NotNull + public SchemaDefinitionFactory getDefinitionFactory() { + if (definitionFactory == null) { + definitionFactory = new SchemaDefinitionFactory(); + } + return definitionFactory; + } + + public void setDefinitionFactory(SchemaDefinitionFactory definitionFactory) { + this.definitionFactory = definitionFactory; + } + + @NotNull + @Override + public PolyStringNormalizer getDefaultPolyStringNormalizer() { + return defaultPolyStringNormalizer; + } + + private LexicalProcessor getParser(String language) { + return lexicalProcessorRegistry.processorFor(language); + } + + private LexicalProcessor getParserNotNull(String language) { + LexicalProcessor lexicalProcessor = getParser(language); + if (lexicalProcessor == null) { + throw new SystemException("No parser for language '"+language+"'"); + } + return lexicalProcessor; + } + + @Override + public Protector getDefaultProtector() { + return defaultProtector; + } + + public void setDefaultProtector(Protector defaultProtector) { + this.defaultProtector = defaultProtector; + } + + @Override + public PrismMonitor getMonitor() { + return monitor; + } + + @Override + public void setMonitor(PrismMonitor monitor) { + this.monitor = monitor; + } + + //endregion + + //region Parsing + @NotNull + @Override + public PrismParser parserFor(@NotNull File file) { + return new PrismParserImplIO(new ParserFileSource(file), null, ParsingContext.createDefault(), this, null, null, null, null); + } + + @NotNull + @Override + public PrismParser parserFor(@NotNull InputStream stream) { + return new PrismParserImplIO(new ParserInputStreamSource(stream), null, ParsingContext.createDefault(), this, null, null, null, null); + } + + @NotNull + @Override + public PrismParserNoIO parserFor(@NotNull String data) { + return new PrismParserImplNoIO(new ParserStringSource(data), null, ParsingContext.createDefault(), this, null, null, null, null); + } + + @NotNull + @Override + public PrismParserNoIO parserFor(@NotNull RootXNode xnode) { + return new PrismParserImplNoIO(new ParserXNodeSource(xnode), null, ParsingContext.createDefault(), this, null, null, null, null); + } + + @NotNull + @Deprecated + @Override + public PrismParserNoIO parserFor(@NotNull Element data) { + return new PrismParserImplNoIO(new ParserElementSource(data), null, ParsingContext.createDefault(), this, null, null, null, null); + } + //endregion + + //region adopt(...) methods + /** + * Set up the specified object with prism context instance and schema definition. + */ + @Override + public void adopt(PrismContainer container, Class declaredType) throws SchemaException { + container.revive(this); + getSchemaRegistry().applyDefinition(container, declaredType, false); + } + + @Override + public void adopt(PrismContainer container) throws SchemaException { + adopt(container, container.getCompileTimeClass()); + } + + @Override + public void adopt(Objectable objectable) throws SchemaException { + adopt(objectable.asPrismObject(), objectable.getClass()); + } + + @Override + public void adopt(Containerable containerable) throws SchemaException { + containerable.asPrismContainerValue().revive(this); + } + + @Override + public void adopt(PrismContainerValue value) throws SchemaException { + value.revive(this); + } + + @Override + public void adopt(ObjectDelta delta) throws SchemaException { + delta.revive(this); + getSchemaRegistry().applyDefinition(delta, delta.getObjectTypeClass(), false); + } + + @Override + public void adopt(C containerable, Class type, ItemPath path) throws SchemaException { + PrismContainerValue prismContainerValue = containerable.asPrismContainerValue(); + adopt(prismContainerValue, type, path); + } + + @Override + public void adopt(PrismContainerValue prismContainerValue, Class type, + ItemPath path) throws SchemaException { + prismContainerValue.revive(this); + getSchemaRegistry().applyDefinition(prismContainerValue, type, path, false); + } + + @Override + public void adopt(PrismContainerValue prismContainerValue, QName typeName, + ItemPath path) throws SchemaException { + prismContainerValue.revive(this); + getSchemaRegistry().applyDefinition(prismContainerValue, typeName, path, false); + } + //endregion + + //region Serializing objects, containers, atomic values (properties) + @Override + public String serializeObjectToString(PrismObject object, String language) throws SchemaException { + return serializerFor(language).serialize(object); + } + + @NotNull + @Override + public PrismSerializer serializerFor(@NotNull String language) { + return new PrismSerializerImpl<>(new SerializerStringTarget(this, language), null, null, null, this); + } + + @NotNull + @Override + public PrismSerializer xmlSerializer() { + return serializerFor(LANG_XML); + } + + @NotNull + @Override + public PrismSerializer jsonSerializer() { + return serializerFor(LANG_JSON); + } + + @NotNull + @Override + public PrismSerializer yamlSerializer() { + return serializerFor(LANG_YAML); + } + + @NotNull + @Override + public PrismSerializer domSerializer() { + return new PrismSerializerImpl<>(new SerializerDomTarget(this), null, null, null, this); + } + + @NotNull + @Override + public PrismSerializer xnodeSerializer() { + return new PrismSerializerImpl<>(new SerializerXNodeTarget(this), null, null, null, this); + } + + @Override + public boolean canSerialize(Object value) { + return prismMarshaller.canSerialize(value); + } + + //endregion + + + @NotNull + @Override + public PrismObject createObject(@NotNull Class clazz) throws SchemaException { + PrismObjectDefinition definition = schemaRegistry.findObjectDefinitionByCompileTimeClass(clazz); + if (definition == null) { + throw new SchemaException("Definition for prism object holding " + clazz + " couldn't be found"); + } + return definition.instantiate(); + } + + @NotNull + @Override + public T createObjectable(@NotNull Class clazz) throws SchemaException { + return createObject(clazz).asObjectable(); + } + + @NotNull + public LexicalProcessorRegistry getLexicalProcessorRegistry() { + return lexicalProcessorRegistry; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObject.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObject.java index f3bfe9e93f4..e8bd2029068 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObject.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObject.java @@ -83,6 +83,7 @@ public String getOid() { } public void setOid(String oid) { + checkMutability(); this.oid = oid; } @@ -91,6 +92,7 @@ public String getVersion() { } public void setVersion(String version) { + checkMutability(); this.version = version; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinition.java index 4a19f653c49..7ac57079dd2 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinition.java @@ -16,129 +16,30 @@ package com.evolveum.midpoint.prism; -import javax.xml.namespace.QName; - import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; /** - * MidPoint Object Definition. - * - * Objects are storable entities in midPoint. - * - * This is mostly just a marker class to identify object boundaries in schema. - * - * This class represents schema definition for objects. See {@link Definition} - * for more details. - * - * "Instance" class of this class is MidPointObject, not Object - to avoid - * confusion with java.lang.Object. - * - * @author Radovan Semancik - * + * @author mederly */ -public class PrismObjectDefinition extends PrismContainerDefinition { - private static final long serialVersionUID = -8298581031956931008L; +public interface PrismObjectDefinition extends PrismContainerDefinition { - public PrismObjectDefinition(QName elementName, ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext, - Class compileTimeClass) { - // Object definition can only be top-level, hence null parent - super(elementName, complexTypeDefinition, prismContext, compileTimeClass); - } - - @Override - public PrismObject instantiate() throws SchemaException { - if (isAbstract()) { - throw new SchemaException("Cannot instantiate abstract definition "+this); - } - PrismObject midPointObject = new PrismObject(getName(), this, prismContext); - return midPointObject; - } - @Override - public PrismObject instantiate(QName name) throws SchemaException { - if (isAbstract()) { - throw new SchemaException("Cannot instantiate abstract definition "+this); - } - name = addNamespaceIfApplicable(name); - PrismObject midPointObject = new PrismObject(name, this, prismContext); - return midPointObject; - } - - public PrismObjectDefinition clone() { - PrismObjectDefinition clone = new PrismObjectDefinition(name, complexTypeDefinition, prismContext, compileTimeClass); - copyDefinitionData(clone); - return clone; - } - - @Override - public PrismObjectDefinition deepClone(boolean ultraDeep) { - return (PrismObjectDefinition) super.deepClone(ultraDeep); - } - - public PrismObjectDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) { - return (PrismObjectDefinition) super.cloneWithReplacedDefinition(itemName, newDefinition); - } - - public PrismContainerDefinition getExtensionDefinition() { - return findContainerDefinition(getExtensionQName()); - } + @NotNull + PrismObject instantiate() throws SchemaException; - public void setExtensionDefinition(ComplexTypeDefinition extensionComplexTypeDefinition) { - QName extensionQName = getExtensionQName(); - - PrismContainerDefinition oldExtensionDef = findContainerDefinition(extensionQName); - - PrismContainerDefinition newExtensionDef = new PrismContainerDefinition(extensionQName, - extensionComplexTypeDefinition, prismContext); - newExtensionDef.setRuntimeSchema(true); - if (oldExtensionDef != null) { - if (newExtensionDef.getDisplayName() == null) { - newExtensionDef.setDisplayName(oldExtensionDef.getDisplayName()); - } - if (newExtensionDef.getDisplayOrder() == null) { - newExtensionDef.setDisplayOrder(oldExtensionDef.getDisplayOrder()); - } - if (newExtensionDef.getHelp() == null) { - newExtensionDef.setHelp(oldExtensionDef.getHelp()); - } - } - - ComplexTypeDefinition newCtd = this.complexTypeDefinition.clone(); - newCtd.replaceDefinition(extensionQName, newExtensionDef); - if (newCtd.getDisplayName() == null) { - newCtd.setDisplayName(this.complexTypeDefinition.getDisplayName()); - } - if (newCtd.getDisplayOrder() == null) { - newCtd.setDisplayOrder(this.complexTypeDefinition.getDisplayOrder()); - } - if (newCtd.getHelp() == null) { - newCtd.setHelp(this.complexTypeDefinition.getHelp()); - } + @Override + PrismObject instantiate(QName name) throws SchemaException; - this.complexTypeDefinition = newCtd; - } - - private QName getExtensionQName() { - String namespace = getName().getNamespaceURI(); - return new QName(namespace, PrismConstants.EXTENSION_LOCAL_NAME); - } - - public I getExtensionItemDefinition(QName elementName) { - PrismContainerDefinition extensionDefinition = getExtensionDefinition(); - if (extensionDefinition == null) { - return null; - } - return (I) extensionDefinition.findItemDefinition(elementName); - } + @NotNull + PrismObjectDefinition clone(); @Override - protected String getDebugDumpClassName() { - return "POD"; - } + PrismObjectDefinition deepClone(boolean ultraDeep); + + PrismObjectDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition); - @Override - public String getDocClassName() { - return "object"; - } - + PrismContainerDefinition getExtensionDefinition(); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinitionImpl.java new file mode 100644 index 00000000000..2e29b5792cf --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismObjectDefinitionImpl.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; + +/** + * MidPoint Object Definition. + * + * Objects are storable entities in midPoint. + * + * This is mostly just a marker class to identify object boundaries in schema. + * + * This class represents schema definition for objects. See {@link Definition} + * for more details. + * + * "Instance" class of this class is MidPointObject, not Object - to avoid + * confusion with java.lang.Object. + * + * @author Radovan Semancik + * + */ +public class PrismObjectDefinitionImpl extends PrismContainerDefinitionImpl implements + PrismObjectDefinition { + private static final long serialVersionUID = -8298581031956931008L; + + public PrismObjectDefinitionImpl(QName elementName, ComplexTypeDefinition complexTypeDefinition, PrismContext prismContext, + Class compileTimeClass) { + // Object definition can only be top-level, hence null parent + super(elementName, complexTypeDefinition, prismContext, compileTimeClass); + } + + @Override + @NotNull + public PrismObject instantiate() throws SchemaException { + if (isAbstract()) { + throw new SchemaException("Cannot instantiate abstract definition "+this); + } + return new PrismObject(getName(), this, prismContext); + } + + @Override + public PrismObject instantiate(QName name) throws SchemaException { + if (isAbstract()) { + throw new SchemaException("Cannot instantiate abstract definition "+this); + } + name = addNamespaceIfApplicable(name); + PrismObject midPointObject = new PrismObject(name, this, prismContext); + return midPointObject; + } + + @NotNull + @Override + public PrismObjectDefinitionImpl clone() { + PrismObjectDefinitionImpl clone = new PrismObjectDefinitionImpl<>(name, complexTypeDefinition, prismContext, compileTimeClass); + copyDefinitionData(clone); + return clone; + } + + @Override + public PrismObjectDefinition deepClone(boolean ultraDeep) { + return (PrismObjectDefinition) super.deepClone(ultraDeep); + } + + @Override + public PrismObjectDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) { + return (PrismObjectDefinition) super.cloneWithReplacedDefinition(itemName, newDefinition); + } + + @Override + public PrismContainerDefinition getExtensionDefinition() { + return findContainerDefinition(getExtensionQName()); + } + + public void setExtensionDefinition(ComplexTypeDefinition extensionComplexTypeDefinition) { + QName extensionQName = getExtensionQName(); + + PrismContainerDefinition oldExtensionDef = findContainerDefinition(extensionQName); + + PrismContainerDefinitionImpl newExtensionDef = new PrismContainerDefinitionImpl<>(extensionQName, + extensionComplexTypeDefinition, prismContext); + newExtensionDef.setRuntimeSchema(true); + if (oldExtensionDef != null) { + if (newExtensionDef.getDisplayName() == null) { + newExtensionDef.setDisplayName(oldExtensionDef.getDisplayName()); + } + if (newExtensionDef.getDisplayOrder() == null) { + newExtensionDef.setDisplayOrder(oldExtensionDef.getDisplayOrder()); + } + if (newExtensionDef.getHelp() == null) { + newExtensionDef.setHelp(oldExtensionDef.getHelp()); + } + } + + ComplexTypeDefinitionImpl newCtd = (ComplexTypeDefinitionImpl) this.complexTypeDefinition.clone(); + newCtd.replaceDefinition(extensionQName, newExtensionDef); + if (newCtd.getDisplayName() == null) { + newCtd.setDisplayName(this.complexTypeDefinition.getDisplayName()); + } + if (newCtd.getDisplayOrder() == null) { + newCtd.setDisplayOrder(this.complexTypeDefinition.getDisplayOrder()); + } + if (newCtd.getHelp() == null) { + newCtd.setHelp(this.complexTypeDefinition.getHelp()); + } + + this.complexTypeDefinition = newCtd; + } + + private QName getExtensionQName() { + String namespace = getName().getNamespaceURI(); + return new QName(namespace, PrismConstants.EXTENSION_LOCAL_NAME); + } + + public I getExtensionItemDefinition(QName elementName) { + PrismContainerDefinition extensionDefinition = getExtensionDefinition(); + if (extensionDefinition == null) { + return null; + } + return (I) extensionDefinition.findItemDefinition(elementName); + } + + @Override + protected String getDebugDumpClassName() { + return "POD"; + } + + @Override + public String getDocClassName() { + return "object"; + } + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismParser.java new file mode 100644 index 00000000000..4ebf40df53f --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismParser.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; +import java.io.IOException; +import java.util.List; + +/** + * Parses a given input into prism or POJO objects. + * + * The interface is pretty straightforward; only two things are of interest: + * 1. how to determine the type of data to be retrieved, + * 2. how to determine the name of the item that is to be created (in case of prism items). + * + * For most cases, both can be determined from the input. E.g. if we are parsing a prism object that is rooted at the + * "user" XML element, it is clear that the type is c:UserType and the name is c:user. In other cases, the algorithms + * are the following: + * + * Data type determination: We collect all the available data, i.e. + * - explicit type specification in source data (xsi:type/@type), + * - itemDefinition provided by the caller, + * - item name in source data, + * - itemName provided by the caller, + * - typeName provided by the caller, + * - typeClass provided by the caller + * and take the most specific of these. In case of conflict we report an error. + * + * Data name determination: First name that is present takes precedence: + * 1. itemName + * 2. source data (if namespace is missing, it is filled from item definition) + * 3. name from itemDefinition + * 4. name from item definition derived from type name + * 5. name from item definition derived from type class + * + * General post-conditions: (For items as well as item values; and for all parsing methods.) + * - All recognizable definitions are set. + * - Prism context is set on all items and PCVs. + * - No unresolved raw values with known types are present. + * + * @author mederly + */ +public interface PrismParser { + + /** + * For string inputs: sets the data language that the parser will try to parse; null means auto-detect. + * For other kinds of input (DOM and XNode) the language is fixed to XML or none, respectively. + * + * @param language The language + * @return Updated parser. + */ + @NotNull + PrismParser language(@Nullable String language); + + /** + * Sets the language of the parser to be XML. + * @return Updated parser. + */ + @NotNull + PrismParser xml(); + + /** + * Sets the language of the parser to be JSON. + * @return Updated parser. + */ + @NotNull + PrismParser json(); + + /** + * Sets the language of the parser to be YAML. + * @return Updated parser. + */ + @NotNull + PrismParser yaml(); + + /** + * Provides a parsing context for the parser. The context contains e.g. selection of strict/compat + * mode of operation (set by client) or a list of warnings (maintained by the parser). + * @param context The parsing context. + * @return Updated parser. + */ + @NotNull + PrismParser context(@NotNull ParsingContext context); + + /** + * Switches the parser into "strict" parsing mode. + * @return Updated parser. + */ + @NotNull + PrismParser strict(); + + /** + * Switches the parser into "compatibility" (or relaxed) parsing mode. + * TODO description here + * @return Updated parser. + */ + @NotNull + PrismParser compat(); + + /** + * Tells parser which definition to use when parsing item (or an item value). Optional. + * @param itemDefinition The definition + * @return Updated parser. + */ + @NotNull + PrismParser definition(ItemDefinition itemDefinition); + + /** + * Tells parser what data type to expect. Optional. + * @param typeName Data type to expect. + * @return Updated parser. + */ + @NotNull + PrismParser type(QName typeName); + + /** + * Tells parser what data type to expect. Optional. + * @param typeClass Data type to expect. + * @return Updated parser. + */ + @NotNull + PrismParser type(Class typeClass); + + /** + * Tells parser what name to use for parsed item. Optional. + * @param itemName Item name to use. + * @return Updated parser. + */ + @NotNull + PrismParser name(QName itemName); + + /** + * Parses the input as a prism object. + * @return The object. + */ + @NotNull + PrismObject parse() throws SchemaException, IOException; + + /** + * Parses the input as a prism item. (Object, container, reference, value.) + * May return raw property values as part of the prism structure, if definitions are not known. + * @return The item. + */ + Item parseItem() throws SchemaException, IOException; + + /** + * Parses the input as a prism value. (Container value, reference value, property value.) + * May return raw property values as part of the prism structure, if definitions are not known. + * @return The item. + */ + IV parseItemValue() throws SchemaException, IOException; + + /** + * Parses a real value - either property or container value. + * @param clazz Expected class of the data. May be null if unknown. + * @return Real value - POJO, Containerable, Objectable or Referencable. + */ + T parseRealValue(@Nullable Class clazz) throws IOException, SchemaException; + + /** + * Parses a real value. The class is not supplied by the caller, so it has to be determined from the data source. + * @return Real value - POJO, Containerable, Objectable or Referencable. + */ + T parseRealValue() throws IOException, SchemaException; + + /** + * Parses a real value and stores it into JAXBElement, using item name derived in the usual way. + */ + JAXBElement parseRealValueToJaxbElement() throws IOException, SchemaException; + + /** + * Parses the input into RootXNode. This is a bit unusual approach, skipping the unmarshalling phase altogether. + * But it is useful at some places. + * @return RootXNode corresponding to the input. + */ + RootXNode parseToXNode() throws IOException, SchemaException; + + /** + * Parses either an item, or a real value. It depends on the type declaration or item name in the source data. + * 1) If explicit type is present, it is taken into account. If it corresponds to a prism item, the input is parsed + * as a prism item. Otherwise, it is parsed as a real value (containerable or simple POJO), if possible. + * 2) If there is no type, the item name is consulted. If it corresponds to a prism item, the input is parsed + * as a prism item. Otherwise, an exception is thrown. + * + * Pre-set parameters (itemDefinition, typeName, itemName) must NOT be present. + * + * Use with utmost care. If at all possible, avoid it. + * + * @return either prism item (Item) or a real value (Object) + */ + Object parseItemOrRealValue() throws IOException, SchemaException; + + + + // ============= other methods (convenience ones, deprecated ones etc) ============= + + /** + * Parses the input as a collection of prism objects. + * Currently supported only for XML. (For the time being, it is used only in tests.) + * @return A list of objects. + */ + @NotNull + List> parseObjects() throws SchemaException, IOException; + +// /** +// * Parses the input as a single value of a prism container. +// * @return Single-valued container. +// */ +// @NotNull +// PrismContainer parseContainer() throws SchemaException, IOException; + +// /** +// * Parses an atomic value - i.e. something that could present a property +// * value, if such a property would exist. +// */ +// T parseAtomicValue(QName typeName) throws IOException, SchemaException; + + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismParserNoIO.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismParserNoIO.java new file mode 100644 index 00000000000..7b5b895c60c --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismParserNoIO.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; +import java.util.List; + +/** + * The same as PrismParser but has no IOException on parseXYZ methods. It is used when parsing from strings or DOM structures + * where no IOExceptions occur. + * + * For methods' descriptions please see the parent interface (PrismParser). + * + * @author mederly + */ +public interface PrismParserNoIO extends PrismParser { + + @NotNull + PrismParserNoIO language(@Nullable String language); + @NotNull + PrismParserNoIO xml(); + @NotNull + PrismParserNoIO json(); + @NotNull + PrismParserNoIO yaml(); + @NotNull + PrismParserNoIO context(@NotNull ParsingContext context); + @NotNull + PrismParserNoIO strict(); + @NotNull + PrismParserNoIO compat(); + @NotNull + PrismParserNoIO definition(ItemDefinition itemDefinition); + @NotNull + PrismParserNoIO name(QName itemName); + @NotNull + PrismParserNoIO type(QName typeName); + @NotNull + PrismParserNoIO type(Class typeClass); + + @NotNull + PrismObject parse() throws SchemaException; + Item parseItem() throws SchemaException; + IV parseItemValue() throws SchemaException; + T parseRealValue(Class clazz) throws SchemaException; + T parseRealValue() throws SchemaException; + JAXBElement parseRealValueToJaxbElement() throws SchemaException; + RootXNode parseToXNode() throws SchemaException; + Object parseItemOrRealValue() throws SchemaException; + + // auxiliary methods + @NotNull + List> parseObjects() throws SchemaException; + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java index 116680adf77..ba36fc75e2c 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java @@ -19,13 +19,19 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.xnode.ListXNode; import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; @@ -91,30 +97,21 @@ public PrismPropertyDefinition getDefinition() { /** * Sets applicable property definition. * + * TODO remove (method in Item is sufficient) * @param definition the definition to set */ public void setDefinition(PrismPropertyDefinition definition) { + checkMutability(); this.definition = definition; } - /** - * Returns property values. - *

- * The values are returned as set. The order of values is not significant. - * - * @return property values - */ - public List> getValues() { - return (List>) super.getValues(); - } - public PrismPropertyValue getValue() { if (!isSingleValue()) { throw new IllegalStateException("Attempt to get single value from property " + getElementName() + " with multiple values"); } List> values = getValues(); - if (values == null || values.isEmpty()) { + if (values.isEmpty()) { return null; } return values.get(0); @@ -228,7 +225,7 @@ public PrismPropertyValue getValue(Class type) { * Will remove all existing values. */ public void setValue(PrismPropertyValue value) { - getValues().clear(); + clear(); addValue(value); } @@ -251,7 +248,8 @@ public void addValues(Collection> pValuesToAdd) { } public void addValue(PrismPropertyValue pValueToAdd) { - pValueToAdd.checkValue(); + checkMutability(); + pValueToAdd.checkValue(); Iterator> iterator = getValues().iterator(); while (iterator.hasNext()) { PrismPropertyValue pValue = iterator.next(); @@ -271,7 +269,8 @@ public void addRealValue(T valueToAdd) { } public boolean deleteValues(Collection> pValuesToDelete) { - boolean changed = false; + checkMutability(); + boolean changed = false; for (PrismPropertyValue pValue: pValuesToDelete) { if (!changed) { changed = deleteValue(pValue); @@ -283,7 +282,8 @@ public boolean deleteValues(Collection> pValuesToDelete) { } public boolean deleteValue(PrismPropertyValue pValueToDelete) { - Iterator> iterator = getValues().iterator(); + checkMutability(); + Iterator> iterator = getValues().iterator(); boolean found = false; while (iterator.hasNext()) { PrismPropertyValue pValue = iterator.next(); @@ -301,7 +301,7 @@ public boolean deleteValue(PrismPropertyValue pValueToDelete) { } public void replaceValues(Collection> valuesToReplace) { - getValues().clear(); + clear(); addValues(valuesToReplace); } @@ -405,7 +405,7 @@ public static PropertyDelta diff(PrismProperty a, PrismProperty b) @Override protected void checkDefinition(PrismPropertyDefinition def) { - if (!(def instanceof PrismPropertyDefinition)) { + if (def == null) { throw new IllegalArgumentException("Definition "+def+" cannot be applied to property "+this); } } @@ -572,7 +572,7 @@ public String debugDump(int indent) { if (def != null && DebugUtil.isDetailedDebugDump()) { sb.append(" def("); - def.debugDumpShortToString(sb); + ((PrismPropertyDefinitionImpl) def).debugDumpShortToString(sb); // if (def.isIndexed() != null) { // sb.append(def.isIndexed() ? ",i+" : ",i-"); // } @@ -620,4 +620,17 @@ protected String getDebugDumpClassName() { return "PP"; } + public static PrismProperty createRaw(@NotNull XNode node, @NotNull QName itemName, @NotNull PrismContext prismContext) + throws SchemaException { + Validate.isTrue(!(node instanceof RootXNode)); + PrismProperty property = new PrismProperty<>(itemName, prismContext); + if (node instanceof ListXNode) { + for (XNode subnode : (ListXNode) node) { + property.add(PrismPropertyValue.createRaw(subnode)); + } + } else { + property.add(PrismPropertyValue.createRaw(node)); + } + return property; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinition.java index 9289490d58e..287d5fed7eb 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinition.java @@ -16,222 +16,57 @@ package com.evolveum.midpoint.prism; -import java.util.Collection; - -import javax.xml.namespace.QName; - import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DisplayableValue; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.Collection; /** - * Property Definition. - *

- * Property is a basic unit of information in midPoint. This class provides - * definition of property type, multiplicity and so on. - *

- * Property is a specific characteristic of an object. It may be considered - * object "attribute" or "field". For example User has fullName property that - * contains string value of user's full name. - *

- * Properties may be single-valued or multi-valued - *

- * Properties may contain primitive types or complex types (defined by XSD - * schema) - *

- * Property values are unordered, implementation may change the order of values - *

- * Duplicate values of properties should be silently removed by implementations, - * but clients must be able tolerate presence of duplicate values. - *

- * Operations that modify the objects work with the granularity of properties. - * They add/remove/replace the values of properties, but do not "see" inside the - * property. - *

- * This class represents schema definition for property. See {@link Definition} - * for more details. - * - * @author Radovan Semancik + * @author mederly */ -public class PrismPropertyDefinition extends ItemDefinition> { +public interface PrismPropertyDefinition extends ItemDefinition> { + Collection> getAllowedValues(); - private static final long serialVersionUID = 7259761997904371009L; - private QName valueType; - private Collection> allowedValues; - private Boolean indexed = null; - private T defaultValue; - private QName matchingRuleQName = null; - - public PrismPropertyDefinition(QName elementName, QName typeName, PrismContext prismContext) { - super(elementName, typeName, prismContext); - } - - public PrismPropertyDefinition(QName elementName, QName typeName, PrismContext prismContext, Collection> allowedValues, T defaultValue) { - super(elementName, typeName, prismContext); - this.allowedValues = allowedValues; - this.defaultValue = defaultValue; - } - - /** - * Returns allowed values for this property. - * - * @return Object array. May be null. - */ - public Collection> getAllowedValues() { - return allowedValues; - } - - public T defaultValue(){ - return defaultValue; - } - /** - * Returns QName of the property value type. - *

- * The returned type is either XSD simple type or complex type. It may not - * be defined in the same schema (especially if it is standard XSD simple - * type). - * - * @return QName of the property value type - */ - public QName getValueType() { - return valueType; - } - - void setValueType(QName valueType) { - this.valueType = valueType; - } - - /** - * This is XSD annotation that specifies whether a property should - * be indexed in the storage. It can only apply to properties. It - * has following meaning: - * - * true: the property must be indexed. If the storage is not able to - * index the value, it should indicate an error. - * - * false: the property should not be indexed. - * - * null: data store decides whether to index the property or - * not. - */ - public Boolean isIndexed() { - return indexed; - } - - public void setIndexed(Boolean indexed) { - this.indexed = indexed; - } + T defaultValue(); /** - * Returns matching rule name. Matching rules are algorithms that specify - * how to compare, normalize and/or order the values. E.g. there are matching - * rules for case insensitive string comparison, for LDAP DNs, etc. - * - * @return matching rule name + * Returns QName of the property value type. + *

+ * The returned type is either XSD simple type or complex type. It may not + * be defined in the same schema (especially if it is standard XSD simple + * type). + * + * @return QName of the property value type + * + * NOTE: This is very strange property. Isn't it the same as typeName(). + * It is even not used in midPoint. Marking as deprecated. */ - public QName getMatchingRuleQName() { - return matchingRuleQName; - } - - public void setMatchingRuleQName(QName matchingRuleQName) { - this.matchingRuleQName = matchingRuleQName; - } - - @Override - public PrismProperty instantiate() { - return instantiate(getName()); - } - - @Override - public PrismProperty instantiate(QName name) { - name = addNamespaceIfApplicable(name); - return new PrismProperty(name, this, prismContext); - } + @Deprecated + QName getValueType(); - @Override - public PropertyDelta createEmptyDelta(ItemPath path) { - return new PropertyDelta(path, this, prismContext); - } + Boolean isIndexed(); - @Override - public PrismPropertyDefinition clone() { - PrismPropertyDefinition clone = new PrismPropertyDefinition(getName(), getTypeName(), getPrismContext()); - copyDefinitionData(clone); - return clone; + default boolean isAnyType() { + return DOMUtil.XSD_ANYTYPE.equals(getTypeName()); } - protected void copyDefinitionData(PrismPropertyDefinition clone) { - super.copyDefinitionData(clone); - clone.indexed = this.indexed; - clone.defaultValue = this.defaultValue; - clone.allowedValues = this.allowedValues; - clone.valueType = this.valueType; - } + QName getMatchingRuleQName(); - @Override - protected void extendToString(StringBuilder sb) { - super.extendToString(sb); - if (indexed != null && indexed) { - sb.append(",I"); - } - if (allowedValues != null && !allowedValues.isEmpty()) { - sb.append(",AVals:").append(allowedValues.size()); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((allowedValues == null) ? 0 : allowedValues.hashCode()); - result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode()); - result = prime * result + ((indexed == null) ? 0 : indexed.hashCode()); - result = prime * result + ((valueType == null) ? 0 : valueType.hashCode()); - return result; - } + @Override + PropertyDelta createEmptyDelta(ItemPath path); @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - PrismPropertyDefinition other = (PrismPropertyDefinition) obj; - if (allowedValues == null) { - if (other.allowedValues != null) - return false; - } else if (!allowedValues.equals(other.allowedValues)) - return false; - if (defaultValue == null) { - if (other.defaultValue != null) - return false; - } else if (!defaultValue.equals(other.defaultValue)) - return false; - if (indexed == null) { - if (other.indexed != null) - return false; - } else if (!indexed.equals(other.indexed)) - return false; - if (valueType == null) { - if (other.valueType != null) - return false; - } else if (!valueType.equals(other.valueType)) - return false; - return true; - } + PrismProperty instantiate(); - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "PPD"; - } + @Override + PrismProperty instantiate(QName name); - @Override - public String getDocClassName() { - return "property"; - } + @NotNull + @Override + PrismPropertyDefinition clone(); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinitionImpl.java new file mode 100644 index 00000000000..349389f15c0 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyDefinitionImpl.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import java.util.Collection; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.delta.PropertyDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.util.DisplayableValue; +import org.jetbrains.annotations.NotNull; + +/** + * Property Definition. + *

+ * Property is a basic unit of information in midPoint. This class provides + * definition of property type, multiplicity and so on. + *

+ * Property is a specific characteristic of an object. It may be considered + * object "attribute" or "field". For example User has fullName property that + * contains string value of user's full name. + *

+ * Properties may be single-valued or multi-valued + *

+ * Properties may contain primitive types or complex types (defined by XSD + * schema) + *

+ * Property values are unordered, implementation may change the order of values + *

+ * Duplicate values of properties should be silently removed by implementations, + * but clients must be able tolerate presence of duplicate values. + *

+ * Operations that modify the objects work with the granularity of properties. + * They add/remove/replace the values of properties, but do not "see" inside the + * property. + *

+ * This class represents schema definition for property. See {@link Definition} + * for more details. + * + * @author Radovan Semancik + */ +public class PrismPropertyDefinitionImpl extends ItemDefinitionImpl> implements PrismPropertyDefinition { + + private static final long serialVersionUID = 7259761997904371009L; + private QName valueType; + private Collection> allowedValues; + private Boolean indexed = null; + private T defaultValue; + private QName matchingRuleQName = null; + + public PrismPropertyDefinitionImpl(QName elementName, QName typeName, PrismContext prismContext) { + super(elementName, typeName, prismContext); + } + + public PrismPropertyDefinitionImpl(QName elementName, QName typeName, PrismContext prismContext, Collection> allowedValues, T defaultValue) { + super(elementName, typeName, prismContext); + this.allowedValues = allowedValues; + this.defaultValue = defaultValue; + } + + /** + * Returns allowed values for this property. + * + * @return Object array. May be null. + */ + @Override + public Collection> getAllowedValues() { + return allowedValues; + } + + @Override + public T defaultValue(){ + return defaultValue; + } + + @Override + public QName getValueType() { + return valueType; + } + + /** + * This is XSD annotation that specifies whether a property should + * be indexed in the storage. It can only apply to properties. It + * has following meaning: + * + * true: the property must be indexed. If the storage is not able to + * index the value, it should indicate an error. + * + * false: the property should not be indexed. + * + * null: data store decides whether to index the property or + * not. + */ + @Override + public Boolean isIndexed() { + return indexed; + } + + public void setIndexed(Boolean indexed) { + this.indexed = indexed; + } + + /** + * Returns matching rule name. Matching rules are algorithms that specify + * how to compare, normalize and/or order the values. E.g. there are matching + * rules for case insensitive string comparison, for LDAP DNs, etc. + * + * @return matching rule name + */ + @Override + public QName getMatchingRuleQName() { + return matchingRuleQName; + } + + public void setMatchingRuleQName(QName matchingRuleQName) { + this.matchingRuleQName = matchingRuleQName; + } + + @Override + public PrismProperty instantiate() { + return instantiate(getName()); + } + + @Override + public PrismProperty instantiate(QName name) { + name = addNamespaceIfApplicable(name); + return new PrismProperty(name, this, prismContext); + } + + @Override + public PropertyDelta createEmptyDelta(ItemPath path) { + return new PropertyDelta(path, this, prismContext); + } + + @NotNull + @Override + public PrismPropertyDefinition clone() { + PrismPropertyDefinitionImpl clone = new PrismPropertyDefinitionImpl(getName(), getTypeName(), getPrismContext()); + copyDefinitionData(clone); + return clone; + } + + protected void copyDefinitionData(PrismPropertyDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.indexed = this.indexed; + clone.defaultValue = this.defaultValue; + clone.allowedValues = this.allowedValues; + clone.valueType = this.valueType; + } + + @Override + protected void extendToString(StringBuilder sb) { + super.extendToString(sb); + if (indexed != null && indexed) { + sb.append(",I"); + } + if (allowedValues != null && !allowedValues.isEmpty()) { + sb.append(",AVals:").append(allowedValues.size()); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((allowedValues == null) ? 0 : allowedValues.hashCode()); + result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode()); + result = prime * result + ((indexed == null) ? 0 : indexed.hashCode()); + result = prime * result + ((valueType == null) ? 0 : valueType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + PrismPropertyDefinitionImpl other = (PrismPropertyDefinitionImpl) obj; + if (allowedValues == null) { + if (other.allowedValues != null) + return false; + } else if (!allowedValues.equals(other.allowedValues)) + return false; + if (defaultValue == null) { + if (other.defaultValue != null) + return false; + } else if (!defaultValue.equals(other.defaultValue)) + return false; + if (indexed == null) { + if (other.indexed != null) + return false; + } else if (!indexed.equals(other.indexed)) + return false; + if (valueType == null) { + if (other.valueType != null) + return false; + } else if (!valueType.equals(other.valueType)) + return false; + return true; + } + + /** + * Return a human readable name of this class suitable for logs. + */ + @Override + protected String getDebugDumpClassName() { + return "PPD"; + } + + @Override + public String getDocClassName() { + return "property"; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java index 9caf074810c..009680b6c5f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java @@ -17,15 +17,13 @@ package com.evolveum.midpoint.prism; +import com.evolveum.midpoint.prism.marshaller.BeanMarshaller; import com.evolveum.midpoint.prism.match.MatchingRule; -import com.evolveum.midpoint.prism.parser.XNodeProcessor; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; -import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.prism.util.PrismUtil; -import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugDumpable; @@ -44,6 +42,7 @@ import java.util.Comparator; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.Nullable; import org.jvnet.jaxb2_commons.lang.Equals; import org.w3c.dom.Element; @@ -56,8 +55,8 @@ public class PrismPropertyValue extends PrismValue implements DebugDumpable, Serializable { private T value; - // The rawElement is set during a schema-less parsing, e.g. during a dumb JAXB parsing or XML parsing without a - // definition. + + // The rawElement is set during a schema-less parsing, e.g. during parsing without a definition. // We can't do anything smarter, as we don't have definition nor prism context. So we store the raw // elements here and process them later (e.g. during applyDefinition or getting a value with explicit type). private XNode rawElement; @@ -66,8 +65,16 @@ public PrismPropertyValue(T value) { this(value, null, null); } + public PrismPropertyValue(T value, PrismContext prismContext) { + this(value, prismContext, null, null); + } + public PrismPropertyValue(T value, OriginType type, Objectable source) { - super(type,source); + this(value, null, type, source); + } + + public PrismPropertyValue(T value, PrismContext prismContext, OriginType type, Objectable source) { + super(type, source); if (value instanceof PrismPropertyValue) { throw new IllegalArgumentException("Probably problem somewhere, encapsulating property " + "value object to another property value."); @@ -94,42 +101,40 @@ public static PrismPropertyValue createRaw(XNode rawElement) { public void setValue(T value) { + checkMutability(); this.value = value; checkValue(); } - public T getValue() { + public T getValue() { if (rawElement != null) { ItemDefinition def = null; Itemable parent = getParent(); if (parent != null && parent.getDefinition() != null) { def = getParent().getDefinition(); } - if (def == null) { - // We are weak now. If there is no better definition for this we assume a default definition and process - // the attribute now. But we should rather do this: TODO: - // throw new IllegalStateException("Attempt to get value withot a type from raw value of property "+getParent()); - if (parent != null && parent.getPrismContext() != null) { - def = SchemaRegistry.createDefaultItemDefinition(parent.getElementName(), parent.getPrismContext()); - } else if (PrismContext.isAllowSchemalessSerialization()) { - if (rawElement instanceof Element) { - // Do the most stupid thing possible. Assume string value. And there will be no definition. - value = (T) ((Element)rawElement).getTextContent(); - } else if (rawElement instanceof PrimitiveXNode){ - try { - QName type = rawElement.getTypeQName() != null ? rawElement.getTypeQName() : DOMUtil.XSD_STRING; - value = (T) ((PrimitiveXNode) rawElement).getParsedValueWithoutRecording(type); - } catch (SchemaException ex){ - throw new IllegalStateException("Cannot fetch value from raw element. " + ex.getMessage(), ex); - } - } else { - throw new IllegalStateException("No parent or prism context in property value "+this+", cannot create default definition." + - "The element is also not a DOM element but it is "+rawElement.getClass()+". Epic fail."); - } - } else { - throw new IllegalStateException("No parent or prism context in property value "+this+" (schemaless serialization is disabled)"); - } - } +// if (def == null) { +// // We are weak now. If there is no better definition for this we assume a default definition and process +// // the attribute now. But we should rather do this: TODO: +// // throw new IllegalStateException("Attempt to get value withot a type from raw value of property "+getParent()); +// if (parent != null && getPrismContext() != null) { +// def = SchemaRegistryImpl.createDefaultItemDefinition(parent.getElementName(), getPrismContext()); +// } else if (PrismContextImpl.isAllowSchemalessSerialization()) { +// if (rawElement instanceof PrimitiveXNode) { +// try { +// QName type = rawElement.getTypeQName() != null ? rawElement.getTypeQName() : DOMUtil.XSD_STRING; +// value = (T) ((PrimitiveXNode) rawElement).getParsedValueWithoutRecording(type); +// } catch (SchemaException ex){ +// throw new IllegalStateException("Cannot fetch value from raw element. " + ex.getMessage(), ex); +// } +// } else { +// throw new IllegalStateException("No parent or prism context in property value "+this+", cannot create default definition." + +// "The element is also not a DOM element but it is "+rawElement.getClass()+". Epic fail."); +// } +// } else { +// throw new IllegalStateException("No parent or prism context in property value "+this+" (schemaless serialization is disabled)"); +// } +// } if (def != null) { try { applyDefinition(def); @@ -137,6 +142,9 @@ public T getValue() { throw new IllegalStateException(e.getMessage(),e); } } + if (rawElement != null) { + return (T) RawType.create(rawElement, getPrismContext()); + } } return value; } @@ -149,7 +157,7 @@ public static Collection getValues(Collection> pval return realValues; } - public Object getRawElement() { + public XNode getRawElement() { return rawElement; } @@ -164,8 +172,9 @@ public boolean isRaw() { @Override public void applyDefinition(ItemDefinition definition) throws SchemaException { - if (definition != null && rawElement !=null) { - value = (T) parseRawElementToNewRealValue(this, (PrismPropertyDefinition) definition); + PrismPropertyDefinition propertyDefinition = (PrismPropertyDefinition) definition; + if (propertyDefinition != null && !propertyDefinition.isAnyType() && rawElement != null) { + value = (T) parseRawElementToNewRealValue(this, propertyDefinition); rawElement = null; } } @@ -181,8 +190,11 @@ public void revive(PrismContext prismContext) throws SchemaException { if (value != null) { if (value instanceof Revivable) { ((Revivable)value).revive(prismContext); - } else if (prismContext.getBeanConverter().canProcess(value.getClass())) { - prismContext.getBeanConverter().revive(value, prismContext); + } else { + BeanMarshaller marshaller = ((PrismContextImpl) prismContext).getBeanMarshaller(); + if (marshaller.canProcess(value.getClass())) { + marshaller.revive(value, prismContext); + } } } } @@ -196,6 +208,7 @@ public void recompute(PrismContext prismContext) { if (realValue == null) { return; } + checkMutability(); // TODO reconsider this PrismUtil.recomputeRealValue(realValue, prismContext); } @@ -370,8 +383,8 @@ private PrismPropertyValue parseRawElementToNewValue(PrismPropertyValue or private T parseRawElementToNewRealValue(PrismPropertyValue prismPropertyValue, PrismPropertyDefinition definition) throws SchemaException { PrismContext prismContext = definition.getPrismContext(); - XNodeProcessor xnodeProcessor = prismContext.getXnodeProcessor(); - T value = xnodeProcessor.parsePrismPropertyRealValue(prismPropertyValue.rawElement, definition, ParsingContext.createDefault()); + //noinspection UnnecessaryLocalVariable + T value = prismContext.parserFor(prismPropertyValue.rawElement.toRootXNode()).definition(definition).parseRealValue(); return value; } @@ -635,4 +648,15 @@ public JAXBElement toJaxbElement() { Object realValue = getValue(); return new JAXBElement(parent.getElementName(), (Class) realValue.getClass(), (T) realValue); } + + @Override + public Class getRealClass() { + return value != null ? value.getClass() : null; + } + + @Nullable + @Override + public T getRealValue() { + return (T) getValue(); + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReference.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReference.java index 1ba348ac0f0..cecf365e347 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReference.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReference.java @@ -59,18 +59,6 @@ public PrismReferenceDefinition getDefinition() { return (PrismReferenceDefinition) super.getDefinition(); } - /** - * Returns reference values. - *

- * The values are returned as set. The order of values is not significant. - * - * @return property values - */ - @Override - public List getValues() { - return (List) super.getValues(); - } - public PrismReferenceValue getValue() { // We are not sure about multiplicity if there is no definition or the definition is dynamic if (getDefinition() != null && !getDefinition().isDynamic()) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinition.java index f0bf92d34c8..f21b3003602 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,155 +16,33 @@ package com.evolveum.midpoint.prism; -import javax.xml.namespace.QName; - import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.path.ObjectReferencePathSegment; -import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import javax.xml.namespace.QName; /** - * Object Reference Schema Definition. - * - * Object Reference is a property that describes reference to an object. It is - * used to represent association between objects. For example reference from - * User object to Account objects that belong to the user. The reference is a - * simple uni-directional link using an OID as an identifier. - * - * This type should be used for all object references so the implementations can - * detect them and automatically resolve them. - * - * This class represents schema definition for object reference. See - * {@link Definition} for more details. - * - * @author Radovan Semancik - * + * @author mederly */ -public class PrismReferenceDefinition extends ItemDefinition { - - private static final long serialVersionUID = 2427488779612517600L; - private QName targetTypeName; - private QName compositeObjectElementName; - private boolean isComposite = false; - - public PrismReferenceDefinition(QName elementName, QName typeName, PrismContext prismContext) { - super(elementName, typeName, prismContext); - } - - /** - * Returns valid XSD object types whose may be the targets of the reference. - * - * Corresponds to "targetType" XSD annotation. - * - * Returns empty set if not specified. Must not return null. - * - * @return set of target type names - */ - public QName getTargetTypeName() { - return targetTypeName; - } - - public void setTargetTypeName(QName targetTypeName) { - this.targetTypeName = targetTypeName; - } - - public QName getCompositeObjectElementName() { - return compositeObjectElementName; - } +public interface PrismReferenceDefinition extends ItemDefinition { + QName getTargetTypeName(); - public void setCompositeObjectElementName(QName compositeObjectElementName) { - this.compositeObjectElementName = compositeObjectElementName; - } - - public boolean isComposite() { - return isComposite; - } + QName getCompositeObjectElementName(); - public void setComposite(boolean isComposite) { - this.isComposite = isComposite; - } + boolean isComposite(); @Override - public boolean isValidFor(QName elementQName, Class clazz) { - return isValidFor(elementQName, clazz, false); - } + PrismReference instantiate(); @Override - public boolean isValidFor(QName elementQName, Class clazz, boolean caseInsensitive) { - if (!clazz.isAssignableFrom(this.getClass())) { - return false; - } - if (QNameUtil.match(elementQName, getName(), caseInsensitive)) { - return true; - } - if (QNameUtil.match(elementQName, getCompositeObjectElementName(), caseInsensitive)) { - return true; - } - return false; - } + PrismReference instantiate(QName name); @Override - T findItemDefinition(ItemPath path, Class clazz) { - if (path.isEmpty() || !(path.first() instanceof ObjectReferencePathSegment)) { - return super.findItemDefinition(path, clazz); - } else { - ItemPath rest = path.rest(); - PrismObjectDefinition referencedObjectDefinition = getSchemaRegistry().determineReferencedObjectDefinition(targetTypeName, rest); - return (T) referencedObjectDefinition.findItemDefinition(rest, clazz); - } - } - - @Override - public PrismReference instantiate() { - return instantiate(getName()); - } - - @Override - public PrismReference instantiate(QName name) { - name = addNamespaceIfApplicable(name); - return new PrismReference(name, this, prismContext); - } - - @Override - public ItemDelta createEmptyDelta(ItemPath path) { - return new ReferenceDelta(path, this, prismContext); - } - - @Override - public PrismReferenceDefinition clone() { - PrismReferenceDefinition clone = new PrismReferenceDefinition(getName(), getTypeName(), getPrismContext()); - copyDefinitionData(clone); - return clone; - } - - protected void copyDefinitionData(PrismReferenceDefinition clone) { - super.copyDefinitionData(clone); - clone.targetTypeName = this.targetTypeName; - clone.compositeObjectElementName = this.compositeObjectElementName; - clone.isComposite = this.isComposite; - } - - /** - * Return a human readable name of this class suitable for logs. - */ - @Override - protected String getDebugDumpClassName() { - return "PRD"; - } - - @Override - public String getDocClassName() { - return "reference"; - } + ItemDelta createEmptyDelta(ItemPath path); + @NotNull @Override - protected void extendToString(StringBuilder sb) { - super.extendToString(sb); - if (isComposite) { - sb.append(",composite"); - } - } - + PrismReferenceDefinition clone(); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinitionImpl.java new file mode 100644 index 00000000000..dc1b223d483 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceDefinitionImpl.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2010-2015 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.delta.ReferenceDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.path.ObjectReferencePathSegment; +import com.evolveum.midpoint.util.QNameUtil; +import org.jetbrains.annotations.NotNull; + +/** + * Object Reference Schema Definition. + * + * Object Reference is a property that describes reference to an object. It is + * used to represent association between objects. For example reference from + * User object to Account objects that belong to the user. The reference is a + * simple uni-directional link using an OID as an identifier. + * + * This type should be used for all object references so the implementations can + * detect them and automatically resolve them. + * + * This class represents schema definition for object reference. See + * {@link Definition} for more details. + * + * @author Radovan Semancik + * + */ +public class PrismReferenceDefinitionImpl extends ItemDefinitionImpl implements PrismReferenceDefinition { + + private static final long serialVersionUID = 2427488779612517600L; + private QName targetTypeName; + private QName compositeObjectElementName; + private boolean isComposite = false; + + public PrismReferenceDefinitionImpl(QName elementName, QName typeName, PrismContext prismContext) { + super(elementName, typeName, prismContext); + } + + /** + * Returns valid XSD object types whose may be the targets of the reference. + * + * Corresponds to "targetType" XSD annotation. + * + * Returns empty set if not specified. Must not return null. + * + * @return set of target type names + */ + @Override + public QName getTargetTypeName() { + return targetTypeName; + } + + public void setTargetTypeName(QName targetTypeName) { + this.targetTypeName = targetTypeName; + } + + @Override + public QName getCompositeObjectElementName() { + return compositeObjectElementName; + } + + public void setCompositeObjectElementName(QName compositeObjectElementName) { + this.compositeObjectElementName = compositeObjectElementName; + } + + @Override + public boolean isComposite() { + return isComposite; + } + + public void setComposite(boolean isComposite) { + this.isComposite = isComposite; + } + + @Override + public boolean isValidFor(QName elementQName, Class clazz) { + return isValidFor(elementQName, clazz, false); + } + + @Override + public boolean isValidFor(@NotNull QName elementQName, @NotNull Class clazz, boolean caseInsensitive) { + if (!clazz.isAssignableFrom(this.getClass())) { + return false; + } + if (QNameUtil.match(elementQName, getName(), caseInsensitive)) { + return true; + } + if (QNameUtil.match(elementQName, getCompositeObjectElementName(), caseInsensitive)) { + return true; + } + return false; + } + + @Override + public T findItemDefinition(@NotNull ItemPath path, @NotNull Class clazz) { + if (path.isEmpty() || !(path.first() instanceof ObjectReferencePathSegment)) { + return super.findItemDefinition(path, clazz); + } else { + ItemPath rest = path.rest(); + PrismObjectDefinition referencedObjectDefinition = getSchemaRegistry().determineReferencedObjectDefinition(targetTypeName, rest); + return (T) referencedObjectDefinition.findItemDefinition(rest, clazz); + } + } + + @Override + public PrismReference instantiate() { + return instantiate(getName()); + } + + @Override + public PrismReference instantiate(QName name) { + name = addNamespaceIfApplicable(name); + return new PrismReference(name, this, prismContext); + } + + @Override + public ItemDelta createEmptyDelta(ItemPath path) { + return new ReferenceDelta(path, this, prismContext); + } + + @NotNull + @Override + public PrismReferenceDefinition clone() { + PrismReferenceDefinitionImpl clone = new PrismReferenceDefinitionImpl(getName(), getTypeName(), getPrismContext()); + copyDefinitionData(clone); + return clone; + } + + protected void copyDefinitionData(PrismReferenceDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.targetTypeName = this.targetTypeName; + clone.compositeObjectElementName = this.compositeObjectElementName; + clone.isComposite = this.isComposite; + } + + /** + * Return a human readable name of this class suitable for logs. + */ + @Override + protected String getDebugDumpClassName() { + return "PRD"; + } + + @Override + public String getDocClassName() { + return "reference"; + } + + @Override + protected void extendToString(StringBuilder sb) { + super.extendToString(sb); + if (isComposite) { + sb.append(",composite"); + } + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceValue.java index bc105907329..657a44b05ea 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismReferenceValue.java @@ -35,6 +35,7 @@ import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_3.EvaluationTimeType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.jetbrains.annotations.Nullable; /** * @author Radovan Semancik @@ -93,6 +94,7 @@ public String getOid() { } public void setOid(String oid) { + checkMutability(); this.oid = oid; } @@ -101,6 +103,7 @@ public PrismObject getObject() { } public void setObject(PrismObject object) { + checkMutability(); this.object = object; } @@ -131,6 +134,7 @@ public void setTargetType(QName targetType) { * @param allowEmptyNamespace This is an ugly hack. See comment in DOMUtil.validateNonEmptyQName. */ public void setTargetType(QName targetType, boolean allowEmptyNamespace) { + checkMutability(); // Null value is OK if (targetType != null) { // But non-empty is not .. @@ -160,10 +164,12 @@ public PolyString getTargetName() { } public void setTargetName(PolyString name) { + checkMutability(); this.targetName = name; } public void setTargetName(PolyStringType name) { + checkMutability(); if (name == null) { this.targetName = null; } else { @@ -185,6 +191,7 @@ public QName getRelation() { } public void setRelation(QName relation) { + checkMutability(); this.relation = relation; } @@ -193,6 +200,7 @@ public String getDescription() { } public void setDescription(String description) { + checkMutability(); this.description = description; } @@ -201,6 +209,7 @@ public SearchFilterType getFilter() { } public void setFilter(SearchFilterType filter) { + checkMutability(); this.filter = filter; } @@ -209,6 +218,7 @@ public EvaluationTimeType getResolutionTime() { } public void setResolutionTime(EvaluationTimeType resolutionTime) { + checkMutability(); this.resolutionTime = resolutionTime; } @@ -491,21 +501,40 @@ public String toString() { } public Referencable asReferencable() { - if (referencable == null){ - Itemable parent = getParent(); + if (referencable != null) { + return referencable; + } + + Itemable parent = getParent(); + if (parent != null) { QName xsdType = parent.getDefinition().getTypeName(); Class clazz = getPrismContext().getSchemaRegistry().getCompileTimeClass(xsdType); - if (clazz != null){ + if (clazz != null) { try { referencable = (Referencable) clazz.newInstance(); } catch (InstantiationException | IllegalAccessException e) { - throw new SystemException("Couldn't create jaxb object instance of '" + clazz + "': "+e.getMessage(), e); + throw new SystemException("Couldn't create jaxb object instance of '" + clazz + "': " + e.getMessage(), + e); } } referencable.setupReferenceValue(this); } - return referencable; - + + // A hack, just to avoid crashes. + return new Referencable() { + PrismReferenceValue referenceValue = PrismReferenceValue.this; + @Override + public PrismReferenceValue asReferenceValue() { + return referenceValue; + } + @Override + public void setupReferenceValue(PrismReferenceValue value) { + referenceValue = value; + } + public String getOid() { // used by some scripts + return referenceValue.getOid(); + } + }; } @Override @@ -580,5 +609,16 @@ public String toHumanReadableString() { } return sb.toString(); } - + + @Override + public Class getRealClass() { + return Referencable.class; + } + + @SuppressWarnings("unchecked") + @Nullable + @Override + public Referencable getRealValue() { + return asReferencable(); + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismSerializer.java new file mode 100644 index 00000000000..da14b0d70f9 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismSerializer.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +/** + * Takes care of serializing prism objects and other beans, i.e. converts java form to + * lexical representation (XML/JSON/YAML strings, DOM tree) or intermediate one (XNode). + * + * General post-conditions: + * 1. All type QNames will be resolvable (i.e. they will be part of static schema) - TODO think again about this; think also about allowing 'system-wide' parts of dynamic schema ... + * 2. If root(..) is configured, it will be set regardless of the object type and content. + * 3. ... TODO ... + * + * @author mederly + */ +public interface PrismSerializer { + + /** + * Sets the name of the root element. Can be done either here or during call to serialize(..) methods. + * + * @param elementName Name of the root element + * @return Serializer with the root element name set. + */ + @NotNull + PrismSerializer root(QName elementName); + + /** + * Sets the item definition to be used during serialization. + * (Not much used.) + * @param itemDefinition + * @return + */ + @NotNull + PrismSerializer definition(ItemDefinition itemDefinition); + + /** + * Sets the context for the serialization operation, containing e.g. serialization options. + * + * @param context Context to be set. + * @return Serializer with the context set. + */ + @NotNull + PrismSerializer context(@Nullable SerializationContext context); + + /** + * Sets the serialization options (part of the context). + * + * @param options Options to be set. + * @return Serializer with the options set. + */ + @NotNull + PrismSerializer options(@Nullable SerializationOptions options); + + /** + * Serializes given prism item. + * + * @param item Item to be serialized. + * @return String/RootXNode representation of the item. + */ + @NotNull + T serialize(@NotNull Item item) throws SchemaException; + + /** + * Serializes given prism value (property, reference, or container). + * Name of the root element is derived in the following way: + * 1. if explicit name is set ( + * @param value Value to be serialized. + * @return String/RootXNode representation of the value. + */ + @NotNull + T serialize(@NotNull PrismValue value) throws SchemaException; + + /** + * Serializes given prism value (property, reference, or container). + * @param value Value to be serialized. + * @param rootName Name of the root element. (Overrides other means of deriving the name.) + * @return String/RootXNode representation of the value. + */ + @NotNull + T serialize(@NotNull PrismValue value, QName rootName) throws SchemaException; + + @NotNull + T serialize(@NotNull RootXNode xnode) throws SchemaException; + + T serialize(JAXBElement value) throws SchemaException; + T serializeRealValue(Object value) throws SchemaException; + T serializeRealValue(Object value, QName rootName) throws SchemaException; + T serializeAnyData(Object value) throws SchemaException; + T serializeAnyData(Object value, QName rootName) throws SchemaException; +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java index 23c7000db15..66cf9c4c561 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java @@ -22,6 +22,8 @@ import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.w3c.dom.Element; import java.io.Serializable; @@ -38,31 +40,44 @@ * @author semancik * */ -public abstract class PrismValue implements Visitable, PathVisitable, Serializable, DebugDumpable, Revivable { +public abstract class PrismValue implements IPrismValue { private OriginType originType; private Objectable originObject; private Itemable parent; - protected Element domElement = null; - private transient Map userData = new HashMap<>();; + private transient Map userData = new HashMap<>(); + protected boolean immutable; - PrismValue() { - super(); + transient protected PrismContext prismContext; + + PrismValue() { + } + + PrismValue(PrismContext prismContext) { + this.prismContext = prismContext; } PrismValue(OriginType type, Objectable source) { - super(); + this(null, type, source); + } + + PrismValue(PrismContext prismContext, OriginType type, Objectable source) { + this.prismContext = prismContext; this.originType = type; this.originObject = source; } - PrismValue(OriginType type, Objectable source, Itemable parent) { - super(); + PrismValue(PrismContext prismContext, OriginType type, Objectable source, Itemable parent) { + this.prismContext = prismContext; this.originType = type; this.originObject = source; this.parent = parent; } + public void setPrismContext(PrismContext prismContext) { + this.prismContext = prismContext; + } + public void setOriginObject(Objectable source) { this.originObject = source; } @@ -71,11 +86,13 @@ public void setOriginType(OriginType type) { this.originType = type; } - public OriginType getOriginType() { + @Override + public OriginType getOriginType() { return originType; } - public Objectable getOriginObject() { + @Override + public Objectable getOriginObject() { return originObject; } @@ -83,18 +100,22 @@ public Map getUserData() { return userData; } - public Object getUserData(String key) { + @Override + public Object getUserData(@NotNull String key) { return userData.get(key); } - public void setUserData(String key, Object value) { + @Override + public void setUserData(@NotNull String key, Object value) { userData.put(key, value); } - public Itemable getParent() { + @Override + public Itemable getParent() { return parent; } + @Override public void setParent(Itemable parent) { if (this.parent != null && parent != null && this.parent != parent) { throw new IllegalStateException("Attempt to reset value parent from "+this.parent+" to "+parent); @@ -102,6 +123,8 @@ public void setParent(Itemable parent) { this.parent = parent; } + @NotNull + @Override public ItemPath getPath() { Itemable parent = getParent(); if (parent == null) { @@ -115,6 +138,7 @@ public ItemPath getPath() { * Or when we know that the previous parent will be discarded and we * want to avoid unnecessary cloning. */ + @Override public void clearParent() { parent = null; } @@ -128,9 +152,14 @@ public static void clearParent(List> values) { } } + @Override public PrismContext getPrismContext() { + if (prismContext != null) { + return prismContext; + } if (parent != null) { - return parent.getPrismContext(); + prismContext = parent.getPrismContext(); + return prismContext; } return null; } @@ -143,15 +172,22 @@ protected ItemDefinition getDefinition() { return parent.getDefinition(); } + @Override public void applyDefinition(ItemDefinition definition) throws SchemaException { + checkMutability(); // TODO reconsider applyDefinition(definition, true); } + @Override public void applyDefinition(ItemDefinition definition, boolean force) throws SchemaException { + checkMutability(); // TODO reconsider // Do nothing by default } public void revive(PrismContext prismContext) throws SchemaException { + if (this.prismContext == null) { + this.prismContext = prismContext; + } recompute(prismContext); } @@ -159,12 +195,11 @@ public void revive(PrismContext prismContext) throws SchemaException { * Recompute the value or otherwise "initialize" it before adding it to a prism tree. * This may as well do nothing if no recomputing or initialization is needed. */ + @Override public void recompute() { recompute(getPrismContext()); } - - public abstract void recompute(PrismContext prismContext); - + @Override public void accept(Visitor visitor) { visitor.visit(this); @@ -217,19 +252,11 @@ public int compare(V v1, V v2) { }; return MiscUtil.unorderedCollectionEquals(collection1, collection2, comparator); } - - public abstract boolean isEmpty(); - + + @Override public void normalize() { // do nothing by default } - - /** - * Returns true if the value is raw. Raw value is a semi-parsed value. - * A value for which we don't have a full definition yet and therefore - * the parsing could not be finished until the defintion is supplied. - */ - public abstract boolean isRaw(); public static Collection cloneValues(Collection values) { Collection clonedCollection = new ArrayList(values.size()); @@ -238,7 +265,7 @@ public static Collection cloneValues(Collection val } return clonedCollection; } - + public abstract PrismValue clone(); protected void copyValues(PrismValue clone) { @@ -247,12 +274,16 @@ protected void copyValues(PrismValue clone) { // Do not clone parent. The clone will most likely go to a different prism // and setting the parent will make it difficult to add it there. clone.parent = null; + // Do not clone immutable flag. } - + + @NotNull public static Collection cloneCollection(Collection values) { Collection clones = new ArrayList(); - for (T value: values) { - clones.add((T)value.clone()); + if (values != null) { + for (T value : values) { + clones.add((T) value.clone()); + } } return clones; } @@ -267,11 +298,7 @@ public static Collection resetParentCollection(Collect } return values; } - - public abstract Object find(ItemPath path); - - public abstract PartiallyResolvedItem findPartial(ItemPath path); - + @Override public int hashCode() { int result = 1; @@ -280,6 +307,7 @@ public int hashCode() { public boolean equalsComplex(PrismValue other, boolean ignoreMetadata, boolean isLiteral) { // parent is not considered at all. it is not relevant. + // neither the immutable flag if (!ignoreMetadata) { if (originObject == null) { if (other.originObject != null) @@ -292,6 +320,7 @@ public boolean equalsComplex(PrismValue other, boolean ignoreMetadata, boolean i return true; } + @Override public boolean equals(PrismValue otherValue, boolean ignoreMetadata) { return equalsComplex(otherValue, ignoreMetadata, false); } @@ -336,6 +365,7 @@ public boolean equals(Object obj) { * Assumes matching representations. I.e. it assumes that both this and otherValue represent the same instance of item. * E.g. the container with the same ID. */ + @Override public Collection diff(PrismValue otherValue) { return diff(otherValue, true, false); } @@ -344,6 +374,7 @@ public Collection diff(PrismValue otherValue) { * Assumes matching representations. I.e. it assumes that both this and otherValue represent the same instance of item. * E.g. the container with the same ID. */ + @Override public Collection diff(PrismValue otherValue, boolean ignoreMetadata, boolean isLiteral) { Collection itemDeltas = new ArrayList(); diffMatchingRepresentation(otherValue, itemDeltas, ignoreMetadata, isLiteral); @@ -355,14 +386,6 @@ void diffMatchingRepresentation(PrismValue otherValue, // Nothing to do by default } - public abstract boolean match(PrismValue otherValue); - - /** - * Returns a short (one-line) representation of the real value stored in this object. - * The value is returned without any decorations or type demarcations (such as PPV, PRV, etc.) - */ - public abstract String toHumanReadableString(); - protected void appendOriginDump(StringBuilder builder) { if (DebugUtil.isDetailedDebugDump()) { if (getOriginType() != null || getOriginObject() != null) { @@ -382,6 +405,7 @@ public static Set getRealValuesOfCollection(Collection boolean collectionContainsEquivalentValue(Collection collection, V value) { if (collection == null) { return false; @@ -393,4 +417,27 @@ public static boolean collectionContainsEquivalentValue(C } return false; } + + + @Override + public boolean isImmutable() { + return immutable; + } + + public void setImmutable(boolean immutable) { + this.immutable = immutable; + } + + protected void checkMutability() { + if (immutable) { + throw new IllegalStateException("An attempt to modify an immutable value of " + toHumanReadableString()); + } + } + + @Nullable + abstract public Class getRealClass(); + + @Nullable + abstract public T getRealValue(); + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationContext.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationContext.java index 44be5428e28..35d254a1b35 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationContext.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationContext.java @@ -22,7 +22,7 @@ * * @author Pavol Mederly */ -public class SerializationContext { +public class SerializationContext implements Cloneable { private SerializationOptions options; @@ -41,4 +41,26 @@ public void setOptions(SerializationOptions options) { public static boolean isSerializeReferenceNames(SerializationContext ctx) { return ctx != null && SerializationOptions.isSerializeReferenceNames(ctx.getOptions()); } + + public static boolean isSerializeCompositeObjects(SerializationContext ctx) { + return ctx != null && SerializationOptions.isSerializeCompositeObjects(ctx.getOptions()); + } + + public static SerializationContext forOptions(SerializationOptions options) { + return new SerializationContext(options); + } + + @Override + public SerializationContext clone() { + SerializationContext clone; + try { + clone = (SerializationContext) super.clone(); + } catch (CloneNotSupportedException e) { + throw new IllegalStateException(e); + } + if (options != null) { + clone.options = options.clone(); + } + return clone; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java index e4d3620ffe8..7c694177fc6 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializationOptions.java @@ -19,9 +19,14 @@ /** * @author Pavol Mederly */ -public class SerializationOptions { +public class SerializationOptions implements Cloneable { + private boolean serializeCompositeObjects; private boolean serializeReferenceNames; + private ItemNameQualificationStrategy itemNameQualificationStrategy; +// private NameQualificationStrategy itemTypeQualificationStrategy; +// private NameQualificationStrategy itemPathQualificationStrategy; +// private NameQualificationStrategy genericQualificationStrategy; public boolean isSerializeReferenceNames() { return serializeReferenceNames; @@ -40,4 +45,84 @@ public static SerializationOptions createSerializeReferenceNames(){ public static boolean isSerializeReferenceNames(SerializationOptions options) { return options != null && options.isSerializeReferenceNames(); } + + public boolean isSerializeCompositeObjects() { + return serializeCompositeObjects; + } + + public void setSerializeCompositeObjects(boolean serializeCompositeObjects) { + this.serializeCompositeObjects = serializeCompositeObjects; + } + + public static SerializationOptions createSerializeCompositeObjects(){ + SerializationOptions serializationOptions = new SerializationOptions(); + serializationOptions.setSerializeCompositeObjects(true); + return serializationOptions; + } + + public static boolean isSerializeCompositeObjects(SerializationOptions options) { + return options != null && options.isSerializeCompositeObjects(); + } + + // public ItemNameQualificationStrategy getItemNameQualificationStrategy() { +// return itemNameQualificationStrategy; +// } +// +// public void setItemNameQualificationStrategy(ItemNameQualificationStrategy itemNameQualificationStrategy) { +// this.itemNameQualificationStrategy = itemNameQualificationStrategy; +// } +// +// public NameQualificationStrategy getItemTypeQualificationStrategy() { +// return itemTypeQualificationStrategy; +// } +// +// public void setItemTypeQualificationStrategy(NameQualificationStrategy itemTypeQualificationStrategy) { +// this.itemTypeQualificationStrategy = itemTypeQualificationStrategy; +// } +// +// public NameQualificationStrategy getItemPathQualificationStrategy() { +// return itemPathQualificationStrategy; +// } +// +// public void setItemPathQualificationStrategy(NameQualificationStrategy itemPathQualificationStrategy) { +// this.itemPathQualificationStrategy = itemPathQualificationStrategy; +// } +// +// public NameQualificationStrategy getGenericQualificationStrategy() { +// return genericQualificationStrategy; +// } +// +// public void setGenericQualificationStrategy(NameQualificationStrategy genericQualificationStrategy) { +// this.genericQualificationStrategy = genericQualificationStrategy; +// } + + public static SerializationOptions createQualifiedNames() { + SerializationOptions opts = new SerializationOptions(); + opts.itemNameQualificationStrategy = ItemNameQualificationStrategy.ALWAYS_USE_FULL_URI; +// opts.itemPathQualificationStrategy = NameQualificationStrategy.ALWAYS; +// opts.itemTypeQualificationStrategy = NameQualificationStrategy.ALWAYS; +// opts.genericQualificationStrategy = NameQualificationStrategy.ALWAYS; + return opts; + } + + public static boolean isFullItemNameUris(SerializationOptions opts) { + return opts != null && opts.itemNameQualificationStrategy != ItemNameQualificationStrategy.ALWAYS_USE_FULL_URI; + } + + public static boolean isUseNsProperty(SerializationOptions opts) { + return opts == null || opts.itemNameQualificationStrategy == null || opts.itemNameQualificationStrategy == ItemNameQualificationStrategy.USE_NS_PROPERTY; + } + + @Override + protected SerializationOptions clone() { + SerializationOptions clone = null; + try { + clone = (SerializationOptions) super.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + clone.serializeReferenceNames = this.serializeReferenceNames; + clone.itemNameQualificationStrategy = itemNameQualificationStrategy; + return clone; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerDomTarget.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerDomTarget.java new file mode 100644 index 00000000000..47ffa09631e --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerDomTarget.java @@ -0,0 +1,22 @@ +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +/** + * @author mederly + */ +public class SerializerDomTarget extends SerializerTarget { + + public SerializerDomTarget(@NotNull PrismContextImpl prismContext) { + super(prismContext); + } + + @Override + @NotNull + public Element write(@NotNull RootXNode xroot, SerializationContext context) throws SchemaException { + return prismContext.getLexicalProcessorRegistry().domProcessor().writeXRootToElement(xroot); + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerStringTarget.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerStringTarget.java new file mode 100644 index 00000000000..f03f46b9e75 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerStringTarget.java @@ -0,0 +1,26 @@ +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.lex.LexicalProcessor; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; + +/** + * @author mederly + */ +public class SerializerStringTarget extends SerializerTarget { + + @NotNull private final String language; + + public SerializerStringTarget(@NotNull PrismContextImpl prismContext, @NotNull String language) { + super(prismContext); + this.language = language; + } + + @NotNull + @Override + public String write(@NotNull RootXNode xroot, SerializationContext context) throws SchemaException { + LexicalProcessor lexicalProcessor = prismContext.getLexicalProcessorRegistry().processorFor(language); + return lexicalProcessor.write(xroot, context); + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerTarget.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerTarget.java new file mode 100644 index 00000000000..a31d8fe44f9 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerTarget.java @@ -0,0 +1,20 @@ +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; + +/** + * @author mederly + */ +public abstract class SerializerTarget { + + @NotNull public final PrismContextImpl prismContext; + + protected SerializerTarget(@NotNull PrismContextImpl prismContext) { + this.prismContext = prismContext; + } + + @NotNull + abstract public T write(@NotNull RootXNode xroot, SerializationContext context) throws SchemaException; +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerXNodeTarget.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerXNodeTarget.java new file mode 100644 index 00000000000..c44fa8dd56b --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SerializerXNodeTarget.java @@ -0,0 +1,22 @@ +package com.evolveum.midpoint.prism; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; + +/** + * @author mederly + */ +public class SerializerXNodeTarget extends SerializerTarget { + + public SerializerXNodeTarget(@NotNull PrismContextImpl prismContext) { + super(prismContext); + } + + @NotNull + @Override + public RootXNode write(@NotNull RootXNode xroot, SerializationContext context) throws SchemaException { + return xroot; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SimpleTypeDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SimpleTypeDefinition.java new file mode 100644 index 00000000000..444246c7b1c --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SimpleTypeDefinition.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +/** + * Primarily for enums. (Experimental.) + * + * Currently there are no special methods. + * + * @author mederly + */ +public interface SimpleTypeDefinition extends TypeDefinition { + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/SimpleTypeDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SimpleTypeDefinitionImpl.java new file mode 100644 index 00000000000..589602da0cf --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/SimpleTypeDefinitionImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; + +/** + * @author mederly + */ +public class SimpleTypeDefinitionImpl extends TypeDefinitionImpl implements SimpleTypeDefinition { + + public SimpleTypeDefinitionImpl(QName typeName, PrismContext prismContext) { + super(typeName, prismContext); + } + + @Override + public void revive(PrismContext prismContext) { + } + + @Override + protected String getDebugDumpClassName() { + return "STD"; + } + + @Override + public String getDocClassName() { + return "simple type"; + } + + @NotNull + @Override + public SimpleTypeDefinitionImpl clone() { + SimpleTypeDefinitionImpl clone = new SimpleTypeDefinitionImpl(typeName, prismContext); + super.copyDefinitionData(clone); + return clone; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/TypeDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/TypeDefinition.java new file mode 100644 index 00000000000..4a73eafb3d1 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/TypeDefinition.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.jetbrains.annotations.Nullable; + +import javax.xml.namespace.QName; + +/** + * @author mederly + */ +public interface TypeDefinition extends Definition { + + /** + * Returns compile-time class, if this type has any. For example, UserType.class, ObjectType.class, ExtensionType.class. + */ + @Nullable + Class getCompileTimeClass(); + + /** + * Name of super type of this complex type definition. E.g. c:ObjectType is a super type for + * c:FocusType which is a super type for c:UserType. Or (more complex example) ri:ShadowAttributesType + * is a super type of ri:AccountObjectClass. (TODO is this really true?) + */ + @Nullable + QName getSuperType(); +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/TypeDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/TypeDefinitionImpl.java new file mode 100644 index 00000000000..b8ba77051a8 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/TypeDefinitionImpl.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import javax.xml.namespace.QName; +import java.util.Objects; + +/** + * @author mederly + */ +public abstract class TypeDefinitionImpl extends DefinitionImpl implements TypeDefinition { + + protected QName superType; + protected Class compileTimeClass; + + public TypeDefinitionImpl(QName typeName, PrismContext prismContext) { + super(typeName, prismContext); + } + + @Override + public QName getSuperType() { + return superType; + } + + public void setSuperType(QName superType) { + this.superType = superType; + } + + @Override + public Class getCompileTimeClass() { + return compileTimeClass; + } + + public void setCompileTimeClass(Class compileTimeClass) { + this.compileTimeClass = compileTimeClass; + } + + protected void copyDefinitionData(TypeDefinitionImpl clone) { + super.copyDefinitionData(clone); + clone.superType = this.superType; + clone.compileTimeClass = this.compileTimeClass; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof TypeDefinitionImpl)) + return false; + if (!super.equals(o)) + return false; + TypeDefinitionImpl that = (TypeDefinitionImpl) o; + return Objects.equals(superType, that.superType) && + Objects.equals(compileTimeClass, that.compileTimeClass); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), superType, compileTimeClass); + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/XmlEntityResolver.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/XmlEntityResolver.java new file mode 100644 index 00000000000..cd1cf859ded --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/XmlEntityResolver.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism; + +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.EntityResolver; + +/** + * @author mederly + */ +public interface XmlEntityResolver extends EntityResolver, LSResourceResolver { +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java index a42636c5438..518b4f70b90 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java @@ -26,7 +26,7 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.parser.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.ItemPath.CompareResult; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ObjectDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ObjectDelta.java index 2cecc741236..9b283f98709 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ObjectDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ObjectDelta.java @@ -1403,6 +1403,22 @@ public int hashCode() { return result; } + public boolean equivalent(ObjectDelta other) { + if (changeType != other.changeType) + return false; + if (objectToAdd == null) { + if (other.objectToAdd != null) + return false; + } else if (!objectToAdd.equivalent(other.objectToAdd)) + return false; + if (!MiscUtil.unorderedCollectionEquals(this.modifications, other.modifications, (o1, o2) -> + ((ItemDelta) o1).equivalent((ItemDelta) o2) ? 0 : 1)) { + return false; + } + return Objects.equals(objectTypeClass, other.objectTypeClass) + && Objects.equals(oid, other.oid); + } + @Override public boolean equals(Object obj) { if (this == obj) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/AbstractParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/AbstractParser.java index 8bf137eb1af..e69de29bb2d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/AbstractParser.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/AbstractParser.java @@ -1,494 +0,0 @@ -package com.evolveum.midpoint.prism.json; - -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.util.Iterator; -import java.util.ListIterator; -import java.util.Map.Entry; - -import javax.xml.namespace.QName; - -import org.apache.commons.lang.StringUtils; - -import com.evolveum.midpoint.prism.parser.Parser; -import com.evolveum.midpoint.prism.parser.json.ItemPathDeserializer; -import com.evolveum.midpoint.prism.parser.json.JsonValueParser; -import com.evolveum.midpoint.prism.parser.json.QNameDeserializer; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.xnode.ListXNode; -import com.evolveum.midpoint.prism.xnode.MapXNode; -import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; -import com.evolveum.midpoint.prism.xnode.RootXNode; -import com.evolveum.midpoint.prism.xnode.ValueParser; -import com.evolveum.midpoint.prism.xnode.XNode; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.JsonTokenId; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.module.SimpleModule; - -public abstract class AbstractParser implements Parser { - - private static final String PROP_NAMESPACE = "@ns"; - private static final String TYPE_DEFINITION = "@typeDef"; - private static final String VALUE_FIELD = "@value"; - - - @Override - public XNode parse(File file) throws SchemaException, IOException { - JsonParser parser = createParser(file); - return parseObject(parser); - } - - protected abstract JsonParser createParser(String dataString) throws SchemaException; - protected abstract JsonParser createParser(File file) throws SchemaException, IOException ; - - @Override - public XNode parse(String dataString) throws SchemaException { -// JsonFactory factory = new JsonFactory(); -// JsonParser parser = null; -// try { -// parser = factory.createParser(dataString); -// } catch (IOException e) { -// throw new SchemaException("Cannot create JSON parser: " + e.getMessage(), e); -// } - JsonParser parser = createParser(dataString); - return parseObject(parser); - } - - @Override - public boolean canParse(File file) throws IOException { - if (file == null) { - return false; - } - return file.getName().endsWith(".json"); - } - - @Override - public boolean canParse(String dataString) { - if (dataString == null) { - return false; - } - return dataString.startsWith("{"); - } - - @Override - public String serializeToString(XNode xnode, QName rootElementName) throws SchemaException { - if (xnode instanceof RootXNode){ - xnode = ((RootXNode) xnode).getSubnode(); - } - return serializeToJson(xnode, rootElementName); - } - - @Override - public String serializeToString(RootXNode xnode) throws SchemaException { - QName rootElementName = xnode.getRootElementName(); - return serializeToJson(xnode.getSubnode(), rootElementName); - } - - - // ------------------- METHODS FOR SERIALIZATION ------------------------------ -// String globalNamespace = null; - public String serializeToJson(XNode node, QName rootElement) throws SchemaException{ - try { -// globalNamespace = rootElement.getNamespaceURI(); - StringWriter out = new StringWriter(); - JsonGenerator generator = createGenerator(out); - return writeObject(node, rootElement, generator, out); - } catch (IOException ex){ - throw new SchemaException("Schema error during serializing to JSON.", ex); - } - - } - - private String writeObject(XNode node, QName rootElement, JsonGenerator generator, StringWriter out) throws JsonGenerationException, IOException{ - generator.writeStartObject(); - generator.writeStringField(PROP_NAMESPACE, rootElement.getNamespaceURI()); - serializeToJson(node, rootElement, rootElement.getNamespaceURI(), generator); - generator.writeEndObject(); - generator.flush(); - generator.close(); - return out.toString(); - } - - - String objectNs = null; - private void serializeToJson(XNode node, QName nodeName, String globalNamespace, JsonGenerator generator) throws JsonGenerationException, IOException{ - - if (node instanceof MapXNode){ - serializerFromMap((MapXNode) node, nodeName, globalNamespace, generator); - } else if (node instanceof ListXNode){ - serializeFromList((ListXNode) node, nodeName, globalNamespace, generator); - } else if (node instanceof PrimitiveXNode){ - serializeFromPrimitive((PrimitiveXNode) node, nodeName, generator); - } - } - - - private void serializerFromMap(MapXNode map, QName nodeName, String globalNamespace, JsonGenerator generator) throws JsonGenerationException, IOException{ - if (nodeName == null){ - generator.writeStartObject(); - } else{ - generator.writeObjectFieldStart(nodeName.getLocalPart()); - } - - // this is used only by first iteration..we need to set namespace right after the root element - if (StringUtils.isBlank(globalNamespace)){ - globalNamespace = nodeName.getNamespaceURI(); - generator.writeStringField(PROP_NAMESPACE, globalNamespace); - } - - - - Iterator> subnodes = map.entrySet().iterator(); - while (subnodes.hasNext()){ - Entry subNode = subnodes.next(); - globalNamespace = serializeNsIfNeeded(subNode.getKey(), globalNamespace, generator); - serializeToJson(subNode.getValue(), subNode. getKey(), globalNamespace, generator); - } - generator.writeEndObject(); - } - - private void serializeFromList(ListXNode list, QName nodeName, String globalNamespace, JsonGenerator generator) throws JsonGenerationException, IOException{ - ListIterator sublist = list.listIterator(); - generator.writeArrayFieldStart(nodeName.getLocalPart()); - while (sublist.hasNext()){ - serializeToJson(sublist.next(), null, globalNamespace, generator); - } - generator.writeEndArray(); - } - - private void serializeFromPrimitive(PrimitiveXNode primitive, QName nodeName, JsonGenerator generator) throws JsonGenerationException, IOException{ - - if (primitive.isExplicitTypeDeclaration()) { - generator.writeStartObject(); - generator.writeFieldName(TYPE_DEFINITION); - generator.writeObject(primitive.getTypeQName()); - - generator.writeObjectField(VALUE_FIELD, primitive.getValue()); - generator.writeEndObject(); - } else { - - if (nodeName == null) { - generator.writeObject(primitive.getValue()); - } else { -// if (StringUtils.isNotBlank(nodeName.getNamespaceURI()) -// && !nodeName.getNamespaceURI().equals(objectNs)) { -// objectNs = nodeName.getNamespaceURI(); -// } - generator.writeObjectField(nodeName.getLocalPart(), primitive.getValue()); - } - } - } - - private String serializeNsIfNeeded(QName subNodeName, String globalNamespace, JsonGenerator generator) throws JsonGenerationException, IOException{ - if (subNodeName == null){ - return globalNamespace; - } - String subNodeNs = subNodeName.getNamespaceURI(); - if (StringUtils.isNotEmpty(subNodeNs)){ - if (!subNodeNs.equals(globalNamespace)){ - globalNamespace = subNodeNs; - generator.writeStringField(PROP_NAMESPACE, globalNamespace); - - } - } - return globalNamespace; - } - //------------------------END OF METHODS FOR SERIALIZATION ------------------------------- - - //------------------------ METHODS FOR PARSING ------------------------------------------- - public XNode parseObject(JsonParser parser) throws SchemaException{ - - ObjectMapper mapper = new ObjectMapper(); - SimpleModule sm = new SimpleModule(); - sm.addDeserializer(QName.class, new QNameDeserializer()); - sm.addDeserializer(ItemPath.class, new ItemPathDeserializer()); - - mapper.registerModule(sm); - - JsonNode obj = null; - try { -// String globalNs = (String) parser.getObjectId(); - parser.setCodec(mapper); - -// TokenBuffer tb = parser.readValueAs(TokenBuffer.class); -// JsonParser p = tb.asParser(); -// System.out.println("======================== " + p.getObjectId()); -// System.out.println("======================== " + p.getTypeId()); -// tb. -// tb.firstToken().asParser().getCurrentTokenId(); -// JsonToken. -// YAMLFactory f = new YAMLFactory(); -// f. - - int i = parser.getCurrentTokenId(); - //System.out.println("id token : " + i); -// Object o =parser.readValueAsTree(); - - System.out.println("id: " + JsonTokenId.ID_START_OBJECT); - JsonToken t = parser.getCurrentToken(); - //System.out.println("cuurent: " + t); - - JsonToken nt = parser.nextToken(); - //System.out.println("cuurent: " + nt); - -// JsonToken t = parser.getCurrentToken(); -// System.out.println("cuurent: " + t); -// mapper.readTree(jp) -// obj = ((YAMLParser)parser).readValueAs(JsonNode.class); - - - - RootXNode xmap = new RootXNode(); - -// Iterator> fields = obj.fields(); -// obj. - -// nt. -// while (fields.hasNext()){ -// Entry field = fields.next(); -// String fieldName = field.getKey(); -// -// JsonNode globalNsNode = field.getValue().get(PROP_NAMESPACE); -// if (globalNsNode == null){ -// throw new SchemaException("No global ns"); -// } -// String globalNs = globalNsNode.asText(); -// -// if (fieldName == null){ -// throw new SchemaException("cannot obtain type"); -// } -// - QName rootElement = new QName("http://midpoint.evolveum.com/xml/ns/test/foo-1.xsd", "user"); -// ((RootXNode) xmap).setRootElementName(rootElement); - - parseJsonObject(xmap, rootElement, null, parser); - -// } - return xmap; - } catch (JsonParseException e) { - throw new SchemaException("Cannot parse from JSON: " + e.getMessage(), e); - } catch (JsonMappingException e) { - throw new SchemaException("Cannot parse from JSON: " + e.getMessage(), e); - } catch (IOException e) { - throw new SchemaException("Cannot parse from JSON: " + e.getMessage(), e); - } - } - - private void parseJsonObject(XNode xmap, QName propertyName, final JsonNode obj, final JsonParser parser) throws SchemaException { - try{ - JsonToken token = parser.nextToken(); - //System.out.println("token " + token); - JsonToken current = parser.getCurrentToken(); - //System.out.println("current " + current); - JsonToken value = parser.nextValue(); - //System.out.println("value " + value); - if (token == null){ - token = parser.nextToken(); - } - switch (token){ - case START_OBJECT: - parseToMap(obj, propertyName, xmap, parser); - break; - case START_ARRAY: - parseToList(obj, propertyName, xmap, parser); - break; - default: - parseToPrimitive(obj, propertyName, xmap, parser); - } - } catch (Exception e){ - //TODO: - throw new SchemaException("Error ", e); - } -// switch (obj.getNodeType()){ -// case OBJECT: -// parseToMap(obj, propertyName, xmap, parser); -// break; -// case ARRAY: -// parseToList(obj, propertyName, xmap, parser); -// break; -// default: -// parseToPrimitive(obj, propertyName, xmap, parser); -// } - - } - - private void parseToMap(JsonNode node, QName propertyName, XNode parent, JsonParser parser) throws SchemaException{ - Iterator> fields = node.fields(); - String nsToUse = getNamespace(node, propertyName.getNamespaceURI()); - - MapXNode subMap = new MapXNode(); - if (parent instanceof RootXNode){ - ((RootXNode) parent).setSubnode(subMap); - } else { - addXNode(propertyName, parent, subMap); - } - - while (fields.hasNext()){ - Entry field = fields.next(); - QName childrenName = new QName(nsToUse, field.getKey()); - if (isSpecial(field.getValue())){ - parseSpecial(subMap, childrenName, field.getValue(), parser); - continue; - } - parseJsonObject(subMap, childrenName, field.getValue(), parser); - } - } - - private void parseToList(JsonNode node, QName propertyName, XNode parent, JsonParser parser) throws SchemaException{ - Iterator elements = node.elements(); - ListXNode listNode = new ListXNode(); - addXNode(propertyName, parent, listNode); - while (elements.hasNext()){ - JsonNode element = elements.next(); - if (isSpecial(element)){ - parseSpecial(listNode, propertyName, element, parser); - continue; - } - parseJsonObject(listNode, propertyName, element, parser); - } - } - - private void parseToPrimitive(JsonNode node, QName propertyName, XNode parent, JsonParser parser){ - if (propertyName.getLocalPart().equals(PROP_NAMESPACE)){ - return; - } - PrimitiveXNode primitive = createPrimitiveXNode(node, parser); - addXNode(propertyName, parent, primitive); - } - - private void parseSpecial(XNode xmap, QName propertyName, JsonNode obj, final JsonParser parser) throws SchemaException{ - //System.out.println("special"); - QName typeDefinition = extractTypeName(obj, parser); - - if (typeDefinition != null){ - obj = obj.get(VALUE_FIELD); - } - - PrimitiveXNode primitive = createPrimitiveXNode(obj, parser, typeDefinition); - addXNode(propertyName, xmap, primitive); - } - - //---------------------------END OF METHODS FOR PARSING ---------------------------------------- - - //------------------------------ HELPER METHODS ------------------------------------------------ - private PrimitiveXNode createPrimitiveXNode(JsonNode node, JsonParser parser){ - return createPrimitiveXNode(node, parser, null); - } - - private PrimitiveXNode createPrimitiveXNode(JsonNode node, JsonParser parser, QName typeDefinition){ - PrimitiveXNode primitive = new PrimitiveXNode(); - boolean f = parser.canReadObjectId(); - //System.out.println("can read obj id: " + f); - //try{ - //System.out.println("obj id: " + parser.getObjectId()); - //System.out.println("type id: " + parser.getTypeId()); - // - //} catch (Exception e){ - // throw new IllegalStateException(e); - //} - ValueParser vp = new JsonValueParser(parser, node); - primitive.setValueParser(vp); - if (typeDefinition != null){ - primitive.setExplicitTypeDeclaration(true); - primitive.setTypeQName(typeDefinition); - } - return primitive; - } - - private String getNamespace(JsonNode obj, String ns){ - JsonNode objNsNode = obj.get(PROP_NAMESPACE); - - if (objNsNode == null){ - return ns; - } - - String objNs = objNsNode.asText(); - - if (!objNs.equals(ns)){ - return objNs; - } - return ns; - } - - private boolean isSpecial(JsonNode next){ - if (next.isObject()) { - Iterator nextFields = next.fieldNames(); - while (nextFields.hasNext()) { - String str = nextFields.next(); - if (str.startsWith("@") && !str.equals(PROP_NAMESPACE)) { - return true; - } - } - } - return false; - } - - private QName extractTypeName(JsonNode node, JsonParser parser) throws SchemaException{ - if (node.has(TYPE_DEFINITION)){ - //System.out.println("has type def"); - JsonNode typeDef = node.get(TYPE_DEFINITION); - ObjectMapper m = (ObjectMapper) parser.getCodec(); - ObjectReader r = m.reader(QName.class); - - try { - return r.readValue(typeDef); - } catch (IOException e) { - throw new SchemaException("Cannot extract type definition " + e.getMessage(), e); - } - } - return null; - } - - - private void addXNode(QName fieldName, XNode parent, XNode children) { - if (parent instanceof MapXNode) { - ((MapXNode) parent).put(fieldName, children); - } else if (parent instanceof ListXNode) { - ((ListXNode) parent).add(children); - } - } - - public abstract JsonGenerator createGenerator(StringWriter out) throws SchemaException; -// private JsonGenerator createJsonGenerator(StringWriter out) throws SchemaException{ -// try { -// JsonFactory factory = new JsonFactory(); -// JsonGenerator generator = factory.createGenerator(out); -// generator.setPrettyPrinter(new DefaultPrettyPrinter()); -// generator.setCodec(configureMapperForSerialization()); -// return generator; -// } catch (IOException ex){ -// throw new SchemaException("Schema error during serializing to JSON.", ex); -// } -// -// } -// -// private ObjectMapper configureMapperForSerialization(){ -// ObjectMapper mapper = new ObjectMapper(); -// mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); -// mapper.setSerializationInclusion(Include.NON_NULL); -// mapper.registerModule(createSerializerModule()); -// return mapper; -// } -// -// private Module createSerializerModule(){ -// SimpleModule module = new SimpleModule("MidpointModule", new Version(0, 0, 0, "aa")); -// module.addSerializer(QName.class, new QNameSerializer()); -// module.addSerializer(PolyString.class, new PolyStringSerializer()); -// module.addSerializer(ItemPath.class, new ItemPathSerializer()); -// module.addSerializer(JAXBElement.class, new JaxbElementSerializer()); -// return module; -// } - - - -} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/PrismJasonProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/PrismJasonProcessor.java index 66d4d10ab25..e69de29bb2d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/PrismJasonProcessor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/json/PrismJasonProcessor.java @@ -1,836 +0,0 @@ -/* - * Copyright (c) 2013-2015 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.evolveum.midpoint.prism.json; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; - -import javax.xml.namespace.QName; - -import org.w3c.dom.Element; - -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismReference; -import com.evolveum.midpoint.prism.PrismReferenceDefinition; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.parser.json.PolyStringSerializer; -import com.evolveum.midpoint.prism.parser.json.QNameDeserializer; -import com.evolveum.midpoint.prism.parser.json.QNameSerializer; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.schema.PrismSchema; -import com.evolveum.midpoint.prism.schema.SchemaRegistry; -import com.evolveum.midpoint.prism.util.JavaTypeConverter; -import com.evolveum.midpoint.prism.util.PrismUtil; -import com.evolveum.midpoint.prism.xml.XsdTypeMapper; -import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.core.JsonEncoding; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.PrettyPrinter; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; -import com.fasterxml.jackson.module.jaxb.deser.DomElementJsonDeserializer; - -public class PrismJasonProcessor { - - private SchemaRegistry schemaRegistry; - private PrismContext prismContext; -// private PrismSchema prismSchema; - - - public PrismSchema getPrismSchema(Class clazz) { - - return schemaRegistry.findSchemaByCompileTimeClass(clazz); -// -// return prismSchema; - } - - public PrismContext getPrismContext() { - return prismContext; - } - - public void setPrismContext(PrismContext prismContext) { - this.prismContext = prismContext; - } - - public void setSchemaRegistry(SchemaRegistry schemaRegistry) { - this.schemaRegistry = schemaRegistry; - } - - public SchemaRegistry getSchemaRegistry() { - return schemaRegistry; - } - - private PrismSchema prismSchema = null; - - public PrismObject parseObject(File file, Class valueType) throws IOException, SchemaException{ - ObjectMapper mapper = new ObjectMapper(); -// mapper.configure(Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, false); - -// SimpleModule module = new SimpleModule("MidpointModule", new Version(0, 0, 0, "aa")); -// module.addDeserializer(QName.class, new QNameDeserializer()); -// module.addSerializer(PolyString.class, new PolyStringSerializer()); -//// module.addSerializer(Node.class, new DOMSerializer()); -// module.addSerializer(Element.class, new DOMSerializer()); -// mapper.registerModule(module); - -// mapper.configure(Feature.UNWRAP_ROOT_VALUE, true); - ObjectReader reader = mapper.reader(valueType); - - JsonFactory factory = new JsonFactory(); - factory.createJsonParser(file); -// reader. - - T object = reader.readValue(file); - PrismObjectDefinition def = schemaRegistry.findObjectDefinitionByCompileTimeClass(valueType); - - PrismObject prismObj = object.asPrismObject(); -// prismObj.setDefinition(def); -// prismObj.applyDefinition(def); -// prismContext.adopt(prismObj.asObjectable()); - - //System.out.println("object: \n" + prismObj.debugDump()); - - return prismObj; - } - - private void serializeToJson(PrismContainerValue val, JsonGenerator generator) throws JsonGenerationException, IOException{ -// generator.writeStartObject(); -// if (val != null && val.getPath() != null && val.getPath().last() != null){ -//// generator.writeFieldName(ItemPath.getName(val.getPath().last()).getLocalPart()); -// -// }else{ -// generator.writeFieldName(val.getContainer().getCompileTimeClass().getSimpleName()); -// } - generator.writeStartObject(); - - for (Item item : val.getItems()){ -// generator.writeFieldName(item.getElementName().getLocalPart()); - - if (item.isEmpty()){ - continue; - } - generator.writeFieldName(item.getElementName().getLocalPart()); - -// PrismConstants. - if (item.getValues().size() > 1){ - generator.writeStartArray(); - for (PrismValue v : item.getValues()){ - serializeValue(v, generator); - } - generator.writeEndArray(); - continue; - } -// - serializeValue(item.getValues().iterator().next(), generator); - -// } -// generator.writeEndArray(); - } - generator.writeEndObject(); - } - - private void serializeValue(PrismValue v, JsonGenerator generator) throws JsonProcessingException, IOException{ - if (v instanceof PrismPropertyValue){ - Object o = ((PrismPropertyValue) v).getValue(); - serializeProperty(o, generator); -// generator.writeObject(o); -// generator.writeString("\n"); - } - if (v instanceof PrismReferenceValue){ - generator.writeStartObject(); - String oid = ((PrismReferenceValue) v).getOid(); - generator.writeFieldName("oid"); - generator.writeString(oid); -// generator.writeString("\n"); - QName qname = ((PrismReferenceValue) v).getTargetType(); - if (qname != null){ - generator.writeFieldName("taretType"); - generator.writeString(qname.toString()); - - } - generator.writeEndObject(); -// generator.writeString("\n"); - } - if (v instanceof PrismContainerValue){ -// generator.writeString("\n"); - serializeToJson((PrismContainerValue) v, generator); -// generator.writeEndObject(); - } - } - - private void serializeProperty(Object o, JsonGenerator generator) throws JsonGenerationException, IOException{ -// if (o instanceof PolyString){ -// generator.writeStartObject(); -// generator.writeStringField("orig", ((PolyString) o).getOrig()); -// generator.writeStringField("norm", ((PolyString) o).getNorm()); -// generator.writeEndObject(); -// } else if (o instanceof Element){ -// serializeElementProperty(o, generator); -// } else if (o instanceof QName){ -// generator.writeStartObject(); -// generator.writeStringField("namespace", ((QName) o).getNamespaceURI()); -// generator.writeStringField("localPart", ((QName) o).getLocalPart()); -// generator.writeEndObject(); -// } else{ -//// TypeVariable[] typeVariable = o.getClass().getTypeParameters(); -// if (containsElement(o)){ -// -// } else{ - generator.writeObject(o); -// } -// } - } - - private boolean containsElement(Object o){ - Field[] fields = o.getClass().getFields(); - for (int i = 0; i < fields.length; i++){ - Field field = fields[i]; - if (Element.class.isAssignableFrom(field.getType())){ - return true; - } - } - return false; - } - - private void serializeElementProperty(Object o, JsonGenerator generator) throws JsonGenerationException, IOException { - Element rootNode = (Element) o; - QName root = DOMUtil.getQName(rootNode); - -// generator.writeFieldName(root.getLocalPart()); - generator.writeStartObject(); - List children = DOMUtil.getChildElements(rootNode, root); - for (Element child : children){ -// Node child = children.item(i); - - if (DOMUtil.hasChildElements(child)){ - serializeElementProperty(child, generator); - } else{ - QName childName = DOMUtil.getQName(child); -// if (child.getNodeType() != Node.ATTRIBUTE_NODE){ - generator.writeStringField(childName.getLocalPart(), child.getTextContent()); -// } - } - - } - generator.writeEndObject(); - - } - - public void serializeToJson(PrismObject object, OutputStream out) throws IOException, SchemaException{ - ObjectMapper mapper = new ObjectMapper(); - SimpleModule module = new SimpleModule("MidpointModule", new Version(0, 0, 0, "aa")); -// JaxbAnnotationModule module = new JaxbAnnotationModule(); -// SetupContext ctx = -// module.setupModule(mapper); - module.addSerializer(QName.class, new QNameSerializer()); - module.addSerializer(PolyString.class, new PolyStringSerializer()); -// module.addSerializer(Node.class, new DOMSerializer()); -// module.addSerializer(Element.class, new DOMSerializer()); - -// JaxbElementSerializer jaxbSerializer = new JaxbElementSerializer(); -// module.addSerializer(JAXBElement.class, jaxbSerializer); -// module.addSerializer(DataHandler.class, new DataHandlerJsonSerializer()); -// module.addSerializer(Element.class, new DomElementJsonSerializer()); - mapper.registerModule(module); - -// jaxbModule.addSerializer(new DataHandlerJsonSerializer()); -// jaxbModule.addSerializer(Element.class, new DomElementJsonSerializer()); -// JaxbAnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); -// mapper.getSerializationConfig().setAnnotationIntrospector(introspector); - mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector()); -// mapper.registerModule(jaxbModule); -// mapper.configure(com.fasterxml.jackson.c, state) -// Feature. - mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); - mapper.setSerializationInclusion(Include.NON_NULL); -// mapper.configure(SerializationFeature.WRITE_NULL_PROPERTIES, false); -// mapper.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRITE_EMPTY_JSON_ARRAYS, false); -// mapper.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true); - - ObjectWriter writer = mapper.writer(); -// JsonGenerator jsonGenerator = new J - JsonFactory factory = new JsonFactory(); -// mapper.configure(org.codehaus.jackson.JsonGenerator.Feature.FLUSH_PASSED_TO_STREAM, true); - JsonGenerator generator = factory.createGenerator(out , JsonEncoding.UTF8); - - PrettyPrinter pp = new DefaultPrettyPrinter(); -// pp. - generator.setPrettyPrinter(pp); - generator.setCodec(mapper); -// generator.writeObject(object.asObjectable()); - - -for (PrismContainerValue pcv : object.getValues()){ - - -serializeToJson(pcv, generator); - - } -generator.flush(); -generator.close(); - } - - JsonParser parser = null; - public PrismObject parseObject(InputStream inputStream, Class valueType) throws IOException, SchemaException{ - - ObjectMapper mapper = new ObjectMapper(); - JsonNode obj = null; - try { - - JsonFactory facotry = new JsonFactory(); - parser = facotry.createJsonParser(inputStream); - parser.setCodec(mapper); - - obj = parser.readValueAs(JsonNode.class); - - PrismSchema schema = getPrismSchema(valueType); - - prismSchema = schema; - if (schema == null) { - throw new SchemaException("No schema for namespace " + valueType); - } - - JsonNode type = obj.get("_type"); - String typeValue = null; - - PrismObjectDefinition objectDefinition = null; - if (type != null){ - typeValue = type.asText(); -// QName objQname = new QName(defaultNamespace, typeValue); -// objectDefinition = schema.findObjectDefinitionByElementName(valueType); - } else { - objectDefinition = schema.findObjectDefinitionByCompileTimeClass(valueType); - } - - -// if (objectDefinition == null) { -// throw new SchemaException("No definition found for type " + new QName(defaultNamespace, typeValue) + " (as defined by xsi:type)"); -// } - PrismObject object = parseObject(obj, objectDefinition.getName(), objectDefinition.getNamespace(), objectDefinition); - return object; - } catch (JsonParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - throw e; - } catch (JsonMappingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - throw e; - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - throw e; - } - -// return null; - - } - - private PrismObject parseObject(JsonNode jsonObject, QName itemName, String defaultNamespace, - PrismObjectDefinition objectDefinition) throws SchemaException, JsonParseException, JsonMappingException, IOException { - - PrismObject object = (PrismObject) parsePrismContainer(jsonObject, itemName, defaultNamespace, objectDefinition); - - if (jsonObject.findValue("_oid") != null){ - String oid = jsonObject.findValue("_oid").asText(); - object.setOid(oid); - } - - if (jsonObject.findValue("_version") != null){ - - String version = jsonObject.findValue("_version").asText(); - object.setVersion(version); - - } - return object; - } - - private PrismContainer parsePrismContainer(JsonNode jsonObject, QName itemName, String defaultNamespace, PrismContainerDefinition containerDefinition) throws SchemaException, JsonParseException, JsonMappingException, IOException { - PrismContainer container = containerDefinition.instantiate(itemName); - - PrismContainerValue pval = new PrismContainerValue(null, null, container, null, null, prismContext); // TODO set concreteType (if this code would be really used) - - Collection newContainerItems = parsePrismContainerItems(jsonObject, - containerDefinition, defaultNamespace); - addValuesToContainerValue(pval, newContainerItems); - container.add(pval); - - return container; - } - - private void addValuesToContainerValue(PrismContainerValue containerValue, - Collection newContainerItems) throws SchemaException { - for (Item newItem : newContainerItems) { - if (newItem == null){ - //System.out.println("new item name null"); - continue; - } - Item existingItem = containerValue.findItem(newItem.getElementName()); - if (existingItem == null) { - containerValue.add(newItem); - } else { - for (PrismValue newPVal : newItem.getValues()) { - existingItem.add(newPVal.clone()); - } - } - } - } - - protected Collection> parsePrismContainerItems(JsonNode jsonObject, - PrismContainerDefinition containerDefinition, String defaultNamespace) - throws SchemaException, JsonParseException, JsonMappingException, IOException { - - // TODO: more robustness in handling schema violations (min/max - // constraints, etc.) - - Collection> props = new HashSet<>(); - - // Iterate over all the XML elements there. Each element is - // an item value. - Iterator> items = jsonObject.fields(); - -// String namespace = null; -// JsonNode defaultNs = jsonObject.findValue("_ns"); -// if (defaultNs != null){ -// defaultNamespace = defaultNs.getTextValue(); -// } - while (items.hasNext()){ - Entry item = items.next(); - - //not items, will be handled differently -// if (item.getKey() != null && item.getKey().startsWith("_")){ -// continue; -// } -// -// JsonNode ns = item.getValue().findValue("_ns"); -// JsonNode nsw = item.getValue().get("_ns"); -// -// if (nsw != null){ -// defaultNamespace = nsw.getTextValue(); -// } -// -// PrismSchema schema = getPrismSchema(containerDefinition.get); -// ItemDefinition def = prismSchema.findItemDefinition(item.getKey(), containerDefinition.getTypeClass()); - - - if (item.getKey().equals("id") || item.getKey().equals("any")){ - continue; - } - QName itemQName = new QName(defaultNamespace, item.getKey()); - - ItemDefinition def = locateItemDefinition(containerDefinition, itemQName); - - if (def == null) { - if (containerDefinition.isRuntimeSchema()) { - // No definition for item, but the schema is runtime. the - // definition may come later. - // Null is OK here. - } else { -// continue; -// throw new SchemaException("Item " + itemQName + " has no definition", itemQName); - } -// continue; - } - - -// if (item.getValue().isObject()){ -// parsePrismContainerItems(item.getValue(), containerDefinition, defaultNamespace); -// } else{ - Item parsedItem = parseItem(item.getValue(), itemQName, defaultNamespace, def); - props.add(parsedItem); -// } - } - - return props; - } - - - private ItemDefinition locateItemDefinition( - PrismContainerDefinition containerDefinition, QName itemQname) - throws SchemaException { - ItemDefinition def = containerDefinition.findItemDefinition(itemQname); - if (def != null) { - return def; - } - -// if (containerDefinition.isRuntimeSchema()) { -// // Try to locate global definition in any of the schemas -// def = getPrismContext().getSchemaRegistry().resolveGlobalItemDefinition(itemQname); -// } - return def; - } - - private ItemDefinition locateItemDefinition( - PrismContainerDefinition containerDefinition, ItemPath itemQname) - throws SchemaException { - ItemDefinition def = containerDefinition.findItemDefinition(itemQname); - if (def != null) { - return def; - } - -// if (containerDefinition.isRuntimeSchema()) { -// // Try to locate global definition in any of the schemas -// def = getPrismContext().getSchemaRegistry().resolveGlobalItemDefinition(itemQname); -// } - return def; - } - - public Item parseItem(JsonNode values, QName itemName, String defaultNamespace, ItemDefinition def) - throws SchemaException, JsonParseException, JsonMappingException, IOException { - if (def == null) { - // Assume property in a container with runtime definition - return (Item) parsePrismPropertyRaw(values, itemName); - } - if (def instanceof PrismContainerDefinition) { - return (Item) parsePrismContainer(values, itemName, defaultNamespace, (PrismContainerDefinition) def); - } else if (def instanceof PrismPropertyDefinition) { - return (Item) parsePrismProperty(values, itemName, (PrismPropertyDefinition) def); - } - if (def instanceof PrismReferenceDefinition) { - return (Item) parsePrismReference(values, itemName, (PrismReferenceDefinition) def); - } else { - throw new IllegalArgumentException("Attempt to parse unknown definition type " + def.getClass().getName()); - } - } - - private PrismProperty parsePrismPropertyRaw(JsonNode values, QName itemName) - throws SchemaException { - return null; - } - - public PrismProperty parsePrismProperty(JsonNode values, QName propName, - PrismPropertyDefinition propertyDefinition) throws SchemaException, JsonParseException, JsonMappingException, IOException { - if (values.isNull()) { - return null; - } - PrismProperty prop = propertyDefinition.instantiate(propName); - - if (!propertyDefinition.isMultiValue() && values.isArray()) { - throw new SchemaException("Attempt to store multiple values in single-valued property " + propName); - } - if (values.isArray()){ - Iterator vals = values.elements(); - while (vals.hasNext()){ - JsonNode val = vals.next(); - if (val != null){ - T realValue = parsePrismPropertyRealValue(val, propertyDefinition); - if (realValue != null) { - prop.add(new PrismPropertyValue(realValue)); - } - } - } -// } else if (values.isObject()){ -// Iterator> vals = values.getFields(); -// while (vals.hasNext()){ -// Entry val = vals.next(); -// -// if (val != null){ -// if (val.getValue().isObject()){ -// QName itemQName = new QName(propertyDefinition.getNamespace(), val.getKey()); -// ItemDefinition def = locateItemDefinition(containerDefinition, new ItemPath(prop.getElementName(), itemQName)); -// T realValue = parseAtomicValue(val.getValue(), (PrismPropertyDefinition) def); -// if (realValue != null) { -// prop.add(new PrismPropertyValue(realValue)); -// } -// }else{ -// T realValue = parseAtomicValue(values, propertyDefinition); -// if (realValue != null) { -// prop.add(new PrismPropertyValue(realValue)); -// } -// } -// } -// } - } else { - if (values != null){ - T realValue = parsePrismPropertyRealValue(values, propertyDefinition); - if (realValue != null) { - prop.add(new PrismPropertyValue(realValue)); - } - } - } - - return prop; - } - - public T parsePrismPropertyRealValue(JsonNode valueElement, PrismPropertyDefinition propertyDefinition) - throws SchemaException, JsonParseException, JsonMappingException, IOException { - QName typeName = propertyDefinition.getTypeName(); -// PrismJaxbProcessor jaxbProcessor = getPrismContext().getPrismJaxbProcessor(); - Object realValue = null; - - if (propertyDefinition.getTypeName().getLocalPart().equals("any")){ - return null; - } - - Class expectedJavaType = XsdTypeMapper.toJavaType(propertyDefinition.getTypeName()); - if (expectedJavaType == null) { - expectedJavaType = (Class) schemaRegistry.determineCompileTimeClass(propertyDefinition.getTypeName()); - } - - - Object value = null; - ObjectMapper mapper = new ObjectMapper(); - SimpleModule module = new SimpleModule("asd", new Version(0, 0, 0, "vvv")); - module.addDeserializer(QName.class, new QNameDeserializer()); - module.addDeserializer(Element.class, new DomElementJsonDeserializer()); -// module.addDeserializer(, deser) -// JaxbElementDeserializer jaxbDeserializer = new JaxbElementDeserializer(); -// jaxbDeserializer.setExpectedClass(expectedJavaType); -// jaxbDeserializer.setNode(valueElement); -// jaxbDeserializer.setPrismSchema(prismSchema); -// module.addDeserializer(JAXBElement.class, jaxbDeserializer); -// module.addDeserializer(Element.class, new DOMDeserializer()); - mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector()); - mapper.registerModule(module); -// JaxbAnnotationModule jaxbModule = new JaxbAnnotationModule(); -// mapper.registerModule(jaxbModule); -// mapper. -// module. - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, false); -// mapper.configure(Feature.USE_GETTERS_AS_SETTERS, true); - - //System.out.println("expected java type: " + expectedJavaType.getSimpleName()); -// PrismJaxbProcessor jaxbProcessor = prismContext.getPrismJaxbProcessor(); - -// mapper.getTypeFactory(). - - - -// if (jaxbProcessor.canConvert(expectedJavaType)){ -// ObjectReader r = mapper.reader(JAXBElement.class); -// value = r.readValue(valueElement); -// JAXBElement e = new JAXBElement(typeName, expectedJavaType, value); -// System.out.println("cal convert"); -// value = r.readValue(valueElement); -// } else - if (typeName.equals(PolyStringType.COMPLEX_TYPE)) { - ObjectReader r = mapper.reader(PolyStringType.class); - - value = r.readValue(valueElement); -// } -// else if (Element.class.isAssignableFrom(expectedJavaType)){ -// Document doc = DOMUtil.getDocument(); -// readElementValue(doc, valueElement, null); - } else{ - ObjectReader r = mapper.reader(expectedJavaType); - value = r.readValue(valueElement); - } -// Object value = null; -// if (expectedJavaType.equals(PolyString.class)){ -// if (valueElement.isObject()){ -// JsonNode orig = valueElement.get("orig"); -// JsonNode norm = valueElement.get("norm"); -// value = new PolyString(orig.asText(), norm.asText()); -// System.out.println("orig: " + orig.asText() +" norm: " + norm.asText()); -// } -// -// } -// - realValue = JavaTypeConverter.convert(expectedJavaType, value); - - postProcessPropertyRealValue((T) realValue); - return (T) realValue; - } - -// private void readElementValue(Document doc, JsonNode valueElement, Element root) { -// Iterator> elements = valueElement.getFields(); -// while (elements.hasNext()){ -// Entry element = elements.next(); -// Element e = doc.createElement(element.getKey()); -// if (root != null){ -// root.appendChild(e); -// } -// if (element.getValue().isObject()){ -// readElementValue(doc, element.getValue(), e); -// } else{ -// e.setTextContent(valueElement.asText()); -// } -// -// } -// -// } - - private void postProcessPropertyRealValue(T realValue) { - if (realValue == null) { - return; - } - PrismUtil.recomputeRealValue(realValue, getPrismContext()); - } - - public PrismReference parsePrismReference(JsonNode values, QName propName, - PrismReferenceDefinition referenceDefinition) throws SchemaException, JsonParseException, JsonMappingException, IOException { - if (values == null) { - return null; - } - PrismReference ref = referenceDefinition.instantiate(); - - if (!referenceDefinition.isMultiValue() && values.isArray()) { - throw new SchemaException("Attempt to store multiple values in single-valued property " + propName); - } - - if (propName.equals(referenceDefinition.getName())) { - // This is "real" reference (oid type and nothing more) - ref.add(parseReferenceValue(values, referenceDefinition.getNamespace())); - } else { - // This is a composite object (complete object stored inside - // reference) - ref.add(parseReferenceAsCompositeObject(values, referenceDefinition)); - } - return ref; - } - - public PrismReferenceValue parseReferenceValue(JsonNode value, String defaultNs) { - String oid = null; - if (value.get("_oid") != null){ - oid = value.get("_oid").asText(); - } - - - QName type = null; - if (value.get("_type") != null){ - type = new QName(defaultNs, value.get("_type").asText()); - } -// if (type != null) { -// DOMUtil.validateNonEmptyQName(type, " in reference type in " + DOMUtil.getQName(element)); -// } - PrismReferenceValue refVal = new PrismReferenceValue(oid); - refVal.setTargetType(type); - - String description = null; - if (value.get("description") != null){ - description = value.get("description").asText(); - } - - refVal.setDescription(description); -// QName relationAttribute = DOMUtil.getQNameAttribute(element, PrismConstants.ATTRIBUTE_RELATION_LOCAL_NAME); -// if (relationAttribute != null) { -// DOMUtil.validateNonEmptyQName(relationAttribute, " in reference type in " + DOMUtil.getQName(element)); -// } -// refVal.setRelation(relationAttribute); - -// Element descriptionElement = DOMUtil.getChildElement(element, PrismConstants.ELEMENT_DESCRIPTION_LOCAL_NAME); -// if (descriptionElement != null) { -// refVal.setDescription(descriptionElement.getTextContent()); -// } -// Element filterElement = DOMUtil.getChildElement(element, PrismConstants.ELEMENT_FILTER_LOCAL_NAME); -// if (filterElement != null) { -// refVal.setFilter(DOMUtil.getFirstChildElement(filterElement)); -// } - - return refVal; - } - - private PrismReferenceValue parseReferenceAsCompositeObject(JsonNode valueElement, - PrismReferenceDefinition referenceDefinition) throws SchemaException, JsonParseException, JsonMappingException, IOException { - QName targetTypeName = referenceDefinition.getTargetTypeName(); - PrismObjectDefinition schemaObjectDefinition = null; - if (targetTypeName != null) { - schemaObjectDefinition = getPrismContext().getSchemaRegistry().findObjectDefinitionByType(targetTypeName); - } - - PrismObject compositeObject = null; - try { -// if (valueElement instanceof Element) { -// Element valueDomElement = (Element) valueElement; - - JsonNode type = valueElement.get("_type"); - String typeVal = null; - if (type != null){ - typeVal = type.asText(); - } - - if (typeVal != null){ - QName itemName = new QName(referenceDefinition.getNamespace(), typeVal); - PrismObjectDefinition schemaObjectDefinitionFromXsiType = schemaRegistry.findObjectDefinitionByElementName(new QName(referenceDefinition.getNamespace(), typeVal)); - if (schemaObjectDefinitionFromXsiType != null) { - schemaObjectDefinition = schemaObjectDefinitionFromXsiType; - } - } - -// if (schemaObjectDefinition == null) { -// compositeObject = parseObject(valueElement); -// } else { - compositeObject = parseObject(valueElement, targetTypeName, referenceDefinition.getNamespace(), schemaObjectDefinition); -// } -// } else if (valueElement instanceof JAXBElement) { -// // This must be complete JAXB object -// JAXBElement jaxbElement = (JAXBElement) valueElement; -// Objectable objectable = jaxbElement.getValue(); -// compositeObject = objectable.asPrismObject(); -// -// PrismObjectDefinition schemaObjectDefinitionFromJaxbType = findDefinitionFromJaxbType(jaxbElement); -// if (schemaObjectDefinitionFromJaxbType != null) { -// schemaObjectDefinition = schemaObjectDefinitionFromJaxbType; -// } -// -// if (schemaObjectDefinition == null) { -// getPrismContext().adopt(objectable); -// } else { -// compositeObject.revive(getPrismContext()); -// compositeObject.applyDefinition(schemaObjectDefinition); -// } -// } - } catch (SchemaException e) { - throw new SchemaException(e.getMessage() + " while parsing composite object in reference element " - + referenceDefinition.getCompositeObjectElementName(), e); - } - - PrismReferenceValue refVal = new PrismReferenceValue(); - refVal.setObject(compositeObject); - return refVal; - } -} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalParsingMode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalParsingMode.java new file mode 100644 index 00000000000..d03ff0282e9 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalParsingMode.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex; + +/** + * @author mederly + */ +public enum LexicalParsingMode { + + // TODO documentation + STRICT, LAX; +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalProcessor.java new file mode 100644 index 00000000000..1aaab6a06ef --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalProcessor.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.evolveum.midpoint.prism.lex; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.ParserSource; +import com.evolveum.midpoint.prism.ParsingContext; +import com.evolveum.midpoint.prism.SerializationContext; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Takes care of converting between XNode tree and specific lexical representation (XML, JSON, YAML). As a special case, + * NullLexicalProcessor uses XNode tree itself as a lexical representation. + * + * @author semancik + * + */ +public interface LexicalProcessor { + + @NotNull + RootXNode read(@NotNull ParserSource source, @NotNull ParsingContext parsingContext) throws SchemaException, IOException; + + @NotNull + List readObjects(ParserSource source, ParsingContext parsingContext) throws SchemaException, IOException; + + /** + * Checks if the processor can read from a given file. (Guessed by file extension, for now.) + * Used for autodetection of language. + */ + boolean canRead(@NotNull File file) throws IOException; + + /** + * Checks if the processor can read from a given string. Note this is only an approximative information (for now). + * Used for autodetection of language. + */ + boolean canRead(@NotNull String dataString); + + /** + * Serializes a root node into XNode tree. + */ + @NotNull + T write(@NotNull RootXNode xnode, @Nullable SerializationContext serializationContext) throws SchemaException; + + /** + * Serializes a non-root node into XNode tree. + * So, xnode SHOULD NOT be a root node (at least for now). + * + * TODO consider removing - replacing by the previous form. + */ + @NotNull + T write(@NotNull XNode xnode, @NotNull QName rootElementName, @Nullable SerializationContext serializationContext) throws SchemaException; + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalProcessorRegistry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalProcessorRegistry.java new file mode 100644 index 00000000000..edfa1151ec4 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalProcessorRegistry.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.lex.dom.DomLexicalProcessor; +import com.evolveum.midpoint.prism.lex.json.JsonLexicalProcessor; +import com.evolveum.midpoint.prism.lex.json.NullLexicalProcessor; +import com.evolveum.midpoint.prism.lex.json.YamlLexicalProcessor; +import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.exception.SystemException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static com.evolveum.midpoint.prism.PrismContext.LANG_JSON; +import static com.evolveum.midpoint.prism.PrismContext.LANG_XML; +import static com.evolveum.midpoint.prism.PrismContext.LANG_YAML; + +/** + * @author mederly + */ +public class LexicalProcessorRegistry { + + private final Map parserMap; + + private final DomLexicalProcessor domLexicalProcessor; + private final NullLexicalProcessor nullLexicalProcessor; + + public LexicalProcessorRegistry(SchemaRegistry schemaRegistry) { + domLexicalProcessor = new DomLexicalProcessor(schemaRegistry); + nullLexicalProcessor = new NullLexicalProcessor(); + + parserMap = new HashMap<>(); + parserMap.put(LANG_XML, domLexicalProcessor); + parserMap.put(LANG_JSON, new JsonLexicalProcessor()); + parserMap.put(LANG_YAML, new YamlLexicalProcessor()); + } + + @NotNull + private LexicalProcessor findProcessor(File file) throws IOException { + for (Map.Entry entry: parserMap.entrySet()) { + LexicalProcessor aLexicalProcessor = entry.getValue(); + if (aLexicalProcessor.canRead(file)) { + return aLexicalProcessor; + } + } + throw new SystemException("No lexical processor for file '"+file+"' (autodetect)"); + } + + @NotNull + private LexicalProcessor findProcessor(@NotNull String data){ + for (Map.Entry entry: parserMap.entrySet()) { + LexicalProcessor aLexicalProcessor = entry.getValue(); + if (aLexicalProcessor.canRead(data)) { + return aLexicalProcessor; + } + } + throw new SystemException("No lexical processor for data '"+ DebugUtil.excerpt(data,16)+"' (autodetect)"); + } + + @NotNull + public DomLexicalProcessor domProcessor() { + return domLexicalProcessor; + } + + @NotNull + public LexicalProcessor processorFor(String language) { + LexicalProcessor lexicalProcessor = parserMap.get(language); + if (lexicalProcessor == null) { + throw new SystemException("No lexical processor for language '"+language+"'"); + } + return (LexicalProcessor) lexicalProcessor; + } + + @NotNull + public LexicalProcessor findProcessor(@NotNull ParserSource source) throws IOException { + if (source instanceof ParserXNodeSource) { + return nullLexicalProcessor; + } else if (source instanceof ParserElementSource) { + return processorFor(LANG_XML); + } else if (source instanceof ParserFileSource) { + return findProcessor(((ParserFileSource) source).getFile()); + } else if (source instanceof ParserStringSource) { + return findProcessor(((ParserStringSource) source).getData()); + } else { + throw new IllegalArgumentException("Cannot determine lexical processor from " + source.getClass()); + } + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalUtils.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalUtils.java new file mode 100644 index 00000000000..7629ef4260b --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/LexicalUtils.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex; + +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; + +/** + * @author mederly + */ +public class LexicalUtils { + + @NotNull + public static RootXNode createRootXNode(XNode xnode, QName rootElementName) { + if (xnode instanceof RootXNode) { + return (RootXNode) xnode; + } else { + RootXNode xroot = new RootXNode(rootElementName); + xroot.setSubnode(xnode); + return xroot; + } + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/dom/DomLexicalProcessor.java similarity index 78% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomParser.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/dom/DomLexicalProcessor.java index 866b29e3654..86309bab73a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomParser.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/dom/DomLexicalProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,113 +13,114 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.prism.parser; +package com.evolveum.midpoint.prism.lex.dom; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.midpoint.prism.lex.LexicalProcessor; +import com.evolveum.midpoint.prism.lex.LexicalUtils; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.prism.xnode.*; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.namespace.QName; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.xml.namespace.QName; +public class DomLexicalProcessor implements LexicalProcessor { -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.Validate; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import com.evolveum.midpoint.prism.PrismConstants; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.schema.SchemaRegistry; -import com.evolveum.midpoint.prism.xml.XmlTypeConverter; -import com.evolveum.midpoint.prism.xnode.ListXNode; -import com.evolveum.midpoint.prism.xnode.MapXNode; -import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; -import com.evolveum.midpoint.prism.xnode.RootXNode; -import com.evolveum.midpoint.prism.xnode.SchemaXNode; -import com.evolveum.midpoint.prism.xnode.ValueParser; -import com.evolveum.midpoint.prism.xnode.XNode; -import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.exception.SchemaException; - -public class DomParser implements Parser { - - public static final Trace LOGGER = TraceManager.getTrace(DomParser.class); + public static final Trace LOGGER = TraceManager.getTrace(DomLexicalProcessor.class); private static final QName SCHEMA_ELEMENT_QNAME = DOMUtil.XSD_SCHEMA_ELEMENT; private SchemaRegistry schemaRegistry; - public DomParser(SchemaRegistry schemaRegistry) { + public DomLexicalProcessor(SchemaRegistry schemaRegistry) { super(); this.schemaRegistry = schemaRegistry; } + @Deprecated + public XNode read(File file, ParsingContext parsingContext) throws SchemaException, IOException { + return read(new ParserFileSource(file), parsingContext); + } + + @NotNull @Override - public Collection parseCollection(File file) throws SchemaException, IOException { - Document document = DOMUtil.parseFile(file); - return parseCollection(document); + public RootXNode read(@NotNull ParserSource source, @NotNull ParsingContext parsingContext) throws SchemaException, IOException { + if (source instanceof ParserElementSource) { + return read(((ParserElementSource) source).getElement()); + } + + InputStream is = source.getInputStream(); + try { + Document document = DOMUtil.parse(is); + return read(document); + } finally { + if (source.closeStreamAfterParsing()) { + IOUtils.closeQuietly(is); + } + } } + @NotNull @Override - public Collection parseCollection(InputStream stream) throws SchemaException, IOException { - Document document = DOMUtil.parse(stream); - return parseCollection(document); + public List readObjects(ParserSource source, ParsingContext parsingContext) throws SchemaException, IOException { + InputStream is = source.getInputStream(); + try { + Document document = DOMUtil.parse(is); + return readObjects(document); + } finally { + if (source.closeStreamAfterParsing()) { + IOUtils.closeQuietly(is); + } + } } - - private Collection parseCollection(Document document) throws SchemaException{ + + private List readObjects(Document document) throws SchemaException{ Element root = DOMUtil.getFirstChildElement(document); // TODO: maybe some check if this is a collection of other objects??? List children = DOMUtil.listChildElements(root); - Collection nodes = new ArrayList(); + List nodes = new ArrayList<>(); for (Element child : children){ - RootXNode xroot = parse(child); + RootXNode xroot = read(child); nodes.add(xroot); } return nodes; } - - @Override - public Collection parseCollection(String dataString) throws SchemaException { - throw new UnsupportedOperationException(); - } - - @Override - public XNode parse(File file) throws SchemaException { - Document document = DOMUtil.parseFile(file); - return parse(document); - } - - @Override - public XNode parse(InputStream stream) throws SchemaException, IOException { - Document document = DOMUtil.parse(stream); - return parse(document); - } - - @Override - public XNode parse(String dataString) throws SchemaException { - Document document = DOMUtil.parseDocument(dataString); - return parse(document); - } - - public RootXNode parse(Document document) throws SchemaException { + @NotNull + public RootXNode read(Document document) throws SchemaException { Element rootElement = DOMUtil.getFirstChildElement(document); - RootXNode xroot = parse(rootElement); - return xroot; + return read(rootElement); } - - public RootXNode parse(Element rootElement) throws SchemaException{ + + @NotNull + public RootXNode read(Element rootElement) throws SchemaException{ RootXNode xroot = new RootXNode(DOMUtil.getQName(rootElement)); extractCommonMetadata(rootElement, xroot); XNode xnode = parseElementContent(rootElement); @@ -181,6 +182,7 @@ public MapXNode parseElementAsMap(Element element) throws SchemaException { /** * Parses the content of the element (the name of the provided element is ignored, only the content is parsed). */ + @Nullable public XNode parseElementContent(Element element) throws SchemaException { if (DOMUtil.isNil(element)) { return null; @@ -332,7 +334,7 @@ private PrimitiveXNode parsePrimitiveElement(final Element element) throw private static T parsePrimitiveElementValue(Element element, QName typeName, XNodeProcessorEvaluationMode mode) throws SchemaException { try { - if (ItemPath.XSD_TYPE.equals(typeName)) { + if (ItemPathType.COMPLEX_TYPE.equals(typeName)) { return (T) parsePath(element); } else if (DOMUtil.XSD_QNAME.equals(typeName)) { return (T) DOMUtil.getQNameValue(element); @@ -383,9 +385,10 @@ private static T parsePrimitiveAttrValue(Attr attr, QName typeName, XNodePro } } - private static ItemPath parsePath(Element element) { + @NotNull + private static ItemPathType parsePath(Element element) { XPathHolder holder = new XPathHolder(element); - return holder.toItemPath(); + return new ItemPathType(holder.toItemPath()); } private SchemaXNode parseSchemaElement(Element schemaElement) { @@ -395,18 +398,12 @@ private SchemaXNode parseSchemaElement(Element schemaElement) { } @Override - public boolean canParse(File file) throws IOException { - if (file == null) { - return false; - } + public boolean canRead(@NotNull File file) throws IOException { return file.getName().endsWith(".xml"); } @Override - public boolean canParse(String dataString) { - if (dataString == null) { - return false; - } + public boolean canRead(@NotNull String dataString) { if (dataString.startsWith(" xprim, QName elementName) throws SchemaException { - DomSerializer serializer = new DomSerializer(this, schemaRegistry); + DomLexicalWriter serializer = new DomLexicalWriter(this, schemaRegistry); return serializer.serializeXPrimitiveToElement(xprim, elementName); } - - public Element serializeXRootToElement(RootXNode xroot) throws SchemaException { - DomSerializer serializer = new DomSerializer(this, schemaRegistry); + + @NotNull + public Element writeXRootToElement(@NotNull RootXNode xroot) throws SchemaException { + DomLexicalWriter serializer = new DomLexicalWriter(this, schemaRegistry); return serializer.serialize(xroot); } - // used only by JaxbDomHack.toAny(..) - hopefully it will disappear soon - @Deprecated - public Element serializeXRootToElement(RootXNode xroot, Document document) throws SchemaException { - DomSerializer serializer = new DomSerializer(this, schemaRegistry); - return serializer.serialize(xroot, document); - } - private Element serializeToElement(XNode xnode, QName elementName) throws SchemaException { Validate.notNull(xnode); Validate.notNull(elementName); @@ -481,7 +462,7 @@ private Element serializeToElement(XNode xnode, QName elementName) throws Schema } else if (xnode instanceof PrimitiveXNode) { return serializeXPrimitiveToElement((PrimitiveXNode) xnode, elementName); } else if (xnode instanceof RootXNode) { - return serializeXRootToElement((RootXNode)xnode); + return writeXRootToElement((RootXNode)xnode); } else if (xnode instanceof ListXNode) { ListXNode xlist = (ListXNode) xnode; if (xlist.size() == 0) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/dom/DomLexicalWriter.java similarity index 90% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/dom/DomLexicalWriter.java index 4f58549e23f..26f13ffa90a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/dom/DomLexicalWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.evolveum.midpoint.prism.parser; +package com.evolveum.midpoint.prism.lex.dom; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.schema.SchemaRegistryImpl; import com.evolveum.midpoint.prism.xml.DynamicNamespacePrefixMapper; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.prism.xnode.ListXNode; @@ -27,26 +29,33 @@ import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import javax.xml.namespace.QName; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; /** * @author semancik * */ -public class DomSerializer { +public class DomLexicalWriter { private Document doc; private Element topElement; private boolean serializeCompositeObjects = false; private SchemaRegistry schemaRegistry; - DomSerializer(DomParser parser, SchemaRegistry schemaRegistry) { + DomLexicalWriter(DomLexicalProcessor parser, SchemaRegistry schemaRegistry) { super(); this.schemaRegistry = schemaRegistry; } @@ -63,7 +72,7 @@ private DynamicNamespacePrefixMapper getNamespacePrefixMapper() { if (schemaRegistry == null) { return null; } - return schemaRegistry.getNamespacePrefixMapper(); + return ((SchemaRegistryImpl) schemaRegistry).getNamespacePrefixMapper(); } private void initialize() { @@ -76,7 +85,8 @@ private void initializeWithExistingDocument(Document document) { topElement = document.getDocumentElement(); // TODO is this ok? } - public Element serialize(RootXNode rootxnode) throws SchemaException { + @NotNull + public Element serialize(@NotNull RootXNode rootxnode) throws SchemaException { initialize(); return serializeInternal(rootxnode, null); } @@ -93,17 +103,15 @@ public Element serializeUnderElement(RootXNode rootxnode, Element parentElement) return serializeInternal(rootxnode, parentElement); } - private Element serializeInternal(RootXNode rootxnode, Element parentElement) throws SchemaException { + @NotNull + private Element serializeInternal(@NotNull RootXNode rootxnode, Element parentElement) throws SchemaException { QName rootElementName = rootxnode.getRootElementName(); Element topElement = createElement(rootElementName, parentElement); if (parentElement != null) { parentElement.appendChild(topElement); } QName typeQName = rootxnode.getTypeQName(); - if (typeQName == null && rootxnode.getSubnode().getTypeQName() != null) { - typeQName = rootxnode.getSubnode().getTypeQName(); - } - if (typeQName != null && !schemaRegistry.hasImplicitTypeDefinition(rootElementName, typeQName)) { + if (typeQName != null && rootxnode.isExplicitTypeDeclaration()) { DOMUtil.setXsiType(topElement, setQNamePrefixExplicitIfNeeded(typeQName)); } XNode subnode = rootxnode.getSubnode(); @@ -201,7 +209,7 @@ private void serializePrimitiveElementOrAttribute(PrimitiveXNode xprim, Eleme } if (typeQName == null) { // this means that either xprim is unparsed or it is empty - if (com.evolveum.midpoint.prism.PrismContext.isAllowSchemalessSerialization()) { + if (com.evolveum.midpoint.prism.PrismContextImpl.isAllowSchemalessSerialization()) { // We cannot correctly serialize without a type. But this is needed // sometimes. So just default to string String stringValue = xprim.getStringValue(); @@ -236,13 +244,14 @@ private void serializePrimitiveElementOrAttribute(PrimitiveXNode xprim, Eleme Element element = null; - if (typeQName.equals(ItemPath.XSD_TYPE)) { - ItemPath itemPath = (ItemPath)xprim.getValue(); - if (itemPath != null) { + if (ItemPathType.COMPLEX_TYPE.equals(typeQName)) { + //ItemPathType itemPathType = //ItemPathType.asItemPathType(xprim.getValue()); // TODO fix this hack + ItemPathType itemPathType = (ItemPathType) xprim.getValue(); + if (itemPathType != null) { if (asAttribute) { throw new UnsupportedOperationException("Serializing ItemPath as an attribute is not supported yet"); } - XPathHolder holder = new XPathHolder(itemPath); + XPathHolder holder = new XPathHolder(itemPathType.getItemPath()); element = holder.toElement(elementOrAttributeName, parentElement.getOwnerDocument()); parentElement.appendChild(element); } @@ -260,7 +269,7 @@ private void serializePrimitiveElementOrAttribute(PrimitiveXNode xprim, Eleme parentElement.appendChild(element); } - if (typeQName.equals(DOMUtil.XSD_QNAME)) { + if (DOMUtil.XSD_QNAME.equals(typeQName)) { QName value = (QName) xprim.getParsedValueWithoutRecording(DOMUtil.XSD_QNAME); value = setQNamePrefixExplicitIfNeeded(value); if (asAttribute) { @@ -311,6 +320,7 @@ private void serializeSchema(SchemaXNode xschema, Element parentElement) { * @param qname element QName * @return created DOM element */ + @NotNull private Element createElement(QName qname, Element parentElement) { String namespaceURI = qname.getNamespaceURI(); if (!StringUtils.isBlank(namespaceURI)) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java new file mode 100644 index 00000000000..a6ec27e3174 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/AbstractJsonLexicalProcessor.java @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex.json; + +import java.io.*; +import java.util.*; +import java.util.Map.Entry; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.ParserSource; +import com.evolveum.midpoint.prism.ParsingContext; +import com.evolveum.midpoint.prism.SerializationContext; +import com.evolveum.midpoint.prism.SerializationOptions; +import com.evolveum.midpoint.prism.lex.LexicalProcessor; +import com.evolveum.midpoint.prism.lex.LexicalUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.core.JsonParser; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.Validate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.prism.xnode.ListXNode; +import com.evolveum.midpoint.prism.xnode.MapXNode; +import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.SchemaXNode; +import com.evolveum.midpoint.prism.xnode.ValueParser; +import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public abstract class AbstractJsonLexicalProcessor implements LexicalProcessor { + + private static final Trace LOGGER = TraceManager.getTrace(AbstractJsonLexicalProcessor.class); + + static final String PROP_NAMESPACE = "@ns"; + static final String PROP_TYPE = "@type"; + static final String PROP_VALUE = "@value"; + + //region Parsing implementation + + @NotNull + @Override + public RootXNode read(@NotNull ParserSource source, @NotNull ParsingContext parsingContext) throws SchemaException, IOException { + InputStream is = source.getInputStream(); + try { + JsonParser parser = createJacksonParser(is); + return parseFromStart(parser, parsingContext); + } finally { + if (source.closeStreamAfterParsing()) { + IOUtils.closeQuietly(is); + } + } + } + + @NotNull + @Override + public List readObjects(ParserSource source, ParsingContext parsingContext) throws SchemaException, IOException { + throw new UnsupportedOperationException("Parse objects not supported for json and yaml."); // why? + } + + protected abstract JsonParser createJacksonParser(String dataString) throws SchemaException; + protected abstract JsonParser createJacksonParser(InputStream stream) throws SchemaException, IOException; + + class JsonParsingContext { + @NotNull final JsonParser parser; + @NotNull final ParsingContext prismParsingContext; + // Definitions of namespaces ('@ns') within maps; to be applied after parsing. + @NotNull final IdentityHashMap defaultNamespaces = new IdentityHashMap<>(); + // Entries that should be skipped when filling-in default namespaces - those that are explicitly set with no-NS ('#name'). + // (Values for these entries are not important. Only key presence is relevant.) + @NotNull final IdentityHashMap, Object> noNamespaceEntries = new IdentityHashMap<>(); + JsonParsingContext(@NotNull JsonParser parser, @NotNull ParsingContext prismParsingContext) { + this.parser = parser; + this.prismParsingContext = prismParsingContext; + } + } + + @NotNull + private RootXNode parseFromStart(JsonParser unconfiguredParser, ParsingContext parsingContext) throws SchemaException { + JsonParsingContext ctx = null; + try { + JsonParser parser = configureParser(unconfiguredParser); + parser.nextToken(); + if (parser.currentToken() == null) { + throw new SchemaException("Nothing to parse: the input is empty."); + } + ctx = new JsonParsingContext(parser, parsingContext); + XNode xnode = parseValue(ctx); + if (!(xnode instanceof MapXNode) || ((MapXNode) xnode).size() != 1) { + throw new SchemaException("Expected MapXNode with a single key; got " + xnode + " instead. At " + getPositionSuffix(ctx)); + } + processDefaultNamespaces(xnode, null, ctx); + processSchemaNodes(xnode); + Entry entry = ((MapXNode) xnode).entrySet().iterator().next(); + RootXNode root = new RootXNode(entry.getKey(), entry.getValue()); + if (entry.getValue() != null) { + root.setTypeQName(entry.getValue().getTypeQName()); // TODO - ok ???? + } + return root; + } catch (IOException e) { + throw new SchemaException("Cannot parse JSON/YAML object: " + e.getMessage() + + (ctx != null ? " At: " + getPositionSuffix(ctx) : ""), + e); + } + } + + // Default namespaces (@ns properties) are processed in the second pass, because they might be present within an object + // at any place, even at the end. + private void processDefaultNamespaces(XNode xnode, String parentDefault, JsonParsingContext ctx) { + if (xnode instanceof MapXNode) { + MapXNode map = (MapXNode) xnode; + final String currentDefault = ctx.defaultNamespaces.containsKey(map) ? ctx.defaultNamespaces.get(map) : parentDefault; + for (Entry entry : map.entrySet()) { + QName fieldName = entry.getKey(); + XNode subnode = entry.getValue(); + if (StringUtils.isNotEmpty(currentDefault) + && StringUtils.isEmpty(fieldName.getNamespaceURI()) + && !ctx.noNamespaceEntries.containsKey(entry)) { + map.qualifyKey(fieldName, currentDefault); + } + processDefaultNamespaces(subnode, currentDefault, ctx); + } + } else if (xnode instanceof ListXNode) { + for (XNode item : (ListXNode) xnode) { + processDefaultNamespaces(item, parentDefault, ctx); + } + } + } + + // Schema nodes can be detected only after namespaces are resolved. + // We simply convert primitive nodes to schema ones. + private void processSchemaNodes(XNode xnode) throws SchemaException, IOException { + if (xnode instanceof MapXNode) { + MapXNode map = (MapXNode) xnode; + XNode schemaNode = null; + for (Entry entry : map.entrySet()) { + QName fieldName = entry.getKey(); + XNode subnode = entry.getValue(); + if (DOMUtil.XSD_SCHEMA_ELEMENT.equals(fieldName)) { + schemaNode = subnode; + } else { + processSchemaNodes(subnode); + } + } + if (schemaNode != null) { + if (schemaNode instanceof PrimitiveXNode) { + PrimitiveXNode primitiveXNode = (PrimitiveXNode) schemaNode ; + if (primitiveXNode.isParsed()) { + throw new SchemaException("Cannot convert from PrimitiveXNode to SchemaXNode: node is already parsed: " + primitiveXNode); + } + SchemaXNode schemaXNode = new SchemaXNode(); + map.replace(DOMUtil.XSD_SCHEMA_ELEMENT, schemaXNode); + schemaXNode.setSchemaElement(((JsonValueParser) primitiveXNode.getValueParser()).asDomElement()); + } else { + throw new SchemaException("Cannot convert 'schema' field to SchemaXNode: not a PrimitiveNode but " + schemaNode); + } + } + } else if (xnode instanceof ListXNode) { + for (XNode item : (ListXNode) xnode) { + processSchemaNodes(item); + } + } + } + + @NotNull + private XNode parseValue(JsonParsingContext ctx) throws IOException, SchemaException { + Validate.notNull(ctx.parser.currentToken()); + + switch (ctx.parser.currentToken()) { + case START_OBJECT: + return parseJsonObject(ctx); + case START_ARRAY: + return parseToList(ctx); + case VALUE_STRING: + case VALUE_TRUE: + case VALUE_FALSE: + case VALUE_NUMBER_FLOAT: + case VALUE_NUMBER_INT: + return parseToPrimitive(ctx); + case VALUE_NULL: + return parseToEmptyPrimitive(); + default: + throw new SchemaException("Unexpected current token: " + ctx.parser.currentToken()); + } + } + + /** + * Normally returns a MapXNode. However, JSON primitives can be simulated by two-member object (@type + @value); in these cases we return PrimitiveXNode. + */ + @NotNull + private XNode parseJsonObject(JsonParsingContext ctx) throws SchemaException, IOException { + Validate.notNull(ctx.parser.currentToken()); + + QName typeName = null; + + Object tid = ctx.parser.getTypeId(); + if (tid != null) { + typeName = tagToTypeName(tid, ctx); + } + + final MapXNode map = new MapXNode(); + PrimitiveXNode primitiveValue = null; + boolean defaultNamespaceDefined = false; + QNameUtil.QNameInfo currentFieldNameInfo = null; + for (;;) { + JsonToken token = ctx.parser.nextToken(); + if (token == null) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Unexpected end of data while parsing a map structure at " + getPositionSuffix(ctx)); + break; + } else if (token == JsonToken.END_OBJECT) { + break; + } else if (token == JsonToken.FIELD_NAME) { + String newFieldName = ctx.parser.getCurrentName(); + if (currentFieldNameInfo != null) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Two field names in succession: " + currentFieldNameInfo + " and " + newFieldName); + } + currentFieldNameInfo = QNameUtil.uriToQNameInfo(newFieldName, true); + } else { + XNode valueXNode = parseValue(ctx); + if (isSpecial(currentFieldNameInfo.name)) { + String stringValue; + if (!(valueXNode instanceof PrimitiveXNode)) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Value of '" + currentFieldNameInfo + "' attribute must be a primitive one. It is " + valueXNode + " instead. At " + getPositionSuffix(ctx)); + stringValue = ""; + } else { + stringValue = ((PrimitiveXNode) valueXNode).getStringValue(); + } + + if (isNamespaceDeclaration(currentFieldNameInfo.name)) { + if (defaultNamespaceDefined) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Default namespace defined more than once at " + getPositionSuffix(ctx)); + } + ctx.defaultNamespaces.put(map, stringValue); + defaultNamespaceDefined = true; + } else if (isTypeDeclaration(currentFieldNameInfo.name)) { + if (typeName != null) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Value type defined more than once at " + getPositionSuffix(ctx)); + } + typeName = QNameUtil.uriToQName(stringValue, true); + } else if (isValue(currentFieldNameInfo.name)) { + if (primitiveValue != null) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Primitive value ('" + PROP_VALUE + "') defined more than once at " + getPositionSuffix(ctx)); + } + if (valueXNode instanceof PrimitiveXNode) { + primitiveValue = (PrimitiveXNode) valueXNode; + } + } + } else { + Map.Entry entry = map.putReturningEntry(currentFieldNameInfo.name, valueXNode); + if (currentFieldNameInfo.explicitEmptyNamespace) { + ctx.noNamespaceEntries.put(entry, null); + } + } + currentFieldNameInfo = null; + } + } + // Return either map or primitive value (in case of @type/@value) + XNode rv; + if (primitiveValue != null) { + if (!map.isEmpty()) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Both '" + PROP_VALUE + "' and regular content present at " + getPositionSuffix(ctx)); + rv = map; + } else { + rv = primitiveValue; + } + } else { + rv = map; + } + if (typeName != null) { + rv.setTypeQName(typeName); + rv.setExplicitTypeDeclaration(true); + } + return rv; + } + + private boolean isSpecial(QName fieldName) { + return isTypeDeclaration(fieldName) || isNamespaceDeclaration(fieldName) || isValue(fieldName); + } + + private boolean isTypeDeclaration(QName fieldName) { + return new QName(PROP_TYPE).equals(fieldName); + } + + private boolean isNamespaceDeclaration(QName fieldName) { + return new QName(PROP_NAMESPACE).equals(fieldName); + } + + private boolean isValue(QName fieldName) { + return new QName(PROP_VALUE).equals(fieldName); + } + + private String getPositionSuffix(JsonParsingContext ctx) { + return String.valueOf(ctx.parser.getCurrentLocation()); + } + + private ListXNode parseToList(JsonParsingContext ctx) throws SchemaException, IOException { + Validate.notNull(ctx.parser.currentToken()); + + ListXNode list = new ListXNode(); + for (;;) { + JsonToken token = ctx.parser.nextToken(); + if (token == null) { + ctx.prismParsingContext.warnOrThrow(LOGGER, "Unexpected end of data while parsing a list structure at " + getPositionSuffix(ctx)); + return list; + } else if (token == JsonToken.END_ARRAY) { + return list; + } else { + list.add(parseValue(ctx)); + } + } + } + + private PrimitiveXNode parseToPrimitive(JsonParsingContext ctx) throws IOException, SchemaException { + PrimitiveXNode primitive = new PrimitiveXNode(); + + Object tid = ctx.parser.getTypeId(); + if (tid != null) { + QName typeName = tagToTypeName(tid, ctx); + primitive.setTypeQName(typeName); + primitive.setExplicitTypeDeclaration(true); + } else { + // We don't try to determine XNode type from the implicit JSON/YAML type (integer, number, ...), + // because XNode type prescribes interpretation in midPoint. E.g. YAML string type would be interpreted + // as xsd:string, even if the schema would expect e.g. timestamp. + } + + JsonNode jn = ctx.parser.readValueAs(JsonNode.class); + ValueParser vp = new JsonValueParser(ctx.parser, jn); + primitive.setValueParser(vp); + + return primitive; + } + + private PrimitiveXNode parseToEmptyPrimitive() throws IOException, SchemaException { + PrimitiveXNode primitive = new PrimitiveXNode(); + primitive.setValueParser(new JsonNullValueParser()); + return primitive; + } + + // TODO remove if not needed + private QName getCurrentTypeName(JsonParsingContext ctx) throws IOException, SchemaException { + switch (ctx.parser.currentToken()) { + case VALUE_NUMBER_INT: + case VALUE_NUMBER_FLOAT: + return determineNumberType(ctx.parser.getNumberType()); + case VALUE_FALSE: + case VALUE_TRUE: + return DOMUtil.XSD_BOOLEAN; + case VALUE_STRING: + return DOMUtil.XSD_STRING; + case VALUE_NULL: + return null; // TODO? + default: + throw new SchemaException("Unexpected current token type: " + ctx.parser.currentToken() + "/" + ctx.parser.getText() + " at " + getPositionSuffix(ctx)); + } + } + + QName determineNumberType(JsonParser.NumberType numberType) throws SchemaException { + switch (numberType) { + case BIG_DECIMAL: + return DOMUtil.XSD_DECIMAL; + case BIG_INTEGER: + return DOMUtil.XSD_INTEGER; + case LONG: + return DOMUtil.XSD_LONG; + case INT: + return DOMUtil.XSD_INT; + case FLOAT: + return DOMUtil.XSD_FLOAT; + case DOUBLE: + return DOMUtil.XSD_DOUBLE; + default: + throw new SchemaException("Unsupported number type: " + numberType); + } + } + + protected abstract QName tagToTypeName(Object tid, JsonParsingContext ctx) throws IOException, SchemaException; + + private JsonParser configureParser(JsonParser parser) { + ObjectMapper mapper = new ObjectMapper(); + SimpleModule sm = new SimpleModule(); + sm.addDeserializer(QName.class, new QNameDeserializer()); + sm.addDeserializer(ItemPath.class, new ItemPathDeserializer()); + sm.addDeserializer(PolyString.class, new PolyStringDeserializer()); + sm.addDeserializer(ItemPathType.class, new ItemPathTypeDeserializer()); + + mapper.registerModule(sm); + parser.setCodec(mapper); + return parser; + } + + //endregion + + //region Serialization implementation + + class JsonSerializationContext { + @NotNull final JsonGenerator generator; + @NotNull private final SerializationContext prismSerializationContext; + private String currentNamespace; + + private JsonSerializationContext(@NotNull JsonGenerator generator, @Nullable SerializationContext prismSerializationContext) { + this.generator = generator; + this.prismSerializationContext = prismSerializationContext != null ? + prismSerializationContext : + new SerializationContext(null); + } + } + @NotNull + @Override + public String write(@NotNull XNode xnode, @NotNull QName rootElementName, SerializationContext serializationContext) throws SchemaException { + return write(LexicalUtils.createRootXNode(xnode, rootElementName), serializationContext); + } + + protected abstract JsonGenerator createJacksonGenerator(StringWriter out) throws SchemaException; + + protected abstract void writeExplicitType(QName explicitType, JsonGenerator generator) throws IOException; + + @NotNull + @Override + public String write(@NotNull RootXNode root, SerializationContext prismSerializationContext) throws SchemaException { + StringWriter out = new StringWriter(); + try ( JsonGenerator generator = createJacksonGenerator(out) ) { + JsonSerializationContext ctx = new JsonSerializationContext(generator, prismSerializationContext); + serialize(root.toMapXNode(), ctx); // TODO default namespace + } catch (IOException ex) { + throw new SchemaException("Error during serializing to JSON/YAML: " + ex.getMessage(), ex); + } + return out.toString(); + } + + private void serialize(XNode xnode, JsonSerializationContext ctx) throws IOException { + if (xnode instanceof MapXNode) { + serializeFromMap((MapXNode) xnode, ctx); + } else if (xnode instanceof ListXNode) { + serializeFromList((ListXNode) xnode, ctx); + } else if (xnode instanceof PrimitiveXNode) { + serializeFromPrimitive((PrimitiveXNode) xnode, ctx); + } else if (xnode instanceof SchemaXNode) { + serializeFromSchema((SchemaXNode) xnode, ctx); + } else if (xnode == null) { + serializeFromNull(ctx); + } else { + throw new UnsupportedOperationException("Cannot serialize from " + xnode); + } + } + + private void serializeFromNull(JsonSerializationContext ctx) throws IOException { + ctx.generator.writeNull(); + } + + private void serializeFromMap(MapXNode map, JsonSerializationContext ctx) throws IOException { + ctx.generator.writeStartObject(); + QName explicitType = getExplicitType(map); + if (explicitType != null) { + writeExplicitType(explicitType, ctx.generator); + } + String oldDefaultNamespace = ctx.currentNamespace; + generateNsDeclarationIfNeeded(map, ctx); + for (Entry entry : map.entrySet()) { + if (entry.getValue() == null) { + continue; + } + ctx.generator.writeFieldName(createKeyUri(entry, ctx)); + serialize(entry.getValue(), ctx); + } + ctx.generator.writeEndObject(); + ctx.currentNamespace = oldDefaultNamespace; + } + + private void generateNsDeclarationIfNeeded(MapXNode map, JsonSerializationContext ctx) throws IOException { + SerializationOptions opts = ctx.prismSerializationContext.getOptions(); + if (!SerializationOptions.isUseNsProperty(opts) || map.isEmpty()) { + return; + } + String namespace = determineNewCurrentNamespace(map, ctx); + if (namespace != null && !StringUtils.equals(namespace, ctx.currentNamespace)) { + ctx.currentNamespace = namespace; + ctx.generator.writeFieldName(PROP_NAMESPACE); + ctx.generator.writeString(namespace); + } + } + + private String determineNewCurrentNamespace(MapXNode map, JsonSerializationContext ctx) { + Map counts = new HashMap<>(); + for (QName childName : map.keySet()) { + String childNs = childName.getNamespaceURI(); + if (StringUtils.isEmpty(childNs)) { + continue; + } + if (childNs.equals(ctx.currentNamespace)) { + return ctx.currentNamespace; // found existing => continue with it + } + Integer c = counts.get(childNs); + counts.put(childNs, c != null ? c+1 : 1); + } + // otherwise, take the URI that occurs the most in the map + Entry max = null; + for (Entry count : counts.entrySet()) { + if (max == null || count.getValue() > max.getValue()) { + max = count; + } + } + return max != null ? max.getKey() : null; + } + + private String createKeyUri(Entry entry, JsonSerializationContext ctx) { + QName key = entry.getKey(); + if (namespaceMatch(ctx.currentNamespace, key.getNamespaceURI())) { + return key.getLocalPart(); + } else if (StringUtils.isNotEmpty(ctx.currentNamespace) && !isAttribute(entry.getValue())) { + return QNameUtil.qNameToUri(key, true); // items with no namespace should be written as such (starting with '#') + } else { + return QNameUtil.qNameToUri(key, false); // items with no namespace can be written in plain + } + } + + private boolean isAttribute(XNode node) { + return node instanceof PrimitiveXNode && ((PrimitiveXNode) node).isAttribute(); + } + + private boolean namespaceMatch(String currentNamespace, String itemNamespace) { + if (StringUtils.isEmpty(currentNamespace)) { + return StringUtils.isEmpty(itemNamespace); + } else { + return currentNamespace.equals(itemNamespace); + } + } + + private void serializeFromList(ListXNode list, JsonSerializationContext ctx) throws IOException { + ctx.generator.writeStartArray(); + for (XNode item : list) { + serialize(item, ctx); + } + ctx.generator.writeEndArray(); + } + + protected abstract void serializeFromPrimitive(PrimitiveXNode primitive, JsonSerializationContext ctx) throws IOException; + + private void serializeFromSchema(SchemaXNode node, JsonSerializationContext ctx) throws IOException { + ctx.generator.writeObject(node.getSchemaElement()); + } + + + void serializePrimitiveTypeLessValue(PrimitiveXNode primitive, JsonSerializationContext ctx) throws IOException { + if (primitive.isParsed()) { + ctx.generator.writeObject(primitive.getValue()); + } else { + ctx.generator.writeObject(primitive.getStringValue()); + } + } + + protected QName getExplicitType(XNode xnode) { + return xnode.isExplicitTypeDeclaration() ? xnode.getTypeQName() : null; + } + + private String serializeNsIfNeeded(QName subNodeName, String globalNamespace, JsonGenerator generator) throws JsonGenerationException, IOException{ + if (subNodeName == null){ + return globalNamespace; + } + String subNodeNs = subNodeName.getNamespaceURI(); + if (StringUtils.isNotBlank(subNodeNs)){ + if (!subNodeNs.equals(globalNamespace)){ + globalNamespace = subNodeNs; + generator.writeStringField(PROP_NAMESPACE, globalNamespace); + + } + } + return globalNamespace; + } + //endregion + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/DomElementSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/DomElementSerializer.java similarity index 84% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/DomElementSerializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/DomElementSerializer.java index e03f32ede41..b1ca413826b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/DomElementSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/DomElementSerializer.java @@ -1,4 +1,4 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; @@ -10,7 +10,7 @@ import com.fasterxml.jackson.databind.ext.DOMSerializer; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -public class DomElementSerializer extends DOMSerializer{ +public class DomElementSerializer extends DOMSerializer { @Override public void serializeWithType(Node value, JsonGenerator jgen, SerializerProvider provider, diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathDeserializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathDeserializer.java similarity index 90% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathDeserializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathDeserializer.java index 9fdb98508cf..cdd0bab3fee 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathDeserializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathDeserializer.java @@ -1,11 +1,14 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; +import javax.xml.namespace.QName; + import org.apache.commons.lang.StringUtils; -import com.evolveum.midpoint.prism.parser.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.util.QNameUtil; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathSerializer.java similarity index 85% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathSerializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathSerializer.java index 2500f3851db..26321287420 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathSerializer.java @@ -1,8 +1,8 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; -import com.evolveum.midpoint.prism.parser.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; @@ -10,14 +10,13 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -public class ItemPathSerializer extends JsonSerializer{ +public class ItemPathSerializer extends JsonSerializer { @Override public void serialize(ItemPath value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { XPathHolder xpath = new XPathHolder(value); String path = xpath.getXPathWithDeclarations(true); -// value. jgen.writeObject(path); } @@ -25,7 +24,6 @@ public void serialize(ItemPath value, JsonGenerator jgen, SerializerProvider pro @Override public void serializeWithType(ItemPath value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException { - // TODO Auto-generated method stub serialize(value, jgen, provider); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathTypeDeserializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathTypeDeserializer.java similarity index 94% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathTypeDeserializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathTypeDeserializer.java index 7cb49c211b0..f8b65f51dc0 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/ItemPathTypeDeserializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathTypeDeserializer.java @@ -1,10 +1,10 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; import org.apache.commons.lang.StringUtils; -import com.evolveum.midpoint.prism.parser.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import com.fasterxml.jackson.core.JsonParseException; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathTypeSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathTypeSerializer.java new file mode 100644 index 00000000000..9c2f190f141 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/ItemPathTypeSerializer.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex.json; + +import com.evolveum.midpoint.prism.marshaller.XPathHolder; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class ItemPathTypeSerializer extends JsonSerializer { + + @Override + public void serialize(@NotNull ItemPathType value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + XPathHolder xpath = new XPathHolder(value.getItemPath()); + String path = xpath.getXPathWithDeclarations(true); + jgen.writeObject(path); + + } + + @Override + public void serializeWithType(@NotNull ItemPathType value, JsonGenerator jgen, SerializerProvider provider, + TypeSerializer typeSer) throws IOException { + serialize(value, jgen, provider); + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/JsonParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonLexicalProcessor.java similarity index 61% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/JsonParser.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonLexicalProcessor.java index 0676a418c1d..30dcecdaa61 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/JsonParser.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonLexicalProcessor.java @@ -1,24 +1,29 @@ -package com.evolveum.midpoint.prism.parser; +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; - -import javax.xml.namespace.QName; +package com.evolveum.midpoint.prism.lex.json; -import com.evolveum.midpoint.prism.parser.json.ItemPathSerializer; -import com.evolveum.midpoint.prism.parser.json.PolyStringSerializer; -import com.evolveum.midpoint.prism.parser.json.QNameSerializer; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.Version; @@ -28,38 +33,28 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; +import org.jetbrains.annotations.NotNull; -public class JsonParser extends AbstractParser{ - -// private static final String PROP_NAMESPACE = "@ns"; -// private static final String TYPE_DEFINITION = "@typeDef"; -// private static final String VALUE_FIELD = "@value"; -// -// +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +public class JsonLexicalProcessor extends AbstractJsonLexicalProcessor { @Override - public boolean canParse(File file) throws IOException { - if (file == null) { - return false; - } + public boolean canRead(@NotNull File file) throws IOException { return file.getName().endsWith(".json"); } @Override - public boolean canParse(String dataString) { - if (dataString == null) { - return false; - } + public boolean canRead(@NotNull String dataString) { return dataString.startsWith("{"); } - @Override - protected com.fasterxml.jackson.core.JsonParser createParser(File file) throws SchemaException, IOException { - return createParser(new FileInputStream(file)); - } - @Override - protected com.fasterxml.jackson.core.JsonParser createParser(InputStream stream) throws SchemaException, IOException { + protected com.fasterxml.jackson.core.JsonParser createJacksonParser(InputStream stream) throws SchemaException, IOException { JsonFactory factory = new JsonFactory(); try { return factory.createParser(stream); @@ -69,7 +64,7 @@ protected com.fasterxml.jackson.core.JsonParser createParser(InputStream stream) } @Override - protected com.fasterxml.jackson.core.JsonParser createParser(String dataString) throws SchemaException { + protected com.fasterxml.jackson.core.JsonParser createJacksonParser(String dataString) throws SchemaException { JsonFactory factory = new JsonFactory(); try { return factory.createParser(dataString); @@ -78,7 +73,7 @@ protected com.fasterxml.jackson.core.JsonParser createParser(String dataString) } } - public JsonGenerator createGenerator(StringWriter out) throws SchemaException{ + public JsonGenerator createJacksonGenerator(StringWriter out) throws SchemaException{ return createJsonGenerator(out); } private JsonGenerator createJsonGenerator(StringWriter out) throws SchemaException{ @@ -109,21 +104,23 @@ private Module createSerializerModule(){ module.addSerializer(QName.class, new QNameSerializer()); module.addSerializer(PolyString.class, new PolyStringSerializer()); module.addSerializer(ItemPath.class, new ItemPathSerializer()); + module.addSerializer(ItemPathType.class, new ItemPathTypeSerializer()); // module.addSerializer(Element.class, new DomElementJsonSerializer()); // module.addSerializer(JAXBElement.class, new JaxbElementSerializer()); return module; } @Override - protected boolean serializeExplicitType(PrimitiveXNode primitive, QName explicitType, JsonGenerator generator) throws JsonGenerationException, IOException { + protected void serializeFromPrimitive(PrimitiveXNode primitive, AbstractJsonLexicalProcessor.JsonSerializationContext ctx) throws IOException { + QName explicitType = getExplicitType(primitive); if (explicitType != null) { - generator.writeStartObject(); - generator.writeStringField(TYPE_DEFINITION, QNameUtil.qNameToUri(primitive.getTypeQName())); - generator.writeObjectField(VALUE_FIELD, primitive.getValue()); - generator.writeEndObject(); - return true; - } - return false; + ctx.generator.writeStartObject(); + ctx.generator.writeStringField(PROP_TYPE, QNameUtil.qNameToUri(primitive.getTypeQName())); + ctx.generator.writeObjectField(PROP_VALUE, primitive.getStringValue()); + ctx.generator.writeEndObject(); + } else { + serializePrimitiveTypeLessValue(primitive, ctx); + } } @Override @@ -131,7 +128,8 @@ protected void writeExplicitType(QName explicitType, JsonGenerator generator) th generator.writeObjectField("@type", explicitType); } - - - + @Override + protected QName tagToTypeName(Object tid, AbstractJsonLexicalProcessor.JsonParsingContext ctx) { + return null; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonNullValueParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonNullValueParser.java new file mode 100644 index 00000000000..c4035917325 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonNullValueParser.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex.json; + +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.util.JavaTypeConverter; +import com.evolveum.midpoint.prism.xml.XsdTypeMapper; +import com.evolveum.midpoint.prism.xnode.ValueParser; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.w3c.dom.Element; + +import javax.xml.namespace.QName; +import java.io.IOException; +import java.util.Map; + +public class JsonNullValueParser implements ValueParser { + + public JsonNullValueParser() { + } + + @Override + public T parse(QName typeName, XNodeProcessorEvaluationMode mode) throws SchemaException { + Class clazz = XsdTypeMapper.toJavaType(typeName); + if (clazz == null) { + throw new SchemaException("Unsupported type " + typeName); + } + return (T) JavaTypeConverter.convert(clazz, ""); + } + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public String getStringValue() { + return ""; + } + + @Override + public String toString() { + return "JsonNullValueParser"; + } + + @Override + public Map getPotentiallyRelevantNamespaces() { + return null; // TODO implement + } + + Element asDomElement() throws IOException { + return null; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/JsonValueParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonValueParser.java similarity index 65% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/JsonValueParser.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonValueParser.java index 1f565f8ee7c..2edf199a42e 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/JsonValueParser.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/JsonValueParser.java @@ -1,11 +1,11 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; import java.util.Map; import javax.xml.namespace.QName; -import com.evolveum.midpoint.prism.parser.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.prism.xnode.ValueParser; import com.evolveum.midpoint.util.exception.SchemaException; @@ -14,54 +14,47 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Document; +import org.w3c.dom.Element; public class JsonValueParser implements ValueParser { - private final JsonParser parser; + @NotNull private final JsonParser parser; private JsonNode node; - public JsonValueParser(JsonParser parser, JsonNode node) { + public JsonValueParser(@NotNull JsonParser parser, JsonNode node) { this.parser = parser; this.node = node; } - public JsonValueParser(final JsonParser parser) { - this.parser = parser; - } - + @NotNull public JsonParser getParser() { return parser; } + @Override public T parse(QName typeName, XNodeProcessorEvaluationMode mode) throws SchemaException { ObjectMapper mapper = (ObjectMapper) parser.getCodec(); Class clazz = XsdTypeMapper.toJavaType(typeName); - - ObjectReader r = mapper.reader(clazz); + + ObjectReader r = mapper.readerFor(clazz); try { -// if (parser.getCurrentToken() == null){ -// JsonToken t = parser.nextToken(); -// if (t == null){ -// t = parser.nextToken(); -// } -// } return r.readValue(node); // TODO implement COMPAT mode } catch (IOException e) { - // TODO Auto-generated catch block throw new SchemaException("Cannot parse value: " + e.getMessage(), e); } } @Override public boolean isEmpty() { - return node == null || parser == null || - StringUtils.isBlank(node.asText()); // to be consistent with PrimitiveXNode.isEmpty for parsed values + return node == null || StringUtils.isBlank(node.asText()); // to be consistent with PrimitiveXNode.isEmpty for parsed values } @Override public String getStringValue() { - if (node == null){ + if (node == null) { return null; } return node.asText(); @@ -76,4 +69,10 @@ public String toString() { public Map getPotentiallyRelevantNamespaces() { return null; // TODO implement } + + Element asDomElement() throws IOException { + ObjectMapper mapper = (ObjectMapper) parser.getCodec(); + ObjectReader r = mapper.readerFor(Document.class); + return ((Document) r.readValue(node)).getDocumentElement(); + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/NullLexicalProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/NullLexicalProcessor.java new file mode 100644 index 00000000000..0903145e68f --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/NullLexicalProcessor.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex.json; + +import com.evolveum.midpoint.prism.ParserSource; +import com.evolveum.midpoint.prism.ParserXNodeSource; +import com.evolveum.midpoint.prism.ParsingContext; +import com.evolveum.midpoint.prism.SerializationContext; +import com.evolveum.midpoint.prism.lex.LexicalProcessor; +import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.util.exception.SchemaException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * @author mederly + */ +public class NullLexicalProcessor implements LexicalProcessor { + + @NotNull + @Override + public RootXNode read(@NotNull ParserSource source, @NotNull ParsingContext parsingContext) throws SchemaException, IOException { + if (!(source instanceof ParserXNodeSource)) { + throw new IllegalStateException("Unsupported parser source: " + source.getClass().getName()); + } + return ((ParserXNodeSource) source).getXNode(); + } + + @NotNull + @Override + public List readObjects(ParserSource source, ParsingContext parsingContext) throws SchemaException, IOException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean canRead(@NotNull File file) throws IOException { + return false; + } + + @Override + public boolean canRead(@NotNull String dataString) { + return false; + } + + @NotNull + @Override + public XNode write(@NotNull RootXNode xnode, @Nullable SerializationContext serializationContext) throws SchemaException { + return xnode; + } + + @NotNull + @Override + public XNode write(@NotNull XNode xnode, @NotNull QName rootElementName, @Nullable SerializationContext serializationContext) + throws SchemaException { + return xnode; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/PolyStringDeserializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/PolyStringDeserializer.java similarity index 94% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/PolyStringDeserializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/PolyStringDeserializer.java index 246c982f8a5..4efa0da13d8 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/PolyStringDeserializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/PolyStringDeserializer.java @@ -1,4 +1,4 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/PolyStringSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/PolyStringSerializer.java similarity index 96% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/PolyStringSerializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/PolyStringSerializer.java index 0aec12dd31c..f58fa60d494 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/PolyStringSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/PolyStringSerializer.java @@ -1,4 +1,4 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/QNameDeserializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/QNameDeserializer.java similarity index 95% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/QNameDeserializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/QNameDeserializer.java index c8fd4fc5012..53f516486d9 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/QNameDeserializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/QNameDeserializer.java @@ -1,4 +1,4 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; @@ -63,7 +63,7 @@ private QName deserializeFromObject(JsonNode node){ private QName deserializeFromString(JsonNode node){ String qnameUri = node.asText(); - return QNameUtil.uriToQName(qnameUri); + return QNameUtil.uriToQName(qnameUri, true); // return new QName(node.asText()); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/QNameSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/QNameSerializer.java new file mode 100644 index 00000000000..381426c3365 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/QNameSerializer.java @@ -0,0 +1,26 @@ +package com.evolveum.midpoint.prism.lex.json; + +import java.io.IOException; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.util.QNameUtil; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; + +public class QNameSerializer extends JsonSerializer { + + @Override + public void serialize(QName value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + jgen.writeString(QNameUtil.qNameToUri(value, false)); + } + + @Override + public void serializeWithType(QName value, JsonGenerator jgen, SerializerProvider provider, + TypeSerializer typeSer) throws IOException { + serialize(value, jgen, provider); + } + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/XmlGregorialCalendarSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/XmlGregorianCalendarSerializer.java similarity index 85% rename from infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/XmlGregorialCalendarSerializer.java rename to infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/XmlGregorianCalendarSerializer.java index 0dd356443e6..da16f1fdbfe 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/json/XmlGregorialCalendarSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/XmlGregorianCalendarSerializer.java @@ -1,4 +1,4 @@ -package com.evolveum.midpoint.prism.parser.json; +package com.evolveum.midpoint.prism.lex.json; import java.io.IOException; @@ -10,7 +10,7 @@ import com.fasterxml.jackson.databind.ext.CoreXMLSerializers.XMLGregorianCalendarSerializer; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -public class XmlGregorialCalendarSerializer extends XMLGregorianCalendarSerializer{ +public class XmlGregorianCalendarSerializer extends XMLGregorianCalendarSerializer{ @Override public void serializeWithType(XMLGregorianCalendar value, JsonGenerator jgen, diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/YamlLexicalProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/YamlLexicalProcessor.java new file mode 100644 index 00000000000..4244184dee5 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/YamlLexicalProcessor.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.lex.json; + +import com.evolveum.midpoint.prism.lex.json.yaml.MidpointYAMLFactory; +import com.evolveum.midpoint.prism.lex.json.yaml.MidpointYAMLGenerator; +import com.evolveum.midpoint.prism.lex.json.yaml.MidpointYAMLParser; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +//import com.fasterxml.jackson.core.YAMLGenerator; + +public class YamlLexicalProcessor extends AbstractJsonLexicalProcessor { + + private static final String YAML = "tag:yaml.org,2002:"; + private static final String TAG_STRING = YAML + "str"; + private static final String TAG_INT = YAML + "int"; + private static final String TAG_BOOL = YAML + "bool"; + private static final String TAG_FLOAT = YAML + "float"; + private static final String TAG_NULL = YAML + "null"; + + //------------------------END OF METHODS FOR SERIALIZATION ------------------------------- + + @Override + public boolean canRead(@NotNull File file) throws IOException { + return file.getName().endsWith(".yaml"); + } + + @Override + public boolean canRead(@NotNull String dataString) { + return dataString.startsWith("---"); + } + + public YAMLGenerator createJacksonGenerator(StringWriter out) throws SchemaException{ + try { + MidpointYAMLFactory factory = new MidpointYAMLFactory(); + MidpointYAMLGenerator generator = (MidpointYAMLGenerator) factory.createGenerator(out); + generator.setPrettyPrinter(new DefaultPrettyPrinter()); + generator.setCodec(configureMapperForSerialization()); + return generator; + } catch (IOException ex){ + throw new SchemaException("Schema error during serializing to JSON.", ex); + } + + + } + + private ObjectMapper configureMapperForSerialization(){ + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); +// mapper.enableDefaultTyping(DefaultTyping.NON_CONCRETE_AND_ARRAYS, As.EXISTING_PROPERTY); +// mapper.configure(SerializationFeaCture.); +// mapper.setSerializationInclusion(Include.NON_NULL); + mapper.registerModule(createSerializerModule()); + + mapper.disableDefaultTyping(); + +// mapper.enableDefaultTyping(DefaultTyping.NON_CONCRETE_AND_ARRAYS); +// mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.EXISTING_PROPERTY); +// //mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.EXTERNAL_PROPERTY); +// mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY); + + return mapper; + } + + private Module createSerializerModule(){ + SimpleModule module = new SimpleModule("MidpointModule", new Version(0, 0, 0, "aa")); + module.addSerializer(QName.class, new QNameSerializer()); + module.addSerializer(PolyString.class, new PolyStringSerializer()); + module.addSerializer(ItemPath.class, new ItemPathSerializer()); + module.addSerializer(ItemPathType.class, new ItemPathTypeSerializer()); +// module.addSerializer(JAXBElement.class, new JaxbElementSerializer()); + module.addSerializer(XMLGregorianCalendar.class, new XmlGregorianCalendarSerializer()); + module.addSerializer(Element.class, new DomElementSerializer()); + return module; + } + + @Override + protected MidpointYAMLParser createJacksonParser(InputStream stream) throws SchemaException, IOException { + MidpointYAMLFactory factory = new MidpointYAMLFactory(); + try { + MidpointYAMLParser p = (MidpointYAMLParser) factory.createParser(stream); +// p.enable(Feature.BOGUS); +// String oid = p.getObjectId(); + return p; + } catch (IOException e) { + throw e; + } + } + + @Override + protected QName tagToTypeName(Object tag, AbstractJsonLexicalProcessor.JsonParsingContext ctx) throws IOException, SchemaException { + if (tag == null) { + return null; + } if (TAG_STRING.equals(tag)) { + return DOMUtil.XSD_STRING; + } else if (TAG_BOOL.equals(tag)) { + return DOMUtil.XSD_BOOLEAN; + } else if (TAG_NULL.equals(tag)) { + return null; // ??? + } else if (TAG_INT.equals(tag)) { + QName type = determineNumberType(ctx.parser.getNumberType()); + if (DOMUtil.XSD_INT.equals(type) || DOMUtil.XSD_INTEGER.equals(type)) { + return type; + } else { + return DOMUtil.XSD_INT; // suspicious + } + } else if (TAG_FLOAT.equals(tag)) { + QName type = determineNumberType(ctx.parser.getNumberType()); + if (DOMUtil.XSD_FLOAT.equals(type) || DOMUtil.XSD_DOUBLE.equals(type) || DOMUtil.XSD_DECIMAL.equals(type)) { + return type; + } else { + return DOMUtil.XSD_FLOAT; // suspicious + } + } else if (tag instanceof String) { + return QNameUtil.uriToQName((String) tag, true); + } else { + // TODO issue a warning? + return null; + } + } + + @Override + protected MidpointYAMLParser createJacksonParser(String dataString) throws SchemaException { + MidpointYAMLFactory factory = new MidpointYAMLFactory(); + try { + return (MidpointYAMLParser) factory.createParser(dataString); + } catch (IOException e) { + throw new SchemaException("Cannot create JSON parser: " + e.getMessage(), e); + } + + } + + @Override + protected void serializeFromPrimitive(PrimitiveXNode primitive, AbstractJsonLexicalProcessor.JsonSerializationContext ctx) throws IOException { + QName explicitType = getExplicitType(primitive); + if (explicitType != null) { + ctx.generator.writeTypeId(QNameUtil.qNameToUri(explicitType, false, '/')); + } + serializePrimitiveTypeLessValue(primitive, ctx); + } + + @Override + protected void writeExplicitType(QName explicitType, JsonGenerator generator) throws JsonGenerationException, IOException { + generator.writeObjectField("@type", explicitType); + // if (generator.canWriteTypeId()){ +// String type = QNameUtil.qNameToUri(explicitType); +// type = type.replace("#", "//"); +// generator.writeTypeId(type); +// } + } + +} + + diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLFactory.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLFactory.java new file mode 100644 index 00000000000..a92bda4208a --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLFactory.java @@ -0,0 +1,38 @@ +package com.evolveum.midpoint.prism.lex.json.yaml; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.Writer; + +import com.fasterxml.jackson.core.JsonParser; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.io.IOContext; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +public class MidpointYAMLFactory extends YAMLFactory { + + + + @Override + protected MidpointYAMLGenerator _createGenerator(Writer out, IOContext ctxt) throws IOException { + int feats = _yamlGeneratorFeatures; + MidpointYAMLGenerator gen = new MidpointYAMLGenerator(ctxt, _generatorFeatures, feats, _objectCodec, out, _version); + // any other initializations? No? + return gen; + } + + @SuppressWarnings("resource") + @Override + protected MidpointYAMLParser _createParser(InputStream in, IOContext ctxt) throws IOException, JsonParseException { + return _createParser(_createReader(in, null, ctxt), ctxt); + } + + @Override + protected MidpointYAMLParser _createParser(Reader r, IOContext ctxt) throws IOException, JsonParseException { + MidpointYAMLParser p = new MidpointYAMLParser(ctxt, _getBufferRecycler(), _parserFeatures, _yamlParserFeatures, _objectCodec, r); + p.enable(JsonParser.Feature.ALLOW_YAML_COMMENTS); + return p; + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLGenerator.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLGenerator.java new file mode 100644 index 00000000000..96e642a0b76 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLGenerator.java @@ -0,0 +1,41 @@ +package com.evolveum.midpoint.prism.lex.json.yaml; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.core.io.IOContext; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.events.ImplicitTuple; +import org.yaml.snakeyaml.events.ScalarEvent; + +import java.io.IOException; +import java.io.Writer; + +public class MidpointYAMLGenerator extends YAMLGenerator { + + public MidpointYAMLGenerator(IOContext ctxt, int jsonFeatures, int yamlFeatures, ObjectCodec codec, + Writer out, DumperOptions.Version version) throws IOException { + super(ctxt, jsonFeatures, yamlFeatures, codec, out, version); + } + + @Override + protected ScalarEvent _scalarEvent(String value, Character style) { + if (value.contains("\n")) { + style = Character.valueOf('|'); + } + + ImplicitTuple implicit; + String yamlTag = _typeId; + if (yamlTag != null) { + _typeId = null; + implicit = new ImplicitTuple(false, false); // we want to always preserve the tags (if they are present) + } else { + implicit = new ImplicitTuple(true, true); + } + String anchor = _objectId; + if (anchor != null) { + _objectId = null; + } + return new ScalarEvent(anchor, yamlTag, implicit, value, null, null, style); + } + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLParser.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLParser.java new file mode 100644 index 00000000000..c03e28502c9 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/lex/json/yaml/MidpointYAMLParser.java @@ -0,0 +1,45 @@ +package com.evolveum.midpoint.prism.lex.json.yaml; + +import java.io.Reader; + +//import org.yaml.snakeyaml.events.CollectionStartEvent; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.core.io.IOContext; +import com.fasterxml.jackson.core.util.BufferRecycler; +import com.fasterxml.jackson.dataformat.yaml.YAMLParser; + +public class MidpointYAMLParser extends YAMLParser { + + public MidpointYAMLParser(IOContext ctxt, BufferRecycler br, int parserFeatures, int csvFeatures, + ObjectCodec codec, Reader reader) { + super(ctxt, br, parserFeatures, csvFeatures, codec, reader); + // TODO Auto-generated constructor stub + } + +// @Override +// public String getTypeId() throws IOException, JsonGenerationException +// { +// String tag = null; +// if (_lastEvent instanceof CollectionStartEvent) { +// tag = ((CollectionStartEvent) _lastEvent).getTag(); +// } else if (_lastEvent instanceof ScalarEvent){ +// tag = ((ScalarEvent) _lastEvent).getTag(); +// } +// +// +// if (tag != null) { +// /* 04-Aug-2013, tatu: Looks like YAML parser's expose these in... +// * somewhat exotic ways sometimes. So let's prepare to peel off +// * some wrappings: +// */ +// while (tag.startsWith("!")) { +// tag = tag.substring(1); +// } +// return tag; +// } +// +// return null; +// } + +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/BeanMarshaller.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/BeanMarshaller.java new file mode 100644 index 00000000000..74f86a14406 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/BeanMarshaller.java @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.prism.marshaller; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.xml.XsdTypeMapper; +import com.evolveum.midpoint.prism.xnode.*; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.Handler; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.exception.TunnelException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; +import com.evolveum.prism.xml.ns._public.types_3.*; +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.namespace.QName; +import java.lang.reflect.*; +import java.util.*; + +public class BeanMarshaller { + + private static final Trace LOGGER = TraceManager.getTrace(BeanMarshaller.class); + + public static final String DEFAULT_PLACEHOLDER = "##default"; + + @NotNull private final PrismBeanInspector inspector; + @NotNull private final PrismContext prismContext; + @NotNull private final Map specialMarshallers = new HashMap<>(); + + @FunctionalInterface + private interface Marshaller { + XNode marshal(Object bean, SerializationContext sc) throws SchemaException; + } + + private void createSpecialMarshallerMap() { + specialMarshallers.put(XmlAsStringType.class, this::marshalXmlAsStringType); + specialMarshallers.put(SchemaDefinitionType.class, this::marshalSchemaDefinition); + specialMarshallers.put(ProtectedByteArrayType.class, this::marshalProtectedDataType); + specialMarshallers.put(ProtectedStringType.class, this::marshalProtectedDataType); + specialMarshallers.put(ItemPathType.class, this::marshalItemPathType); + specialMarshallers.put(RawType.class, this::marshalRawType); +// add(PolyString.class, this::unmarshalPolyStringFromPrimitive, this::unmarshalPolyStringFromMap); +// add(PolyStringType.class, this::unmarshalPolyStringFromPrimitive, this::unmarshalPolyStringFromMap); + } + + public BeanMarshaller(@NotNull PrismContext prismContext, @NotNull PrismBeanInspector inspector) { + this.prismContext = prismContext; + this.inspector = inspector; + createSpecialMarshallerMap(); + } + + @Nullable + public XNode marshall(@Nullable T bean) throws SchemaException { + return marshall(bean, null); + } + + @Nullable + public XNode marshall(@Nullable T bean, @Nullable SerializationContext ctx) throws SchemaException { + if (bean == null) { + return null; + } + Marshaller marshaller = specialMarshallers.get(bean.getClass()); + if (marshaller != null) { + return marshaller.marshal(bean, ctx); + } else if (bean instanceof Containerable) { + return prismContext.xnodeSerializer().serializeRealValue(bean, new QName("dummy")).getSubnode(); + } else if (bean instanceof Enum) { + return marshalEnum((Enum) bean, ctx); + } else if (bean.getClass().getAnnotation(XmlType.class) != null) { + return marshalXmlType(bean, ctx); + } else { + return marshalToPrimitive(bean, ctx); + } + } + + private XNode marshalToPrimitive(Object bean, SerializationContext ctx) { + return createPrimitiveXNode(bean, null, false); + } + + private XNode marshalXmlType(Object bean, SerializationContext ctx) throws SchemaException { + + Class beanClass = bean.getClass(); + + MapXNode xmap; + if (bean instanceof SearchFilterType) { + // this hack is here because of c:ConditionalSearchFilterType - it is analogous to situation when unmarshalling this type (TODO: rework this in a nicer way) + xmap = marshalSearchFilterType((SearchFilterType) bean); + if (SearchFilterType.class.equals(bean.getClass())) { + return xmap; // nothing more to serialize; otherwise we continue, because in that case we deal with a subclass of SearchFilterType + } + } else { + xmap = new MapXNode(); + } + + String namespace = inspector.determineNamespace(beanClass); + if (namespace == null) { + throw new IllegalArgumentException("Cannot determine namespace of "+beanClass); + } + + List propOrder = inspector.getPropOrder(beanClass); + for (String fieldName: propOrder) { + QName elementName = inspector.findFieldElementQName(fieldName, beanClass, namespace); + Method getter = inspector.findPropertyGetter(beanClass, fieldName); + if (getter == null) { + throw new IllegalStateException("No getter for field "+fieldName+" in "+beanClass); + } + Object getterResult; + try { + getterResult = getter.invoke(bean); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new SystemException("Cannot invoke method for field "+fieldName+" in "+beanClass+": "+e.getMessage(), e); + } + + if (getterResult == null) { + continue; + } + + Field field = inspector.findPropertyField(beanClass, fieldName); + boolean isAttribute = inspector.isAttribute(field, getter); + + if (getterResult instanceof Collection) { + Collection col = (Collection) getterResult; + if (col.isEmpty()) { + continue; + } + Iterator i = col.iterator(); +// if (i == null) { +// // huh?!? .. but it really happens +// throw new IllegalArgumentException("Iterator of collection returned from "+getter+" is null"); +// } + Object getterResultValue = i.next(); + if (getterResultValue == null) { + continue; + } + + ListXNode xlist = new ListXNode(); + + // elementName will be determined from the first item on the list + // TODO make sure it will be correct with respect to other items as well! + if (getterResultValue instanceof JAXBElement && ((JAXBElement) getterResultValue).getName() != null) { + elementName = ((JAXBElement) getterResultValue).getName(); + } + + for (Object element: col) { + if (element == null){ + continue; + } + QName fieldTypeName = inspector.findFieldTypeName(field, element.getClass(), namespace); + Object elementToMarshall = element; + if (element instanceof JAXBElement){ + elementToMarshall = ((JAXBElement) element).getValue(); + } + XNode marshalled = marshallValue(elementToMarshall, fieldTypeName, isAttribute, ctx); + + // Brutal hack - made here just to make scripts (bulk actions) functional while not breaking anything else + // Fix it in 3.1. [med] + if (fieldTypeName == null && element instanceof JAXBElement && marshalled != null) { + QName typeName = inspector.determineTypeForClass(elementToMarshall.getClass()); + if (typeName != null && !getSchemaRegistry().hasImplicitTypeDefinition(elementName, typeName) + && getSchemaRegistry().findTypeDefinitionByType(typeName, TypeDefinition.class) != null) { + marshalled.setExplicitTypeDeclaration(true); + marshalled.setTypeQName(typeName); + } + } + else { + // end of hack + + setExplicitTypeDeclarationIfNeeded(getter, getterResultValue, marshalled, fieldTypeName); + } + xlist.add(marshalled); + } + xmap.put(elementName, xlist); + } else { + QName fieldTypeName = inspector.findFieldTypeName(field, getterResult.getClass(), namespace); + Object valueToMarshall = null; + if (getterResult instanceof JAXBElement){ + valueToMarshall = ((JAXBElement) getterResult).getValue(); + elementName = ((JAXBElement) getterResult).getName(); + } else{ + valueToMarshall = getterResult; + } + XNode marshelled = marshallValue(valueToMarshall, fieldTypeName, isAttribute, ctx); + if (!getter.getReturnType().equals(valueToMarshall.getClass()) && getter.getReturnType().isAssignableFrom(valueToMarshall.getClass()) && !(valueToMarshall instanceof Enum)) { + PrismObjectDefinition def = prismContext.getSchemaRegistry().determineDefinitionFromClass(valueToMarshall.getClass()); + if (def != null){ + QName type = def.getTypeName(); + marshelled.setTypeQName(type); + marshelled.setExplicitTypeDeclaration(true); + } + } + xmap.put(elementName, marshelled); + +// setExplicitTypeDeclarationIfNeeded(getter, valueToMarshall, xmap, fieldTypeName); + } + } + + return xmap; + } + + private XNode marshalEnum(Enum bean, SerializationContext ctx) { + Class beanClass = bean.getClass(); + String enumValue = inspector.findEnumFieldValue(beanClass, bean.toString()); + if (StringUtils.isEmpty(enumValue)){ + enumValue = bean.toString(); + } + QName fieldTypeName = inspector.findFieldTypeName(null, beanClass, DEFAULT_PLACEHOLDER); + return createPrimitiveXNode(enumValue, fieldTypeName, false); + + } + + private XNode marshalXmlAsStringType(Object bean, SerializationContext sc) { + PrimitiveXNode xprim = new PrimitiveXNode<>(); + xprim.setValue(((XmlAsStringType) bean).getContentAsString(), DOMUtil.XSD_STRING); + return xprim; + } + + public void revive(Object bean, final PrismContext prismContext) throws SchemaException { + Handler visitor = o -> { + if (o instanceof Revivable) { + try { + ((Revivable)o).revive(prismContext); + } catch (SchemaException e) { + throw new TunnelException(e); + } + } + return true; + }; + try { + visit(bean,visitor); + } catch (TunnelException te) { + SchemaException e = (SchemaException) te.getCause(); + throw e; + } + } + + public void visit(Object bean, Handler handler) { + if (bean == null) { + return; + } + + Class beanClass = bean.getClass(); + + handler.handle(bean); + + if (beanClass.isEnum() || beanClass.isPrimitive()){ + //nothing more to do + return; + } + + // TODO: implement special handling for RawType, if necessary (it has no XmlType annotation any more) + + XmlType xmlType = beanClass.getAnnotation(XmlType.class); + if (xmlType == null) { + // no @XmlType annotation, we are not interested to go any deeper + return; + } + + List propOrder = inspector.getPropOrder(beanClass); + for (String fieldName: propOrder) { + Method getter = inspector.findPropertyGetter(beanClass, fieldName); + if (getter == null) { + throw new IllegalStateException("No getter for field "+fieldName+" in "+beanClass); + } + Object getterResult; + try { + getterResult = getter.invoke(bean); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new SystemException("Cannot invoke method for field "+fieldName+" in "+beanClass+": "+e.getMessage(), e); + } + + if (getterResult == null) { + continue; + } + + if (getterResult instanceof Collection) { + Collection col = (Collection)getterResult; + if (col.isEmpty()) { + continue; + } + + for (Object element: col) { + visitValue(element, handler); + + } + } else { + visitValue(getterResult, handler); + } + } + } + + private void visitValue(Object element, Handler handler) { + Object elementToMarshall = element; + if (element instanceof JAXBElement){ + elementToMarshall = ((JAXBElement) element).getValue(); + } + visit(elementToMarshall, handler); + } + + private void setExplicitTypeDeclarationIfNeeded(Method getter, Object getterResult, XNode xmap, QName fieldTypeName){ + Class getterReturnType = getter.getReturnType(); + Class getterType = null; + if (Collection.class.isAssignableFrom(getterReturnType)){ + Type genericReturnType = getter.getGenericReturnType(); + if (genericReturnType instanceof ParameterizedType){ + Type actualType = inspector.getTypeArgument(genericReturnType, "explicit type declaration"); + + if (actualType instanceof Class){ + getterType = (Class) actualType; + } + } + } + if (getterType == null){ + getterType = getterReturnType; + } + Class getterResultReturnType = getterResult.getClass(); + if (getterType != getterResultReturnType && getterType.isAssignableFrom(getterResultReturnType)) { + xmap.setExplicitTypeDeclaration(true); + xmap.setTypeQName(fieldTypeName); + } + } + + private XNode marshallValue(T value, QName fieldTypeName, boolean isAttribute, SerializationContext ctx) throws SchemaException { + if (value == null) { + return null; + } + if (isAttribute) { + // hoping the value fits into primitive! + return createPrimitiveXNode(value, fieldTypeName, isAttribute); + } else { + return marshall(value, ctx); + } + } + + private PrimitiveXNode createPrimitiveXNode(T value, QName fieldTypeName, boolean isAttribute) { + PrimitiveXNode xprim = new PrimitiveXNode(); + xprim.setValue(value, fieldTypeName); + xprim.setAttribute(isAttribute); + return xprim; + } + + private PrimitiveXNode createPrimitiveXNode(T val, QName type) { + return createPrimitiveXNode(val, type, false); + } + + private XNode marshalRawType(Object value, SerializationContext sc) throws SchemaException { + return ((RawType) value).serializeToXNode(); + } + + private XNode marshalItemPathType(Object o, SerializationContext sc) { + ItemPathType itemPath = (ItemPathType) o; + PrimitiveXNode xprim = new PrimitiveXNode<>(); + if (itemPath != null) { + xprim.setValue(itemPath, ItemPathType.COMPLEX_TYPE); + } + return xprim; + } + + private XNode marshalSchemaDefinition(Object o, SerializationContext ctx) { + SchemaDefinitionType schemaDefinitionType = (SchemaDefinitionType) o; + SchemaXNode xschema = new SchemaXNode(); + xschema.setSchemaElement(schemaDefinitionType.getSchema()); + MapXNode xmap = new MapXNode(); + xmap.put(DOMUtil.XSD_SCHEMA_ELEMENT, xschema); + return xmap; + } + + // TODO create more appropriate interface to be able to simply serialize ProtectedStringType instances + public MapXNode marshalProtectedDataType(Object o, SerializationContext sc) throws SchemaException { + ProtectedDataType protectedType = (ProtectedDataType) o; + MapXNode xmap = new MapXNode(); + if (protectedType.getEncryptedDataType() != null) { + EncryptedDataType encryptedDataType = protectedType.getEncryptedDataType(); + MapXNode xEncryptedDataType = (MapXNode) marshall(encryptedDataType); + xmap.put(ProtectedDataType.F_ENCRYPTED_DATA, xEncryptedDataType); + } else if (protectedType.getClearValue() != null){ + QName type = XsdTypeMapper.toXsdType(protectedType.getClearValue().getClass()); + PrimitiveXNode xClearValue = createPrimitiveXNode(protectedType.getClearValue(), type); + xmap.put(ProtectedDataType.F_CLEAR_VALUE, xClearValue); + } + // TODO: clearValue + return xmap; + } + + + //region Specific marshallers ============================================================== + private MapXNode marshalSearchFilterType(SearchFilterType value) throws SchemaException { + if (value == null) { + return null; + } + return value.serializeToXNode(); + } + + //endregion + + @NotNull + public PrismContext getPrismContext() { + return prismContext; + } + + private SchemaRegistry getSchemaRegistry() { + return prismContext.getSchemaRegistry(); + } + + public boolean canProcess(QName typeName) { + Class clazz = getSchemaRegistry().determineClassForType(typeName); + if (clazz != null && canProcess(clazz)) { + return true; + } + TypeDefinition td = getSchemaRegistry().findTypeDefinitionByType(typeName); + if (td instanceof SimpleTypeDefinition) { + return true; // most probably dynamic enum, at this point + } + return false; + } + + public boolean canProcess(@NotNull Class clazz) { + return !Containerable.class.isAssignableFrom(clazz) && + (RawType.class.equals(clazz) || clazz.getAnnotation(XmlType.class) != null || XsdTypeMapper.getTypeFromClass(clazz) != null); + } + + public QName determineTypeForClass(Class clazz) { + return inspector.determineTypeForClass(clazz); + } + +} + + +// TODO hacked, for now +// private String findEnumFieldValue(Class classType, Object bean){ +// String name = bean.toString(); +// for (Field field: classType.getDeclaredFields()) { +// XmlEnumValue xmlEnumValue = field.getAnnotation(XmlEnumValue.class); +// if (xmlEnumValue != null && field.getName().equals(name)) { +// return xmlEnumValue.value(); +// } +// } +// return null; +// } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/BeanUnmarshaller.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/BeanUnmarshaller.java new file mode 100644 index 00000000000..7e0d4abc509 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/BeanUnmarshaller.java @@ -0,0 +1,959 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.prism.marshaller; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.lex.dom.DomLexicalProcessor; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.prism.xml.XsdTypeMapper; +import com.evolveum.midpoint.prism.xnode.*; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.logging.LoggingUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; +import com.evolveum.prism.xml.ns._public.types_3.*; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.ClassUtils; +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Element; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.*; +import java.util.*; +import java.util.Map.Entry; + +/** + * Analogous to PrismUnmarshaller, this class unmarshals atomic values from XNode tree structures. + * Atomic values are values that can be used as property values (i.e. either simple types, or + * beans that are not containerables). + */ +public class BeanUnmarshaller { + + private static final Trace LOGGER = TraceManager.getTrace(BeanUnmarshaller.class); + + @NotNull private final PrismBeanInspector inspector; + @NotNull private final PrismContext prismContext; + @NotNull private final Map specialPrimitiveUnmarshallers = new HashMap<>(); + @NotNull private final Map specialMapUnmarshallers = new HashMap<>(); + + public BeanUnmarshaller(@NotNull PrismContext prismContext, @NotNull PrismBeanInspector inspector) { + this.prismContext = prismContext; + this.inspector = inspector; + createSpecialUnmarshallerMaps(); + } + + @FunctionalInterface + private interface PrimitiveUnmarshaller { + T unmarshal(PrimitiveXNode node, Class beanClass, ParsingContext pc) throws SchemaException; + } + + @FunctionalInterface + private interface MapUnmarshaller { + T unmarshal(MapXNode node, Class beanClass, ParsingContext pc) throws SchemaException; + } + + private void add(Class beanClass, PrimitiveUnmarshaller primitive, MapUnmarshaller map) { + specialPrimitiveUnmarshallers.put(beanClass, primitive); + specialMapUnmarshallers.put(beanClass, map); + } + + private void createSpecialUnmarshallerMaps() { + add(XmlAsStringType.class, this::unmarshalXmlAsStringFromPrimitive, this::unmarshalXmlAsStringFromMap); + add(RawType.class, this::unmarshalRawType, this::unmarshalRawType); + add(PolyString.class, this::unmarshalPolyStringFromPrimitive, this::unmarshalPolyStringFromMap); + add(PolyStringType.class, this::unmarshalPolyStringFromPrimitive, this::unmarshalPolyStringFromMap); + add(ItemPathType.class, this::unmarshalItemPath, this::notSupported); + add(ProtectedStringType.class, this::unmarshalProtectedString, this::unmarshalProtectedString); + add(ProtectedByteArrayType.class, this::unmarshalProtectedByteArray, this::unmarshalProtectedByteArray); + add(SchemaDefinitionType.class, this::notSupported, this::unmarshalSchemaDefinitionType); + } + + //region Main entry ========================================================================== + /* + * Preconditions: + * 1. typeName is processable by unmarshaller - i.e. it corresponds to simple or complex type NOT of containerable character + */ + + @NotNull + T unmarshal(@NotNull XNode xnode, @NotNull QName typeQName, @NotNull ParsingContext pc) throws SchemaException { + Class classType = getSchemaRegistry().determineClassForType(typeQName); // TODO use correct method! + if (classType == null) { + TypeDefinition td = getSchemaRegistry().findTypeDefinitionByType(typeQName); + if (td instanceof SimpleTypeDefinition) { + // most probably dynamically defined enum (TODO clarify) + classType = (Class) String.class; + } else { + throw new IllegalArgumentException("Couldn't unmarshal " + typeQName + ". Type definition = " + td); + } + } + return unmarshal(xnode, classType, pc); + } + + @NotNull + T unmarshal(@NotNull XNode xnode, @NotNull Class beanClass, @NotNull ParsingContext pc) throws SchemaException { + T value = unmarshalInternal(xnode, beanClass, pc); + if (PrismContextImpl.isExtraValidation() && value != null) { + Class requested = ClassUtils.primitiveToWrapper(beanClass); + Class actual = ClassUtils.primitiveToWrapper(value.getClass()); + if (!requested.isAssignableFrom(actual)) { + throw new AssertionError("Postcondition fail: unmarshal returned a value of " + value + " (" + + actual + ") which is not of requested type (" + requested + ")"); + } + } + return value; + } + + private T unmarshalInternal(@NotNull XNode xnode, @NotNull Class beanClass, @NotNull ParsingContext pc) throws SchemaException { + if (xnode instanceof RootXNode) { + XNode subnode = ((RootXNode) xnode).getSubnode(); + if (subnode == null) { + throw new IllegalStateException("Couldn't parse " + beanClass + " from a root node with a null content: " + xnode.debugDump()); + } else { + return unmarshal(subnode, beanClass, pc); + } + } else if (!(xnode instanceof MapXNode) && !(xnode instanceof PrimitiveXNode)) { + throw new IllegalStateException("Couldn't parse " + beanClass + " from non-map/non-primitive node: " + xnode.debugDump()); + } + + // only maps and primitives after this point + + if (xnode instanceof PrimitiveXNode) { + PrimitiveXNode prim = (PrimitiveXNode) xnode; + if (XmlTypeConverter.canConvert(beanClass)) { + QName xsdType = XsdTypeMapper.toXsdType(beanClass); + Object parsedValue = prim.getParsedValue(xsdType, beanClass); + return postConvertUnmarshal(parsedValue, pc); + } else if (beanClass.isEnum()) { + return unmarshalEnumFromPrimitive(prim, beanClass, pc); + } + @SuppressWarnings("unchecked") + PrimitiveUnmarshaller unmarshaller = specialPrimitiveUnmarshallers.get(beanClass); + if (unmarshaller != null) { + return unmarshaller.unmarshal(prim, beanClass, pc); + } else if (prim.isEmpty()) { + // Special case. Just return empty object + try { + return beanClass.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new SystemException("Cannot instantiate "+beanClass+": "+e.getMessage(), e); + } + } else { + throw new SchemaException("Cannot convert primitive value to bean of type " + beanClass); + } + } else { + @SuppressWarnings("unchecked") + MapUnmarshaller unmarshaller = specialMapUnmarshallers.get(beanClass); + if (unmarshaller != null) { + return unmarshaller.unmarshal((MapXNode) xnode, beanClass, pc); + } + return unmarshalFromMap((MapXNode) xnode, beanClass, pc); + } + } + + public boolean canProcess(QName typeName) { + return ((PrismContextImpl) getPrismContext()).getBeanMarshaller().canProcess(typeName); + } + + public boolean canProcess(Class clazz) { + return ((PrismContextImpl) getPrismContext()).getBeanMarshaller().canProcess(clazz); + } + //endregion + + + private T unmarshalFromMap(@NotNull MapXNode xmap, @NotNull Class beanClass, @NotNull ParsingContext pc) throws SchemaException { + + if (Containerable.class.isAssignableFrom(beanClass)) { + // This could have come from inside; note we MUST NOT parse this as PrismValue, because for objects we would lose oid/version + @SuppressWarnings("unchecked") + T value = (T) prismContext.parserFor(xmap.toRootXNode()).type(beanClass).parseRealValue(); + return value; + //throw new IllegalArgumentException("Couldn't process Containerable: " + beanClass + " from " + xmap.debugDump()); + } else if (SearchFilterType.class.isAssignableFrom(beanClass)) { + T bean = (T) unmarshalSearchFilterType(xmap, (Class) beanClass, pc); + // TODO fix this BRUTAL HACK - it is here because of c:ConditionalSearchFilterType + return unmarshalFromMapToBean(bean, xmap, Collections.singleton("condition"), pc); + } else { + T bean; + try { + bean = beanClass.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new SystemException("Cannot instantiate bean of type " + beanClass + ": " + e.getMessage(), e); + } + return unmarshalFromMapToBean(bean, xmap, null, pc); + } + } + + private T unmarshalFromMapToBean(@NotNull T bean, @NotNull MapXNode xmap, @Nullable Collection keysToParse, @NotNull ParsingContext pc) throws SchemaException { + @SuppressWarnings("unchecked") + Class beanClass = (Class) bean.getClass(); + for (Entry entry : xmap.entrySet()) { + QName key = entry.getKey(); + if (keysToParse != null && !keysToParse.contains(key.getLocalPart())) { + continue; + } + unmarshalMapEntry(bean, beanClass, entry.getKey(), entry.getValue(), xmap, pc); + } + return bean; + } + + private void unmarshalMapEntry(@NotNull T bean, @NotNull Class beanClass, + @NotNull QName key, @NotNull XNode node, @NotNull MapXNode containingMap, @NotNull ParsingContext pc) throws SchemaException { + + final String propName = key.getLocalPart(); + + // this code is just to keep this method reasonably short + PropertyAccessMechanism mechanism = new PropertyAccessMechanism(); + if (!mechanism.compute(bean, beanClass, propName, key, node, pc)) { + return; + } + + final String actualPropertyName = mechanism.actualPropertyName; + final boolean storeAsRawType = mechanism.storeAsRawType; + + final Method getter = mechanism.getter; + final Method setter = mechanism.setter; + Class paramType = mechanism.paramType; + final boolean wrapInJaxbElement = mechanism.wrapInJaxbElement; + + if (Element.class.isAssignableFrom(paramType)) { + throw new IllegalArgumentException("DOM not supported in field "+actualPropertyName+" in "+beanClass); + } + + //check for subclasses??? + if (!storeAsRawType && node.getTypeQName() != null) { + Class explicitParamType = getSchemaRegistry().determineClassForType(node.getTypeQName()); + if (explicitParamType != null) { + paramType = explicitParamType; + } + } + + if (!(node instanceof ListXNode) && Object.class.equals(paramType) && !storeAsRawType) { + throw new IllegalArgumentException("Object property (without @Raw) not supported in field "+actualPropertyName+" in "+beanClass); + } + + String paramNamespace = inspector.determineNamespace(paramType); + + boolean problem = false; + Object propValue = null; + Collection propValues = null; + if (node instanceof ListXNode) { + ListXNode xlist = (ListXNode)node; + if (setter != null) { + try { + propValue = convertSinglePropValue(node, actualPropertyName, paramType, storeAsRawType, beanClass, paramNamespace, pc); + } catch (SchemaException e) { + problem = processSchemaException(e, node, pc); + } + } else { + // No setter, we have to use collection getter + propValues = new ArrayList<>(xlist.size()); + for (XNode xsubsubnode: xlist) { + try { + propValues.add(convertSinglePropValue(xsubsubnode, actualPropertyName, paramType, storeAsRawType, beanClass, paramNamespace, pc)); + } catch (SchemaException e) { + problem = processSchemaException(e, xsubsubnode, pc); + } + } + } + } else { + try { + propValue = convertSinglePropValue(node, actualPropertyName, paramType, storeAsRawType, beanClass, paramNamespace, pc); + } catch (SchemaException e) { + problem = processSchemaException(e, node, pc); + } + } + + if (setter != null) { + Object value = null; + try { + value = prepareValueToBeStored(propValue, wrapInJaxbElement, mechanism.objectFactory, mechanism.elementFactoryMethod, propName, beanClass, pc); + setter.invoke(bean, value); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new SystemException("Cannot invoke setter "+setter+" on bean of type "+beanClass+": "+e.getMessage(), e); + } + } else if (getter != null) { + Object getterReturn; + Collection col; + try { + getterReturn = getter.invoke(bean); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new SystemException("Cannot invoke getter "+getter+" on bean of type "+beanClass+": "+e.getMessage(), e); + } + try { + col = (Collection)getterReturn; + } catch (ClassCastException e) { + throw new SystemException("Getter "+getter+" on bean of type "+beanClass+" returned "+getterReturn+" instead of collection"); + } + if (propValue != null) { + col.add(prepareValueToBeStored(propValue, wrapInJaxbElement, mechanism.objectFactory, mechanism.elementFactoryMethod, propName, beanClass, pc)); + } else if (propValues != null) { + for (Object propVal: propValues) { + col.add(prepareValueToBeStored(propVal, wrapInJaxbElement, mechanism.objectFactory, mechanism.elementFactoryMethod, propName, beanClass, pc)); + } + } else if (!problem) { + throw new IllegalStateException("Strange. Multival property "+propName+" in "+beanClass+" produced null values list, parsed from "+containingMap); + } + checkJaxbElementConsistence(col, pc); + } else { + throw new IllegalStateException("Uh? No setter nor getter."); + } + } + + private class PropertyAccessMechanism { + + Class beanClass; + + // phase1 + String actualPropertyName; // This is the name of property we will really use. (Considering e.g. substitutions.) + boolean storeAsRawType; // Whether the data will be stored as RawType. + Object objectFactory; // JAXB object factory instance (e.g. xxxx.common-3.ObjectFactory). + Method elementFactoryMethod; // Method in object factory that creates a given JAXB element (e.g. createAsIs(value)) + + // phase2 + Method getter, setter; // Getter or setter that will be used to put a value (getter in case of collections) + Class paramType; // Actual parameter type; unwrapped: Collection -> X, JAXBElement -> X + boolean wrapInJaxbElement; // If the paramType contained JAXBElement, i.e. if the value should be wrapped into it before using + + // returns true if the processing is to be continued; + // false in case of using alternative way of unmarshalling (e.g. use of "any" method), or in case of error (in COMPAT mode) + private boolean compute(T bean, Class beanClass, String propName, QName key, XNode node, ParsingContext pc) + throws SchemaException { + + this.beanClass = beanClass; + + // phase1 + if (!computeActualPropertyName(bean, propName, key, node, pc)) { + return false; + } + // phase2 + return computeGetterAndSetter(propName, pc); + } + + // computes actualPropertyName + storeAsRawType + // if necessary, fills-in also objectFactory + elementFactoryMethod + private boolean computeActualPropertyName(T bean, String propName, QName key, XNode node, ParsingContext pc) + throws SchemaException { + Field propertyField = inspector.findPropertyField(beanClass, propName); + Method propertyGetter = null; + if (propertyField == null) { + propertyGetter = inspector.findPropertyGetter(beanClass, propName); + } + + elementFactoryMethod = null; + objectFactory = null; + if (propertyField == null && propertyGetter == null) { + // We have to try to find a more generic field, such as xsd:any or substitution element + // check for global element definition first + elementFactoryMethod = findElementFactoryMethod(propName); + if (elementFactoryMethod != null) { + // great - global element found, let's look up the field + propertyField = inspector.lookupSubstitution(beanClass, elementFactoryMethod); + if (propertyField == null) { + propertyField = inspector.findAnyField(beanClass); // Check for "any" field + if (propertyField != null) { + unmarshalToAnyUsingField(bean, propertyField, key, node, pc); + } else { + unmarshalToAnyUsingGetterIfExists(bean, key, node, pc, propName); + } + return false; + } + } else { + unmarshalToAnyUsingGetterIfExists(bean, key, node, pc, propName); // e.g. "getAny()" + return false; + } + } + + // At this moment, property getter is the exact getter matching key.localPart (propName). + // Property field may be either exact field matching key.localPart (propName), or more generic one (substitution, any). + //noinspection ConstantConditions + assert propertyGetter != null || propertyField != null; + + if (elementFactoryMethod != null) { + storeAsRawType = elementFactoryMethod.getAnnotation(Raw.class) != null; + } else if (propertyGetter != null) { + storeAsRawType = propertyGetter.getAnnotation(Raw.class) != null; + } else { + storeAsRawType = propertyField.getAnnotation(Raw.class) != null; + } + + if (propertyField != null) { + actualPropertyName = propertyField.getName(); + } else { + actualPropertyName = propName; + } + + return true; + } + + private Method findElementFactoryMethod(String propName) { + Class objectFactoryClass = inspector.getObjectFactoryClass(beanClass.getPackage()); + objectFactory = instantiateObjectFactory(objectFactoryClass); + return inspector.findElementMethodInObjectFactory(objectFactoryClass, propName); + } + + private boolean computeGetterAndSetter(String propName, ParsingContext pc) throws SchemaException { + setter = inspector.findSetter(beanClass, actualPropertyName); + wrapInJaxbElement = false; + paramType = null; + if (setter == null) { + // No setter. But if the property is multi-value we need to look + // for a getter that returns a collection (Collection) + getter = inspector.findPropertyGetter(beanClass, actualPropertyName); + if (getter == null) { + pc.warnOrThrow(LOGGER, "Cannot find setter or getter for field " + actualPropertyName + " in " + beanClass); + return false; + } + computeParamTypeFromGetter(propName, getter.getReturnType()); + } else { + getter = null; + Class setterType = setter.getParameterTypes()[0]; + computeParamTypeFromSetter(propName, setterType); + } + return true; + } + + private void computeParamTypeFromSetter(String propName, Class setterParamType) { + if (JAXBElement.class.equals(setterParamType)) { + // TODO some handling for the returned generic parameter types + Type[] genericTypes = setter.getGenericParameterTypes(); + if (genericTypes.length != 1) { + throw new IllegalArgumentException("Too lazy to handle this."); + } + Type genericType = genericTypes[0]; + if (genericType instanceof ParameterizedType) { + Type actualType = inspector.getTypeArgument(genericType, "add some description"); + if (actualType instanceof WildcardType) { + if (elementFactoryMethod == null) { + elementFactoryMethod = findElementFactoryMethod(propName); + } + // This is the case of Collection> + // we need to extract the specific type from the factory method + if (elementFactoryMethod == null) { + throw new IllegalArgumentException( + "Wildcard type in JAXBElement field specification and no factory method found for field " + + actualPropertyName + " in " + beanClass + + ", cannot determine collection type (inner type argument)"); + } + Type factoryMethodGenericReturnType = elementFactoryMethod.getGenericReturnType(); + Type factoryMethodTypeArgument = inspector.getTypeArgument(factoryMethodGenericReturnType, + "in factory method " + elementFactoryMethod + " return type for field " + actualPropertyName + + " in " + beanClass + ", cannot determine collection type"); + if (factoryMethodTypeArgument instanceof Class) { + // This is the case of JAXBElement + paramType = (Class) factoryMethodTypeArgument; + if (Object.class.equals(paramType) && !storeAsRawType) { + throw new IllegalArgumentException("Factory method " + elementFactoryMethod + + " type argument is Object (without @Raw) for field " + + actualPropertyName + " in " + beanClass + ", property " + propName); + } + } else { + throw new IllegalArgumentException( + "Cannot determine factory method return type, got " + factoryMethodTypeArgument + + " - for field " + actualPropertyName + " in " + beanClass + + ", cannot determine collection type (inner type argument)"); + } + } + } + // Class enclosing = paramType.getEnclosingClass(); + // Class clazz = paramType.getClass(); + // Class declaring = paramType.getDeclaringClass(); + wrapInJaxbElement = true; + } else { + paramType = setterParamType; + } + } + + private void computeParamTypeFromGetter(String propName, Class getterReturnType) throws SchemaException { + if (!Collection.class.isAssignableFrom(getterReturnType)) { + throw new SchemaException("Cannot find getter for field " + actualPropertyName + " in " + beanClass + + " does not return collection, cannot use it to set value"); + } + // getter.genericReturnType = Collection<...> + Type typeArgument = inspector.getTypeArgument(getter.getGenericReturnType(), + "for field " + actualPropertyName + " in " + beanClass + ", cannot determine collection type"); + if (typeArgument instanceof Class) { + paramType = (Class) typeArgument; // ok, like Collection + } else if (typeArgument instanceof ParameterizedType) { // something more complex + ParameterizedType paramTypeArgument = (ParameterizedType) typeArgument; + Type rawTypeArgument = paramTypeArgument.getRawType(); + if (rawTypeArgument.equals(JAXBElement.class)) { + // This is the case of Collection> + wrapInJaxbElement = true; + Type innerTypeArgument = inspector.getTypeArgument(typeArgument, + "for field " + actualPropertyName + " in " + beanClass + + ", cannot determine collection type (inner type argument)"); + if (innerTypeArgument instanceof Class) { + // This is the case of Collection> (note that wrapInJaxbElement is now true) + paramType = (Class) innerTypeArgument; + } else if (innerTypeArgument instanceof WildcardType) { + // This is the case of Collection> + // we need to extract the specific type from the factory method + if (elementFactoryMethod == null) { + elementFactoryMethod = findElementFactoryMethod(propName); + if (elementFactoryMethod == null) { + throw new IllegalArgumentException( + "Wildcard type in JAXBElement field specification and no factory method found for field " + + actualPropertyName + " in " + beanClass + + ", cannot determine collection type (inner type argument)"); + } + } + // something like JAXBElement + Type factoryMethodGenericReturnType = elementFactoryMethod.getGenericReturnType(); + Type factoryMethodTypeArgument = inspector.getTypeArgument(factoryMethodGenericReturnType, + "in factory method " + elementFactoryMethod + " return type for field " + actualPropertyName + + " in " + beanClass + ", cannot determine collection type"); + if (factoryMethodTypeArgument instanceof Class) { + // This is the case of JAXBElement + paramType = (Class) factoryMethodTypeArgument; + if (Object.class.equals(paramType) && !storeAsRawType) { + throw new IllegalArgumentException("Factory method " + elementFactoryMethod + + " type argument is Object (and not @Raw) for field " + + actualPropertyName + " in " + beanClass + ", property " + propName); + } + } else { + throw new IllegalArgumentException( + "Cannot determine factory method return type, got " + factoryMethodTypeArgument + + " - for field " + actualPropertyName + " in " + beanClass + + ", cannot determine collection type (inner type argument)"); + } + } else { + throw new IllegalArgumentException( + "Ejha! " + innerTypeArgument + " " + innerTypeArgument.getClass() + " from " + + getterReturnType + " from " + actualPropertyName + " in " + propName + " " + + beanClass); + } + } else { + // The case of Collection> + if (rawTypeArgument instanceof Class) { // ??? rawTypeArgument is the 'Whatever' part + paramType = (Class) rawTypeArgument; + } else { + throw new IllegalArgumentException( + "EH? Eh!? " + typeArgument + " " + typeArgument.getClass() + " from " + getterReturnType + + " from " + actualPropertyName + " in " + propName + " " + beanClass); + } + } + } else { + throw new IllegalArgumentException( + "EH? " + typeArgument + " " + typeArgument.getClass() + " from " + getterReturnType + " from " + + actualPropertyName + " in " + propName + " " + beanClass); + } + } + } + + private void unmarshalToAnyUsingGetterIfExists(@NotNull T bean, @NotNull QName key, @NotNull XNode node, + @NotNull ParsingContext pc, String propName) throws SchemaException { + Method elementMethod = inspector.findAnyMethod(bean.getClass()); + if (elementMethod != null) { + unmarshallToAnyUsingGetter(bean, elementMethod, key, node, pc); + } else { + pc.warnOrThrow(LOGGER, "No field "+propName+" in class "+bean.getClass()+" (and no element method in object factory too)"); + } + } +// +// if (prismContext != null && bean instanceof Revivable) { +// ((Revivable)bean).revive(prismContext); +// } +// +// return bean; +// } +// + // Prepares value to be stored into the bean - e.g. converts PolyString->PolyStringType, wraps a value to JAXB if specified, ... + private Object prepareValueToBeStored(Object propVal, boolean wrapInJaxbElement, Object objectFactory, Method factoryMehtod, String propName, + Class beanClass, ParsingContext pc) { + + if (propVal instanceof PolyString) { + propVal = new PolyStringType((PolyString) propVal); + } + + if (wrapInJaxbElement) { + if (factoryMehtod == null) { + throw new IllegalArgumentException("Param type is JAXB element but no factory method found for it, property "+propName+" in "+beanClass); + } + try { + return factoryMehtod.invoke(objectFactory, propVal); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new SystemException("Unable to invoke factory method "+factoryMehtod+" on "+objectFactory.getClass()+" for property "+propName+" in "+beanClass); + } + } else { + return propVal; + } + } + + /* + * We want to avoid this: + * + * + * up + * + * + * Because it cannot be reasonably serialized in XNode ( gets changed to - * up - * - * - * Because it cannot be reasonably serialized in XNode ( gets changed to + + + + + + + + + + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; icfs:uid + + + Entry UUID + + + + + + + + true + + + + + + + + + + + + + + + cn + Common Name + + + + + + true + true + true + + + + + + + + + $user/fullName + + + + + $user/fullName + + + + + + + + sn + + Surname + + + true + true + true + + + + + + + familyName + + + + + + familyName + + + + + + + givenName + Given Name + + + + true + true + true + + + + + + + + + + $user/givenName + + + + + $user/givenName + + + + + + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff"; ri:uid + Login Name + stringIgnoreCase + + weak + + Source may have description + $user/name + + + + + Targets may have description + $user/name + + + + + + + description + + + + weak + + Expression that assigns a fixed value + Created by IDM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + employeeType + Employee Type + false + + + $user/employeeType + + + + + departmentNumber + Department Number + true + + + $user/extension/dept + + + + + + + + + l + false + + + + + + defaultLocation + middle of nowhere + + + + + + + + + + + + + + + weak + + + + + + + + + + + + weak + + + + + + + + + uid=idm,ou=Administrators,dc=example,dc=com + + + + + + + + + + + + + + + + ds-pwp-account-disabled + + true + + + + false + + + + + + + + + true + + + + + ... + + + name + + + $account/attributes/yyy + + + + + true + + + + + + + + linked + true + + + deleted + + unlinkAccount + + + + unlinked + + + + unmatched + + + + + + + + + + diff --git a/infra/schema/src/test/resources/common/xml/no-ns/user-jack.xml b/infra/schema/src/test/resources/common/xml/no-ns/user-jack.xml new file mode 100644 index 00000000000..bdd44b69a4e --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/no-ns/user-jack.xml @@ -0,0 +1,104 @@ + + + + + jack + + + BAR + 42 + raz + dva + tri + + openS3zam3 + + + + + + jsparrow + + AccountObjectClass + + + + + captain + + Rum Supply System + + + http://midpoint.evolveum.com/xml/ns/public/resource/instance/2f9b9299-5555-5555-5555-000000002222 + + AccountObjectClass + + + + + This is third accountRef + + + + connectorType + org.identityconnectors.ldap.LdapConnector + + + + + + + 42 + + + + + + + + enabled + + + Jack Sparrow + Jack + Sparrow + Cpt. + + Brethren of the Coast + Davie Jones' Locker + + + + + + + + http://www.w3.org/2001/04/xmlenc#aes256-cbc + + + HF6JRsNMeJt6alihT44CXKgpe0c= + + + blc5OXO2Z4vJW7o/XXhqZzg/rkwsIOwRBK7KLgMqwcrVcYpeZZOjxzgRgFiNw4IB + + + + + + + diff --git a/infra/schema/src/test/resources/common/xml/ns/certification-case-1.xml b/infra/schema/src/test/resources/common/xml/ns/certification-case-1.xml new file mode 100644 index 00000000000..79d5e7c066d --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/ns/certification-case-1.xml @@ -0,0 +1,62 @@ + + + + + + 1 + + 2015-12-04T00:38:00.708+01:00 + 2015-12-18T23:59:59.999+01:00 + + 1 + + revoke + 2015-12-04T01:10:13.814+01:00 + + revoke + + + + + + + + ri:cn + + strong + + CN + + + + + ri:sn + + strong + + SN + + + + + + false + diff --git a/infra/schema/src/test/resources/common/xml/ns/mapping.xml b/infra/schema/src/test/resources/common/xml/ns/mapping.xml new file mode 100644 index 00000000000..2733cf5a6bc --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/ns/mapping.xml @@ -0,0 +1,45 @@ + + + + + + $user/name + + + + x:foo + Captain + + + y:sailor + + + + + diff --git a/infra/schema/src/test/resources/common/xml/ns/mappings.xml b/infra/schema/src/test/resources/common/xml/ns/mappings.xml new file mode 100644 index 00000000000..dafd2b0013b --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/ns/mappings.xml @@ -0,0 +1,47 @@ + + + + + + + $user/name + + + + x:foo + Captain + + + y:sailor + + + + + + diff --git a/infra/schema/src/test/resources/common/xml/ns/resource-opendj-simple.xml b/infra/schema/src/test/resources/common/xml/ns/resource-opendj-simple.xml new file mode 100644 index 00000000000..3209731be38 --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/ns/resource-opendj-simple.xml @@ -0,0 +1,70 @@ + + + + + + + + + + Embedded Test OpenDJ + embedded test opendj + + + + + + + connectorType + org.identityconnectors.ldap.LdapConnector + + + run + + + + + + + + + 10389 + localhost + dc=example,dc=com + cn=directory manager + + secret + + + uid + ds-pwp-account-disabled + + + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/common/resource-opendj.xml b/infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml similarity index 99% rename from infra/schema/src/test/resources/common/resource-opendj.xml rename to infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml index 5955651bc6a..bfd42d829f0 100644 --- a/infra/schema/src/test/resources/common/resource-opendj.xml +++ b/infra/schema/src/test/resources/common/xml/ns/resource-opendj.xml @@ -35,10 +35,7 @@ xmlns:mr="http://midpoint.evolveum.com/xml/ns/public/common/matching-rule-3"> - - Embedded Test OpenDJ - embedded test opendj - + Embedded Test OpenDJ @@ -83,8 +80,7 @@ dc=example,dc=com cn=directory manager - secret - + secret uid ds-pwp-account-disabled diff --git a/infra/schema/src/test/resources/common/xml/ns/shadow-hbarbossa.xml b/infra/schema/src/test/resources/common/xml/ns/shadow-hbarbossa.xml new file mode 100644 index 00000000000..1345eced7d9 --- /dev/null +++ b/infra/schema/src/test/resources/common/xml/ns/shadow-hbarbossa.xml @@ -0,0 +1,40 @@ + + + + hbarbossa + + false + linked + + linked + syncChannel + + qn80:AccountObjectClass + + Hector Barbossa + uid=hbarbossa,ou=people,dc=example,dc=com + Barbossa + hbarbossa + 8daaeeae-f0c7-41c9-b258-2a3351aa8876 + + + enabled + + diff --git a/infra/schema/src/test/resources/common/xml/user-jack.xml b/infra/schema/src/test/resources/common/xml/ns/user-jack.xml similarity index 83% rename from infra/schema/src/test/resources/common/xml/user-jack.xml rename to infra/schema/src/test/resources/common/xml/ns/user-jack.xml index ad70cdaf5cd..4cc59396759 100644 --- a/infra/schema/src/test/resources/common/xml/user-jack.xml +++ b/infra/schema/src/test/resources/common/xml/ns/user-jack.xml @@ -28,10 +28,7 @@ xmlns:foo="http://www.example.com/foo" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ext="http://midpoint.evolveum.com/xml/ns/test/extension"> - - jack - jack - + jack BAR @@ -73,7 +70,7 @@ connectorType - >org.identityconnectors.ldap.LdapConnector + org.identityconnectors.ldap.LdapConnector @@ -91,31 +88,13 @@ enabled - - Jack Sparrow - jack sparrow - - - Jack - jack - - - Sparrow - sparrow - - - Cpt. - cpt - + Jack Sparrow + Jack + Sparrow + Cpt. - - Brethren of the Coast - brethren of the coast - - - Davie Jones' Locker - davie jones locker - + Brethren of the Coast + Davie Jones' Locker diff --git a/infra/schema/src/test/resources/common/yaml/no-ns/resource-opendj-simple.yaml b/infra/schema/src/test/resources/common/yaml/no-ns/resource-opendj-simple.yaml new file mode 100644 index 00000000000..8c8eadd92c5 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/no-ns/resource-opendj-simple.yaml @@ -0,0 +1,25 @@ +--- +resource: + oid: "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff" + name: + orig: "Embedded Test OpenDJ" + norm: "embedded test opendj" + connectorRef: + type: "ConnectorType" + filter: + description: "...a filter description..." + equal: + path: "connectorType" + value: "org.identityconnectors.ldap.LdapConnector" + resolutionTime: run + connectorConfiguration: + configurationProperties: + port: "10389" + host: "localhost" + baseContexts: "dc=example,dc=com" + principal: "cn=directory manager" + credentials: + '@ns': "http://prism.evolveum.com/xml/ns/public/types-3" + clearValue: "secret" + vlvSortAttribute: "uid" + accountOperationalAttributes: "ds-pwp-account-disabled" diff --git a/infra/schema/src/test/resources/common/yaml/no-ns/resource-opendj.yaml b/infra/schema/src/test/resources/common/yaml/no-ns/resource-opendj.yaml new file mode 100644 index 00000000000..d00e010c279 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/no-ns/resource-opendj.yaml @@ -0,0 +1,349 @@ +--- +resource: + oid: "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff" + name: "Embedded Test OpenDJ" + fetchResult: + operation: "com.evolveum.midpoint.provisioning.api.ProvisioningService.getObject" + status: "success" + params: + entry: + - unknownJavaObject: + class: "my.class" + toString: "my.value" + key: "a-key" + connectorRef: + type: "ConnectorType" + description: "Reference to the ICF LDAP connector." + filter: + description: "...a filter description..." + equal: + path: "extension/extConnType" + value: "org.identityconnectors.ldap.LdapConnector" + resolutionTime: "import" + connectorConfiguration: + configurationProperties: + port: "10389" + host: "localhost" + baseContexts: "dc=example,dc=com" + principal: "cn=directory manager" + credentials: + clearValue: "secret" + vlvSortAttribute: "uid" + accountOperationalAttributes: "ds-pwp-account-disabled" + connectorPoolConfiguration: + minEvictableIdleTimeMillis: 120000 + minIdle: 1 + maxIdle: 10 + maxObjects: 10 + maxWait: 150000 + producerBufferSize: 100 + timeouts: + create: -1 + get: -1 + update: -1 + delete: -1 + test: -1 + scriptOnConnector: -1 + scriptOnResource: -1 + authentication: -1 + search: -1 + validate: -1 + sync: -1 + schema: -1 + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff" + schema: + definition: + '@ns': "http://www.w3.org/2001/XMLSchema" + schema: "\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\ + \t icfs:uid\n\t\t\t icfs:name\n\t\t\t icfs:name\n\t\t\t __GROUP__\n\t\t\t\t\t\t\t\n\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\ + \t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\ + \n\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t \n\t\t\ + \t icfs:uid\n\t\t\t icfs:name\n\t\t\t icfs:name\n\t\t\t __ACCOUNT__\n\t\t\t \n\t\t\t \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\ + \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\ + \t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\ + \t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\ + \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\ + \t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\ + \t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\ + \t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t" + schemaHandling: + objectType: + - intent: "default" + displayName: "Default Account" + default: true + objectClass: "AccountObjectClass" + attribute: + - ref: "name" + displayName: "Distinguished Name" + limitations: + - access: + read: true + add: true + outbound: + strength: "weak" + source: + - path: "$user/name" + expression: + script: + - code: "'uid=' +name+ ',ou=people,dc=example,dc=com'" + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:uid" + displayName: "Entry UUID" + limitations: + - access: + read: true + - ref: "cn" + displayName: "Common Name" + limitations: + - access: + read: true + add: true + modify: true + outbound: + source: + - path: "$user/fullName" + inbound: + - target: + path: "$user/fullName" + - ref: "sn" + displayName: "Surname" + limitations: + - access: + read: true + add: true + modify: true + outbound: + source: + - path: "familyName" + inbound: + - target: + path: "familyName" + - ref: "givenName" + displayName: "Given Name" + limitations: + - access: + read: true + add: true + modify: true + outbound: + source: + - path: "$user/givenName" + inbound: + - target: + path: "$user/givenName" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:uid" + displayName: "Login Name" + matchingRule: "stringIgnoreCase" + outbound: + strength: "weak" + source: + - description: "Source may have description" + path: "$user/name" + inbound: + - target: + description: "Targets may have description" + path: "$user/name" + - ref: "description" + outbound: + strength: "weak" + expression: + description: "Expression that assigns a fixed value" + value: + - "Created by IDM" + - ref: "employeeType" + displayName: "Employee Type" + tolerant: false + outbound: + source: + - path: "$user/employeeType" + - ref: "departmentNumber" + displayName: "Department Number" + tolerant: true + outbound: + source: + - path: "$user/extension/dept" + - ref: "l" + tolerant: false + outbound: + expression: + variable: + - name: "defaultLocation" + value: !string "middle of nowhere" + script: + - description: "XPath expression that is using a variable declared above" + language: "http://www.w3.org/TR/xpath/" + returnType: "scalar" + code: "$defaultLocation" + protected: + name: "uid=idm,ou=Administrators,dc=example,dc=com" + activation: + administrativeStatus: + outbound: + inbound: + - strength: "weak" + expression: + asIs: + credentials: + password: + outbound: + expression: + asIs: + inbound: + - strength: "weak" + expression: + generate: + capabilities: + native: + credentials: + password: + liveSync: + testConnection: + configured: + activation: + - status: + attribute: "ds-pwp-account-disabled" + enableValue: + - "" + disableValue: + - "true" + liveSync: + - enabled: false + synchronization: + objectSynchronization: + - enabled: true + correlation: + - http://prism.evolveum.com/xml/ns/public/query-3#description: "\n \ + \ ...\n " + http://prism.evolveum.com/xml/ns/public/query-3#equal: + http://prism.evolveum.com/xml/ns/public/query-3#path: "name" + expression: + path: | + $account/attributes/yyy + condition: + value: true + reaction: + - situation: "linked" + synchronize: true + - situation: "deleted" + action: + - handlerUri: "unlinkAccount" + - situation: "unlinked" + action: + - ref: "linkAccount" + - situation: "unmatched" + action: + - userTemplateRef: + oid: "c0c010c0-d34d-b33f-f00d-777111111111" + ref: "addUser" \ No newline at end of file diff --git a/infra/schema/src/test/resources/common/yaml/no-ns/user-jack.yaml b/infra/schema/src/test/resources/common/yaml/no-ns/user-jack.yaml new file mode 100644 index 00000000000..eadd7aac909 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/no-ns/user-jack.yaml @@ -0,0 +1,65 @@ +--- +object: !UserType + oid: 2f9b9299-6f45-498f-bc8e-8d17c6b93b20 + name: jack + extension: + bar : !string BAR + num : !int 42 + multi: + - !string raz + - !string dva + - !string tri + password: !ProtectedStringType + clearValue: "openS3zam3" + link: + - + oid: 2f9b9299-6f45-498f-aaaa-000000001111 + name: jsparrow + resourceRef: + oid: 2f9b9299-5555-5555-5555-000000001111 + objectClass: AccountObjectClass + - + oid: 2f9b9299-6f45-498f-aaaa-000000002222 + name: captain + resource: + oid: 2f9b9299-5555-5555-5555-000000001111 + name: Rum Supply System + connectorRef: + oid: 2f9b9299-cccc-cccc-cccc-000000002222 + connectorConfiguration: { } + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/2f9b9299-5555-5555-5555-000000002222" + objectClass: AccountObjectClass + linkRef: + oid: 2f9b9299-6f45-498f-aaaa-000000003333 + type: "ShadowType" + description: This is third accountRef + filter: + equal: + path: connectorType + value: org.identityconnectors.ldap.LdapConnector + assignment: + id: 111 + extension: + intType: 42 + construction: + resourceRef: + oid: 2f9b9299-5555-5555-5555-000000001111 + activation: + administrativeStatus: enabled + fullName: Jack Sparrow + givenName: Jack + familyName: Sparrow + honorificPrefix: Cpt. + emailAddress: + organizationalUnit: [ "Brethren of the Coast", "Davie Jones' Locker" ] + locality: "" + credentials: + password: + value: + encryptedData: + encryptionMethod: + algorithm: "http://www.w3.org/2001/04/xmlenc#aes256-cbc" + keyInfo: + keyName: "HF6JRsNMeJt6alihT44CXKgpe0c=" + cipherData: + cipherValue: "blc5OXO2Z4vJW7o/XXhqZzg/rkwsIOwRBK7KLgMqwcrVcYpeZZOjxzgRgFiNw4IB" \ No newline at end of file diff --git a/infra/schema/src/test/resources/common/yaml/ns/resource-opendj-simple.yaml b/infra/schema/src/test/resources/common/yaml/ns/resource-opendj-simple.yaml new file mode 100644 index 00000000000..bf7c4c8f426 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/ns/resource-opendj-simple.yaml @@ -0,0 +1,30 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +resource: + oid: "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff" + name: + '@ns': "http://prism.evolveum.com/xml/ns/public/types-3" + orig: "Embedded Test OpenDJ" + norm: "embedded test opendj" + connectorRef: + type: "ConnectorType" + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + description: "...a filter description..." + equal: + path: "connectorType" + value: "org.identityconnectors.ldap.LdapConnector" + resolutionTime: run + connectorConfiguration: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" + configurationProperties: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.ldap.ldap/org.identityconnectors.ldap.LdapConnector" + port: "10389" + host: "localhost" + baseContexts: "dc=example,dc=com" + principal: "cn=directory manager" + credentials: + '@ns': "http://prism.evolveum.com/xml/ns/public/types-3" + clearValue: "secret" + vlvSortAttribute: "uid" + accountOperationalAttributes: "ds-pwp-account-disabled" diff --git a/infra/schema/src/test/resources/common/yaml/ns/resource-opendj.yaml b/infra/schema/src/test/resources/common/yaml/ns/resource-opendj.yaml new file mode 100644 index 00000000000..271d39e5302 --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/ns/resource-opendj.yaml @@ -0,0 +1,360 @@ +--- +'@ns': "http://midpoint.evolveum.com/xml/ns/public/common/common-3" +resource: + oid: "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff" + name: "Embedded Test OpenDJ" + fetchResult: + operation: "com.evolveum.midpoint.provisioning.api.ProvisioningService.getObject" + status: "success" + params: + entry: + - unknownJavaObject: + class: "my.class" + toString: "my.value" + key: "a-key" + connectorRef: + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ConnectorType" + description: "Reference to the ICF LDAP connector." + filter: + '@ns': "http://prism.evolveum.com/xml/ns/public/query-3" + description: "...a filter description..." + equal: + path: "declare namespace x='http://x/'; extension/x:extConnType" + value: "org.identityconnectors.ldap.LdapConnector" + resolutionTime: "import" + connectorConfiguration: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3" + configurationProperties: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/org.forgerock.openicf.connectors.ldap.ldap/org.identityconnectors.ldap.LdapConnector" + port: "10389" + host: "localhost" + baseContexts: "dc=example,dc=com" + principal: "cn=directory manager" + credentials: + '@ns': "http://prism.evolveum.com/xml/ns/public/types-3" + clearValue: "secret" + vlvSortAttribute: "uid" + accountOperationalAttributes: "ds-pwp-account-disabled" + connectorPoolConfiguration: + minEvictableIdleTimeMillis: 120000 + minIdle: 1 + maxIdle: 10 + maxObjects: 10 + maxWait: 150000 + producerBufferSize: 100 + timeouts: + create: -1 + get: -1 + update: -1 + delete: -1 + test: -1 + scriptOnConnector: -1 + scriptOnResource: -1 + authentication: -1 + search: -1 + validate: -1 + sync: -1 + schema: -1 + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff" + schema: + definition: + '@ns': "http://www.w3.org/2001/XMLSchema" + schema: "\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\ + \t icfs:uid\n\t\t\t icfs:name\n\t\t\t icfs:name\n\t\t\t __GROUP__\n\t\t\t\t\t\t\t\n\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\ + \t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\ + \n\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t \n\t\t\ + \t icfs:uid\n\t\t\t icfs:name\n\t\t\t icfs:name\n\t\t\t __ACCOUNT__\n\t\t\t \n\t\t\t \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\ + \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\ + \t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\ + \t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\ + \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\ + \t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\ + \t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\ + \t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\ + \t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t" + schemaHandling: + objectType: + - intent: "default" + displayName: "Default Account" + default: true + objectClass: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff#AccountObjectClass" + attribute: + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:name" + displayName: "Distinguished Name" + limitations: + - access: + read: true + add: true + outbound: + strength: "weak" + source: + - path: "$user/name" + expression: + script: + - code: "'uid=' +name+ ',ou=people,dc=example,dc=com'" + - ref: "declare namespace icfs='http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3'; icfs:uid" + displayName: "Entry UUID" + limitations: + - access: + read: true + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:cn" + displayName: "Common Name" + limitations: + - access: + read: true + add: true + modify: true + outbound: + source: + - path: "$user/fullName" + inbound: + - target: + path: "$user/fullName" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:sn" + displayName: "Surname" + limitations: + - access: + read: true + add: true + modify: true + outbound: + source: + - path: "familyName" + inbound: + - target: + path: "familyName" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:givenName" + displayName: "Given Name" + limitations: + - access: + read: true + add: true + modify: true + outbound: + source: + - path: "$user/givenName" + inbound: + - target: + path: "$user/givenName" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:uid" + displayName: "Login Name" + matchingRule: "http://midpoint.evolveum.com/xml/ns/public/common/matching-rule-3#stringIgnoreCase" + outbound: + strength: "weak" + source: + - description: "Source may have description" + path: "$user/name" + inbound: + - target: + description: "Targets may have description" + path: "$user/name" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:description" + outbound: + strength: "weak" + expression: + description: "Expression that assigns a fixed value" + value: + - "Created by IDM" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:employeeType" + displayName: "Employee Type" + tolerant: false + outbound: + source: + - path: "$user/employeeType" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:departmentNumber" + displayName: "Department Number" + tolerant: true + outbound: + source: + - path: "declare namespace z='http://z/'; $user/extension/z:dept" + - ref: "declare namespace ri='http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff'; ri:l" + tolerant: false + outbound: + expression: + variable: + - name: "http://whatever.com/my#defaultLocation" + value: ! "middle of nowhere" + script: + - description: "XPath expression that is using a variable declared above" + language: "http://www.w3.org/TR/xpath/" + returnType: "scalar" + code: "\n\t\t\t\t\t\t\t\t\t$my:defaultLocation\n\t\t\t\t\t\t\t" + protected: + - '@ns': "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" + name: "uid=idm,ou=Administrators,dc=example,dc=com" + activation: + administrativeStatus: + outbound: + inbound: + - strength: "weak" + expression: + asIs: + credentials: + password: + outbound: + expression: + asIs: + inbound: + - strength: "weak" + expression: + generate: + capabilities: + native: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3" + credentials: + password: + liveSync: + testConnection: + configured: + '@ns': "http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3" + activation: + - status: + attribute: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff#ds-pwp-account-disabled" + enableValue: + - "" + disableValue: + - "true" + liveSync: + - enabled: false + synchronization: + objectSynchronization: + - enabled: true + correlation: + - http://prism.evolveum.com/xml/ns/public/query-3#description: "\n \ + \ ...\n " + http://prism.evolveum.com/xml/ns/public/query-3#equal: + http://prism.evolveum.com/xml/ns/public/query-3#path: "name" + expression: + path: | + declare namespace my='http://myself.me/schemas/whatever'; + declare namespace c='http://midpoint.evolveum.com/xml/ns/public/common/common-3'; + $account/c:attributes/my:yyy + condition: + value: + - "true" + reaction: + - situation: "linked" + synchronize: true + - situation: "deleted" + action: + - handlerUri: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount" + - situation: "unlinked" + action: + - ref: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount" + - situation: "unmatched" + action: + - userTemplateRef: + oid: "c0c010c0-d34d-b33f-f00d-777111111111" + ref: "http://midpoint.evolveum.com/xml/ns/public/model/action-3#addUser" \ No newline at end of file diff --git a/infra/schema/src/test/resources/common/yaml/ns/user-jack.yaml b/infra/schema/src/test/resources/common/yaml/ns/user-jack.yaml new file mode 100644 index 00000000000..7a6842884bd --- /dev/null +++ b/infra/schema/src/test/resources/common/yaml/ns/user-jack.yaml @@ -0,0 +1,68 @@ +--- +'@ns' : 'http://midpoint.evolveum.com/xml/ns/public/common/common-3' +object: !http://midpoint.evolveum.com/xml/ns/public/common/common-3/UserType + oid: 2f9b9299-6f45-498f-bc8e-8d17c6b93b20 + name: jack + extension: + "@ns" : "http://www.example.com/foo" + bar : !http://www.w3.org/2001/XMLSchema/string BAR + num : !http://www.w3.org/2001/XMLSchema/int 42 + multi: + - !http://www.w3.org/2001/XMLSchema/string raz + - !http://www.w3.org/2001/XMLSchema/string dva + - !http://www.w3.org/2001/XMLSchema/string tri + password: !http://prism.evolveum.com/xml/ns/public/types-3/ProtectedStringType + "http://prism.evolveum.com/xml/ns/public/types-3#clearValue": "openS3zam3" + link: + - + oid: 2f9b9299-6f45-498f-aaaa-000000001111 + name: jsparrow + resourceRef: { "oid" : "2f9b9299-5555-5555-5555-000000001111" } + objectClass: AccountObjectClass + - + oid: 2f9b9299-6f45-498f-aaaa-000000002222 + name: captain + resource: + oid: 2f9b9299-5555-5555-5555-000000001111 + name: Rum Supply System + connectorRef: { "oid" : "2f9b9299-cccc-cccc-cccc-000000002222" } + connectorConfiguration: { } + namespace: "http://midpoint.evolveum.com/xml/ns/public/resource/instance/2f9b9299-5555-5555-5555-000000002222" + objectClass: AccountObjectClass + linkRef: + oid: 2f9b9299-6f45-498f-aaaa-000000003333 + type: "http://midpoint.evolveum.com/xml/ns/public/common/common-3#ShadowType" + description: This is third accountRef + filter: + "@ns": "http://prism.evolveum.com/xml/ns/public/query-3" + equal: + path: connectorType + value: org.identityconnectors.ldap.LdapConnector + assignment: + id: 111 + extension: + "@ns": "http://midpoint.evolveum.com/xml/ns/test/extension" + intType: 42 + construction: + resourceRef: + oid: 2f9b9299-5555-5555-5555-000000001111 + activation: + administrativeStatus: enabled + fullName: Jack Sparrow + givenName: Jack + familyName: Sparrow + honorificPrefix: Cpt. + emailAddress: + organizationalUnit: [ "Brethren of the Coast", "Davie Jones' Locker" ] + locality: "" + credentials: + password: + value: + "@ns" : "http://prism.evolveum.com/xml/ns/public/types-3" + encryptedData: + encryptionMethod: + algorithm: "http://www.w3.org/2001/04/xmlenc#aes256-cbc" + keyInfo: + keyName: "HF6JRsNMeJt6alihT44CXKgpe0c=" + cipherData: + cipherValue: "blc5OXO2Z4vJW7o/XXhqZzg/rkwsIOwRBK7KLgMqwcrVcYpeZZOjxzgRgFiNw4IB" \ No newline at end of file diff --git a/infra/schema/src/test/resources/deltaconverter/user-modify-add-account.xml b/infra/schema/src/test/resources/deltaconverter/user-modify-add-account.xml index faa6d6fa89b..d139c572384 100644 --- a/infra/schema/src/test/resources/deltaconverter/user-modify-add-account.xml +++ b/infra/schema/src/test/resources/deltaconverter/user-modify-add-account.xml @@ -26,7 +26,7 @@ add c:linkRef - + diff --git a/infra/schema/src/test/resources/diff/resource-after-ns-change.xml b/infra/schema/src/test/resources/diff/resource-after-ns-change.xml index 855a2642eb5..24759056a7a 100644 --- a/infra/schema/src/test/resources/diff/resource-after-ns-change.xml +++ b/infra/schema/src/test/resources/diff/resource-after-ns-change.xml @@ -20,6 +20,7 @@ + type="t:ProtectedStringType" minOccurs="0" maxOccurs="unbounded"> This is fake. It is only for namespace testing and similar wild things. diff --git a/infra/schema/src/test/resources/diff/resource-before.xml b/infra/schema/src/test/resources/diff/resource-before.xml index 7822d99c7d3..ce85b19cb47 100644 --- a/infra/schema/src/test/resources/diff/resource-before.xml +++ b/infra/schema/src/test/resources/diff/resource-before.xml @@ -17,6 +17,7 @@ - + This is fake. It is only for namespace testing and similar wild things. diff --git a/infra/schema/src/test/resources/queryconvertor/filter-account-by-attributes-and-resource-ref-no-ns.xml b/infra/schema/src/test/resources/queryconvertor/filter-account-by-attributes-and-resource-ref-no-ns.xml new file mode 100644 index 00000000000..73fe2ab26bb --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/filter-account-by-attributes-and-resource-ref-no-ns.xml @@ -0,0 +1,32 @@ + + + + + + + resourceRef + + aae7be60-df56-11df-8608-0002a5d5c51b + + + + attributes/name + uid=jbond,ou=People,dc=example,dc=com + + + diff --git a/infra/schema/testng-unit.xml b/infra/schema/testng-unit.xml index 2f7f07eba46..e64be1c26d5 100644 --- a/infra/schema/testng-unit.xml +++ b/infra/schema/testng-unit.xml @@ -16,13 +16,65 @@ --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - @@ -33,9 +85,7 @@ - - @@ -43,7 +93,6 @@ - diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java index 8b1fd897581..0cea31f53cd 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinitionImpl; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.util.JAXBUtil; @@ -139,7 +140,7 @@ public static String getNodeOid(Node node) { public static void setAttribute(PrismObject account, QName attrName, QName typeName, PrismContext prismContext, String value) throws SchemaException { PrismContainer attributesContainer = account.findContainer(ShadowType.F_ATTRIBUTES); - ResourceAttributeDefinition attrDef = new ResourceAttributeDefinition(attrName, typeName, prismContext); + ResourceAttributeDefinition attrDef = new ResourceAttributeDefinitionImpl(attrName, typeName, prismContext); ResourceAttribute attribute = attrDef.instantiate(); attribute.setRealValue(value); attributesContainer.add(attribute); diff --git a/infra/util/pom.xml b/infra/util/pom.xml index c36776a3d49..23bee7e75f6 100644 --- a/infra/util/pom.xml +++ b/infra/util/pom.xml @@ -88,6 +88,10 @@ aopalliance aopalliance + + org.jetbrains + annotations-java5 + org.testng diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/JAXBUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/JAXBUtil.java index 51456882cb3..e08acd8d290 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/JAXBUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/JAXBUtil.java @@ -231,9 +231,6 @@ public static Class findClassForType(QName typeName, Package pkg) { packageNamespaces.put(pkg, namespace); } - if (namespace == null) { - throw new IllegalArgumentException("No namespace annotation in "+pkg); - } if (!namespace.equals(typeName.getNamespaceURI())) { throw new IllegalArgumentException("Looking for type in namespace " + typeName.getNamespaceURI() + ", but the package annotation indicates namespace " + namespace); diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java index e06acf5a1ee..a1376416932 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java @@ -516,4 +516,16 @@ public static void addIfNotPresent(List receivingList, T supplyingElement receivingList.add(supplyingElement); } } + + public static boolean nullableCollectionsEqual(Collection c1, Collection c2) { + boolean empty1 = c1 == null || c1.isEmpty(); + boolean empty2 = c2 == null || c2.isEmpty(); + if (empty1) { + return empty2; + } else if (empty2) { + return false; + } else { + return c1.equals(c2); + } + } } diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java index b025a0428af..f656ccd2832 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java @@ -25,6 +25,8 @@ import com.evolveum.midpoint.util.logging.TraceManager; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; import org.w3c.dom.Node; /** @@ -54,15 +56,24 @@ public class QNameUtil { private static ThreadLocal temporarilyTolerateUndeclaredPrefixes = new ThreadLocal<>(); public static String qNameToUri(QName qname) { + return qNameToUri(qname, true); + } + + public static String qNameToUri(QName qname, boolean unqualifiedStartsWithHash) { + return qNameToUri(qname, unqualifiedStartsWithHash, '#'); + } + + public static String qNameToUri(QName qname, boolean unqualifiedStartsWithHash, char separatorChar) { String qUri = qname.getNamespaceURI(); StringBuilder sb = new StringBuilder(qUri); // TODO: Check if there's already a fragment // e.g. http://foo/bar#baz - if (!qUri.endsWith("#") && !qUri.endsWith("/")) { - sb.append("#"); + if (unqualifiedStartsWithHash || !qUri.isEmpty()) { + sb.append(separatorChar); + } } sb.append(qname.getLocalPart()); @@ -73,28 +84,47 @@ public static QName uriToQName(String uri) { return uriToQName(uri, false); } + public static boolean noNamespace(@NotNull QName name) { + return StringUtils.isEmpty(name.getNamespaceURI()); + } + + public static boolean hasNamespace(@NotNull QName name) { + return !noNamespace(name); + } + + public static class QNameInfo { + @NotNull public final QName name; + public final boolean explicitEmptyNamespace; + public QNameInfo(@NotNull QName name, boolean explicitEmptyNamespace) { + this.name = name; + this.explicitEmptyNamespace = explicitEmptyNamespace; + } + } + public static QName uriToQName(String uri, boolean allowUnqualified) { + return uriToQNameInfo(uri, allowUnqualified).name; + } - if (uri == null) { - throw new IllegalArgumentException("URI is null"); - } + @NotNull + public static QNameInfo uriToQNameInfo(@NotNull String uri, boolean allowUnqualified) { + Validate.notNull(uri); int index = uri.lastIndexOf("#"); if (index != -1) { String ns = uri.substring(0, index); String name = uri.substring(index+1); - return new QName(ns,name); + return new QNameInfo(new QName(ns, name), "".equals(ns)); } index = uri.lastIndexOf("/"); // TODO check if this is still in the path section, e.g. // if the matched slash is not a beginning of authority // section if (index != -1) { - String ns = uri.substring(0, index+1); + String ns = uri.substring(0, index); String name = uri.substring(index+1); - return new QName(ns,name); + return new QNameInfo(new QName(ns, name), "".equals(ns)); } if (allowUnqualified) { - return new QName(uri); + return new QNameInfo(new QName(uri), false); } else { throw new IllegalArgumentException("The URI (" + uri + ") does not contain slash character"); } diff --git a/infra/util/src/test/java/com/evolveum/midpoint/util/QNameUtilTest.java b/infra/util/src/test/java/com/evolveum/midpoint/util/QNameUtilTest.java index faf4601807b..b315c8f5061 100644 --- a/infra/util/src/test/java/com/evolveum/midpoint/util/QNameUtilTest.java +++ b/infra/util/src/test/java/com/evolveum/midpoint/util/QNameUtilTest.java @@ -57,7 +57,7 @@ public void uriToQName2() { // Then - AssertJUnit.assertEquals(new QName("http://foo.com/bar/","baz"), qname); + AssertJUnit.assertEquals(new QName("http://foo.com/bar","baz"), qname); } @Test diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java index d4236ae4b2d..4dcf172e4a4 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java @@ -26,7 +26,7 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.NameItemPathSegment; diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertExpressionHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertExpressionHelper.java index 31b2f92e9de..0754feb321f 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertExpressionHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertExpressionHelper.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; @@ -76,7 +77,7 @@ private List evaluateExpression(Class resultClass, ExpressionType expr QName xsdType = XsdTypeMapper.toXsdType(resultClass); QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, xsdType, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, xsdType, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java index 5274886067a..860abad3e40 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java @@ -101,7 +101,6 @@ public Collection createCasesForObject(Pr private void processAssignment(AssignmentType assignment, boolean isInducement, AccessCertificationAssignmentReviewScopeType scope, AccessCertificationCampaignType campaign, ObjectType object, List caseList, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { AccessCertificationAssignmentCaseType assignmentCase = new AccessCertificationAssignmentCaseType(prismContext); - assignmentCase.asPrismContainerValue().setConcreteType(AccessCertificationAssignmentCaseType.COMPLEX_TYPE); assignmentCase.setAssignment(assignment.clone()); assignmentCase.setIsInducement(isInducement); assignmentCase.setObjectRef(ObjectTypeUtil.createObjectRef(object)); diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/BasicCertificationTest.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/BasicCertificationTest.java index 203194ef161..0bab6a95f97 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/BasicCertificationTest.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/BasicCertificationTest.java @@ -338,10 +338,11 @@ public void test040SearchCasesFilteredSortedPaged() throws Exception { TestUtil.displayWhen(TEST_NAME); Collection> resolveNames = SelectorOptions.createCollection(GetOperationOptions.createResolveNames()); - ObjectFilter filter = RefFilter.createReferenceEqual(new ItemPath(AccessCertificationCaseType.F_OBJECT_REF), - AccessCertificationCaseType.class, prismContext, ObjectTypeUtil.createObjectRef(userAdministrator).asReferenceValue()); - ObjectPaging paging = ObjectPaging.createPaging(2, 2, getOrderBy(F_TARGET_REF), OrderDirection.DESCENDING); - ObjectQuery query = ObjectQuery.createObjectQuery(filter, paging); + ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) + .item(AccessCertificationCaseType.F_OBJECT_REF).ref(userAdministrator.getOid()) + .desc(getOrderBy(F_TARGET_REF)) + .offset(2).maxSize(2) + .build(); List caseList = modelService.searchContainers( AccessCertificationCaseType.class, query, resolveNames, task, result); @@ -727,8 +728,10 @@ public void test205StartRemediationAllow() throws Exception { display("campaign after remediation start", campaign); assertTrue("wrong campaign state: " + campaign.getState(), campaign.getState() == CLOSED || campaign.getState() == IN_REMEDIATION); - RefFilter taskFilter = RefFilter.createReferenceEqual(new ItemPath(TaskType.F_OBJECT_REF), TaskType.class, prismContext, ObjectTypeUtil.createObjectRef(campaign).asReferenceValue()); - List> tasks = taskManager.searchObjects(TaskType.class, ObjectQuery.createObjectQuery(taskFilter), null, result); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_OBJECT_REF).ref(campaign.getOid()) + .build(); + List> tasks = taskManager.searchObjects(TaskType.class, query, null, result); assertEquals("unexpected number of related tasks", 1, tasks.size()); waitForTaskFinish(tasks.get(0).getOid(), true); diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/CriticalRolesCertificationTest.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/CriticalRolesCertificationTest.java index a4e9f62d2d6..a683155ff55 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/CriticalRolesCertificationTest.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/CriticalRolesCertificationTest.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; @@ -943,8 +944,10 @@ public void test900StartRemediation() throws Exception { display("campaign after remediation start", campaign); assertTrue("wrong campaign state: " + campaign.getState(), campaign.getState() == CLOSED || campaign.getState() == IN_REMEDIATION); - RefFilter taskFilter = RefFilter.createReferenceEqual(new ItemPath(TaskType.F_OBJECT_REF), TaskType.class, prismContext, ObjectTypeUtil.createObjectRef(campaign).asReferenceValue()); - List> tasks = taskManager.searchObjects(TaskType.class, ObjectQuery.createObjectQuery(taskFilter), null, result); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_OBJECT_REF).ref(campaign.getOid()) + .build(); + List> tasks = taskManager.searchObjects(TaskType.class, query, null, result); assertEquals("unexpected number of related tasks", 1, tasks.size()); waitForTaskFinish(tasks.get(0).getOid(), true); diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/RoleInducementCertificationTest.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/RoleInducementCertificationTest.java index 6976fe52270..5a8f10ddfe9 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/RoleInducementCertificationTest.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/RoleInducementCertificationTest.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; @@ -794,8 +795,10 @@ public void test300StartRemediation() throws Exception { display("campaign after remediation start", campaign); assertTrue("wrong campaign state: " + campaign.getState(), campaign.getState() == CLOSED || campaign.getState() == IN_REMEDIATION); - RefFilter taskFilter = RefFilter.createReferenceEqual(new ItemPath(TaskType.F_OBJECT_REF), TaskType.class, prismContext, ObjectTypeUtil.createObjectRef(campaign).asReferenceValue()); - List> tasks = taskManager.searchObjects(TaskType.class, ObjectQuery.createObjectQuery(taskFilter), null, result); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_OBJECT_REF).ref(campaign.getOid()) + .build(); + List> tasks = taskManager.searchObjects(TaskType.class, query, null, result); assertEquals("unexpected number of related tasks", 1, tasks.size()); waitForTaskFinish(tasks.get(0).getOid(), true); diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/ExpressionUtil.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/ExpressionUtil.java index df816dc0637..3c75d305cc9 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/ExpressionUtil.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/ExpressionUtil.java @@ -222,7 +222,12 @@ public static Object resolvePath(ItemPath path, ExpressionVariables variables, O } public static Object convertVariableValue(Object originalValue, String variableName, ObjectResolver objectResolver, - String contextDescription, Task task, OperationResult result) throws ExpressionSyntaxException, ObjectNotFoundException { + String contextDescription, PrismContext prismContext, Task task, OperationResult result) throws ExpressionSyntaxException, ObjectNotFoundException { + if (originalValue instanceof PrismValue) { + ((PrismValue) originalValue).setPrismContext(prismContext); // TODO - or revive? Or make sure prismContext is set here? + } else if (originalValue instanceof Item) { + ((Item) originalValue).setPrismContext(prismContext); // TODO - or revive? Or make sure prismContext is set here? + } if (originalValue instanceof ObjectReferenceType) { try { originalValue = resolveReference((ObjectReferenceType)originalValue, objectResolver, variableName, @@ -291,7 +296,7 @@ public static Object convertVariableValue(Object originalValue, String variableN public static Map prepareScriptVariables(ExpressionVariables variables, ObjectResolver objectResolver, Collection functions, - String contextDescription, Task task, OperationResult result) throws ExpressionSyntaxException, ObjectNotFoundException { + String contextDescription, PrismContext prismContext, Task task, OperationResult result) throws ExpressionSyntaxException, ObjectNotFoundException { Map scriptVariables = new HashMap<>(); // Functions if (functions != null) { @@ -307,7 +312,7 @@ public static Map prepareScriptVariables(ExpressionVariables vari continue; } String variableName = variableEntry.getKey().getLocalPart(); - Object variableValue = ExpressionUtil.convertVariableValue(variableEntry.getValue(), variableName, objectResolver, contextDescription, task, result); + Object variableValue = ExpressionUtil.convertVariableValue(variableEntry.getValue(), variableName, objectResolver, contextDescription, prismContext, task, result); scriptVariables.put(variableName, variableValue); } } @@ -530,18 +535,18 @@ private static ObjectFilter evaluateFilterExpressionsInternal(ObjectFilter filte } return evaluatedFilter; - } else if (filter instanceof PropertyValueFilter) { - PropertyValueFilter pvfilter = (PropertyValueFilter) filter; + } else if (filter instanceof ValueFilter) { + ValueFilter valueFilter = (ValueFilter) filter; - if (pvfilter.getValues() != null && !pvfilter.getValues().isEmpty()) { + if (valueFilter.getValues() != null && !valueFilter.getValues().isEmpty()) { // We have value. Nothing to evaluate. - return pvfilter.clone(); + return valueFilter.clone(); } - ExpressionWrapper expressionWrapper = pvfilter.getExpression(); + ExpressionWrapper expressionWrapper = valueFilter.getExpression(); if (expressionWrapper == null || expressionWrapper.getExpression() == null) { LOGGER.warn("No valueExpression in filter in {}. Returning original filter", shortDesc); - return pvfilter.clone(); + return valueFilter.clone(); } if (!(expressionWrapper.getExpression() instanceof ExpressionType)) { throw new SchemaException("Unexpected expression type " @@ -558,13 +563,13 @@ private static ObjectFilter evaluateFilterExpressionsInternal(ObjectFilter filte LOGGER.debug("Result of search filter expression was null or empty. Expression: {}", valueExpression); - return createFilterForNoValue(pvfilter, valueExpression); + return createFilterForNoValue(valueFilter, valueExpression); } // TODO: log more context LOGGER.trace("Search filter expression in the rule for {} evaluated to {}.", new Object[] { shortDesc, expressionResult }); - PropertyValueFilter evaluatedFilter = (PropertyValueFilter) pvfilter.clone(); + ValueFilter evaluatedFilter = valueFilter.clone(); evaluatedFilter.setValue(expressionResult); evaluatedFilter.setExpression(null); // } @@ -635,14 +640,14 @@ private static ObjectFilter createFilterForNoValue(ObjectFilter filter, Expressi return AllFilter.createAll(); case FILTER_EQUAL_NULL: - if (filter instanceof PropertyValueFilter) { - PropertyValueFilter evaluatedFilter = (PropertyValueFilter) filter.clone(); + if (filter instanceof ValueFilter) { + ValueFilter evaluatedFilter = (ValueFilter) filter.clone(); evaluatedFilter.setExpression(null); return evaluatedFilter; } else if (filter instanceof InOidFilter) { return NoneFilter.createNone(); } else { - throw new IllegalArgumentException("Unknow filter to evaluate: " + filter); + throw new IllegalArgumentException("Unknown filter to evaluate: " + filter); } case ERROR: @@ -667,11 +672,11 @@ private static V evaluateExpression(ExpressionVariables v } if (outputDefinition == null) { - outputDefinition = new PrismPropertyDefinition(ExpressionConstants.OUTPUT_ELMENT_NAME, + outputDefinition = new PrismPropertyDefinitionImpl(ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_STRING, prismContext); } - return evaluateExpression(variables, outputDefinition, expressionType, expressionFactory, shortDesc, + return (V) evaluateExpression(variables, outputDefinition, expressionType, expressionFactory, shortDesc, task, parentResult); // String expressionResult = @@ -713,7 +718,7 @@ private static Collection evaluateStringExpression(ExpressionVariables v String shortDesc, Task task, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition( + PrismPropertyDefinitionImpl outputDefinition = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_STRING, prismContext); outputDefinition.setMaxOccurs(-1); Expression, PrismPropertyDefinition> expression = expressionFactory @@ -741,7 +746,7 @@ public static PrismPropertyValue evaluateCondition(ExpressionVariables ExpressionType expressionType, ExpressionFactory expressionFactory, String shortDesc, Task task, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { - ItemDefinition outputDefinition = new PrismPropertyDefinition( + ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, expressionFactory.getPrismContext()); return (PrismPropertyValue) evaluateExpression(variables, outputDefinition, expressionType, diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java index d339726c015..0e3fc6867a7 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java @@ -209,7 +209,7 @@ private Bindings convertToBindings(ExpressionVariables variables, ObjectResolver Collection functions, String contextDescription, Task task, OperationResult result) throws ExpressionSyntaxException, ObjectNotFoundException { Bindings bindings = scriptEngine.createBindings(); - bindings.putAll(ExpressionUtil.prepareScriptVariables(variables, objectResolver, functions, contextDescription, task, result)); + bindings.putAll(ExpressionUtil.prepareScriptVariables(variables, objectResolver, functions, contextDescription, prismContext, task, result)); return bindings; } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/velocity/VelocityScriptEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/velocity/VelocityScriptEvaluator.java index 82c8ff0cf08..e1849759f3a 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/velocity/VelocityScriptEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/velocity/VelocityScriptEvaluator.java @@ -125,7 +125,8 @@ private VelocityContext createVelocityContext(ExpressionVariables variables, Obj Collection functions, String contextDescription, Task task, OperationResult result) throws ExpressionSyntaxException, ObjectNotFoundException { VelocityContext context = new VelocityContext(); - Map scriptVariables = ExpressionUtil.prepareScriptVariables(variables, objectResolver, functions, contextDescription, task, result); + Map scriptVariables = ExpressionUtil.prepareScriptVariables(variables, objectResolver, functions, contextDescription, + prismContext, task, result); for (Map.Entry scriptVariable : scriptVariables.entrySet()) { context.put(scriptVariable.getKey(), scriptVariable.getValue()); } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/LazyXPathVariableResolver.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/LazyXPathVariableResolver.java index 1376d22e79d..e748f080bdb 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/LazyXPathVariableResolver.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/LazyXPathVariableResolver.java @@ -22,7 +22,7 @@ import javax.xml.namespace.QName; import javax.xml.xpath.XPathVariableResolver; -import com.evolveum.midpoint.prism.parser.DomParser; +import com.evolveum.midpoint.prism.lex.dom.DomLexicalProcessor; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -139,14 +139,13 @@ public static Object convertToXml(Object variableValue, QName variableName, fina if (variableValue instanceof PrismObject) { PrismObject prismObject = (PrismObject)variableValue; - variableValue = prismObject.getPrismContext().serializeToDom(prismObject); + variableValue = prismObject.getPrismContext().domSerializer().serialize(prismObject); } else if (variableValue instanceof PrismProperty) { PrismProperty prismProperty = (PrismProperty)variableValue; - DomParser domProcessor = prismProperty.getPrismContext().getParserDom(); final List elementList = new ArrayList(); for (PrismPropertyValue value: prismProperty.getValues()) { - Element valueElement = prismContext.serializeValueToDom(value, prismProperty.getElementName()); + Element valueElement = prismContext.domSerializer().serialize(value, prismProperty.getElementName()); elementList.add(valueElement); } NodeList nodeList = new NodeList() { @@ -163,7 +162,6 @@ public int getLength() { } else if (variableValue instanceof PrismValue) { PrismValue pval = (PrismValue)variableValue; - DomParser domProcessor = prismContext.getParserDom(); if (pval.getParent() == null) { // Set a fake parent to allow serialization pval.setParent(new Itemable() { @@ -188,7 +186,7 @@ public ItemDefinition getDefinition() { } }); } - variableValue = prismContext.serializeValueToDom(pval, variableName); + variableValue = prismContext.domSerializer().serialize(pval, variableName); } if (!((variableValue instanceof Node)||variableValue instanceof NodeList) diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java index 9fde2f06f56..a4e55f1f3e7 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/xpath/XPathExpressionCodeHolder.java @@ -17,7 +17,7 @@ import java.util.Map; -import com.evolveum.midpoint.prism.parser.TrivialXPathParser; +import com.evolveum.midpoint.prism.marshaller.TrivialXPathParser; /** * @author Radovan Semancik diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java index fc5fd312158..8bddd256755 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/Mapping.java @@ -438,7 +438,7 @@ private boolean isInRange(V value, Task task, OperationResult result) throws Exp } variables.addVariableDefinition(ExpressionConstants.VAR_VALUE, value); - PrismPropertyDefinition outputDef = new PrismPropertyDefinition<>(SchemaConstantsGenerated.C_VALUE, DOMUtil.XSD_BOOLEAN, getPrismContext(), null, false); + PrismPropertyDefinition outputDef = new PrismPropertyDefinitionImpl(SchemaConstantsGenerated.C_VALUE, DOMUtil.XSD_BOOLEAN, getPrismContext(), null, false); PrismPropertyValue rv = ExpressionUtil.evaluateExpression(variables, outputDef, range.getIsInSetExpression(), expressionFactory, "isInSet expression in " + contextDescription, task, result); // but now remove the parent! @@ -866,7 +866,7 @@ private void evaluateCondition(Task task, OperationResult result) throws SchemaE conditionOutputTriple.addToZeroSet(new PrismPropertyValue(Boolean.TRUE)); return; } - PrismPropertyDefinition conditionOutput = new PrismPropertyDefinition<>(CONDITION_OUTPUT_NAME, DOMUtil.XSD_BOOLEAN, expressionFactory.getPrismContext()); + PrismPropertyDefinition conditionOutput = new PrismPropertyDefinitionImpl(CONDITION_OUTPUT_NAME, DOMUtil.XSD_BOOLEAN, expressionFactory.getPrismContext()); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(conditionExpressionType, conditionOutput, "condition in "+getMappingContextDescription(), task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(sources, variables, diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java index bb53e51952c..6e97e037263 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java @@ -21,14 +21,11 @@ import java.io.File; import java.io.IOException; +import com.evolveum.midpoint.prism.*; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; import org.xml.sax.SAXException; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.crypto.AESProtector; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.prism.util.PrismTestUtil; @@ -90,7 +87,7 @@ public void testIterationCondition() throws Exception { ExpressionType expressionType = PrismTestUtil.parseAtomicValue( EXPRESSION_ITERATION_CONDITION_FILE, ExpressionType.COMPLEX_TYPE); - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition(ExpressionConstants.OUTPUT_ELMENT_NAME, + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl(ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, outputDefinition , TEST_NAME, null, result); diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java index 3295f33984d..f1fbdf70248 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpressionUtil.java @@ -35,7 +35,7 @@ import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.parser.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismTestUtil; diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/AbstractScriptTest.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/AbstractScriptTest.java index 238194b7a6b..13cc13c29fa 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/AbstractScriptTest.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/AbstractScriptTest.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.model.common.expression.ExpressionUtil; import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.common.expression.functions.FunctionLibrary; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; @@ -265,9 +266,9 @@ private List> evaluateExpression(ScriptExpressionEvalu private List> evaluateExpression(ScriptExpressionEvaluatorType scriptType, QName typeName, boolean scalar, ExpressionVariables variables, String shortDesc, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - ItemDefinition outputDefinition = new PrismPropertyDefinition(PROPERTY_NAME, typeName, PrismTestUtil.getPrismContext()); + ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl(PROPERTY_NAME, typeName, PrismTestUtil.getPrismContext()); if (!scalar) { - outputDefinition.setMaxOccurs(-1); + ((ItemDefinitionImpl) outputDefinition).setMaxOccurs(-1); } return evaluateExpression(scriptType, outputDefinition, variables, shortDesc, result); } diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java index f07f0c19347..48f9ca9ecdb 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/script/TestScriptCaching.java @@ -19,10 +19,7 @@ import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.common.expression.functions.FunctionLibrary; import com.evolveum.midpoint.model.common.expression.script.jsr223.Jsr223ScriptEvaluator; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.crypto.AESProtector; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.util.PrismTestUtil; @@ -138,7 +135,7 @@ private long executeScript(String filname, String expectedResult, String desc) t // GIVEN OperationResult result = new OperationResult(desc); ScriptExpressionEvaluatorType scriptType = parseScriptType(filname); - ItemDefinition outputDefinition = new PrismPropertyDefinition(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext()); + ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext()); ScriptExpression scriptExpression = scriptExpressionfactory.createScriptExpression(scriptType, outputDefinition, desc); diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/TestMappingTime.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/TestMappingTime.java index 34d3921e99d..b0fc0a47c32 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/TestMappingTime.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/TestMappingTime.java @@ -22,6 +22,7 @@ import javax.xml.datatype.XMLGregorianCalendar; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.xml.sax.SAXException; @@ -162,7 +163,7 @@ public void testExistenceBefore() throws Exception { builder.setNow(TIME_PAST); - PrismPropertyDefinition existenceDef = new PrismPropertyDefinition( + PrismPropertyDefinition existenceDef = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext()); builder.setDefaultTargetDefinition(existenceDef); @@ -193,7 +194,7 @@ public void testExistenceAfter() throws Exception { builder.setNow(TIME_FUTURE); - PrismPropertyDefinition existenceDef = new PrismPropertyDefinition( + PrismPropertyDefinition existenceDef = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext()); builder.setDefaultTargetDefinition(existenceDef); @@ -230,7 +231,7 @@ public void testNoReferenceTime() throws Exception { builder.setNow(TIME_PAST); - PrismPropertyDefinition existenceDef = new PrismPropertyDefinition( + PrismPropertyDefinition existenceDef = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext()); builder.setDefaultTargetDefinition(existenceDef); @@ -270,7 +271,7 @@ public void testSetReferenceTimeBefore() throws Exception { builder.setNow(TIME_PAST); - PrismPropertyDefinition existenceDef = new PrismPropertyDefinition( + PrismPropertyDefinition existenceDef = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext()); builder.setDefaultTargetDefinition(existenceDef); @@ -309,7 +310,7 @@ public void testSetReferenceTimeAfter() throws Exception { builder.setNow(TIME_FUTURE); - PrismPropertyDefinition existenceDef = new PrismPropertyDefinition( + PrismPropertyDefinition existenceDef = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext()); builder.setDefaultTargetDefinition(existenceDef); diff --git a/model/model-common/src/test/resources/mapping/account-inbound-mapping.xml b/model/model-common/src/test/resources/mapping/account-inbound-mapping.xml index 04865366b56..5db0633589c 100644 --- a/model/model-common/src/test/resources/mapping/account-inbound-mapping.xml +++ b/model/model-common/src/test/resources/mapping/account-inbound-mapping.xml @@ -28,6 +28,6 @@ ri:AccountObjectClass CN=Pavol Rufus/O=SEPSAS/C=SK - pavolr + pavolr diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java index 8cf634aaaf2..de84e8ddabe 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java @@ -719,7 +719,7 @@ private ItemListType prepareXmlData(List output) throws JAXBException, Sch ItemListType itemListType = new ItemListType(); if (output != null) { for (Item item : output) { - RawType rawType = prismContext.toRawType(item); + RawType rawType = new RawType(prismContext.xnodeSerializer().serialize(item), prismContext); itemListType.getItem().add(rawType); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebService.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebService.java index a56050637c1..8618970f3fd 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebService.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebService.java @@ -234,7 +234,7 @@ private List> parseScripts(ExecuteScriptsType parameters) throws // here comes MSL script decoding (however with a quick hack to allow passing XML as text here) String scriptsAsString = parameters.getMslScripts(); if (scriptsAsString.startsWith("> scripts } else { // temporarily we send serialized XML in the case of MSL output ItemListType jaxbOutput = prepareXmlData(executionResult.getDataOutput()); - output.setMslData(prismContext.serializeAnyData(jaxbOutput, SchemaConstants.C_VALUE, PrismContext.LANG_XML)); + output.setMslData(prismContext.xmlSerializer().serializeAnyData(jaxbOutput, SchemaConstants.C_VALUE)); } } result.computeStatusIfUnknown(); @@ -285,7 +285,7 @@ private ItemListType prepareXmlData(List output) throws JAXBException, Sch ItemListType itemListType = new ItemListType(); if (output != null) { for (Item item : output) { - RawType rawType = prismContext.toRawType(item); + RawType rawType = new RawType(prismContext.xnodeSerializer().serialize(item), prismContext); itemListType.getItem().add(rawType); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java index cad3341ece3..051400c267a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelWebServiceRaw.java @@ -17,10 +17,8 @@ import com.evolveum.midpoint.model.api.ModelPort; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.xnode.RootXNode; -import com.evolveum.midpoint.prism.xnode.XNode; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -130,7 +128,7 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { Object requestObject; try { - requestObject = prismContext.parseAnyValue(rootElement); + requestObject = prismContext.parserFor(rootElement).parseRealValue(); } catch (SchemaException e) { throw ws.createIllegalArgumentFault("Couldn't parse SOAP request body because of schema exception: " + e.getMessage()); } @@ -145,7 +143,7 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { GetObjectResponseType gr = new GetObjectResponseType(); gr.setObject(objectTypeHolder.value); gr.setResult(operationResultTypeHolder.value); - response = prismContext.serializeAnyDataToElement(gr, ModelPort.GET_OBJECT_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(gr, ModelPort.GET_OBJECT_RESPONSE); } else if (requestObject instanceof SearchObjectsType) { SearchObjectsType s = (SearchObjectsType) requestObject; Holder objectListTypeHolder = new Holder<>(); @@ -153,13 +151,13 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { SearchObjectsResponseType sr = new SearchObjectsResponseType(); sr.setObjectList(objectListTypeHolder.value); sr.setResult(operationResultTypeHolder.value); - response = prismContext.serializeAnyDataToElement(sr, ModelPort.SEARCH_OBJECTS_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(sr, ModelPort.SEARCH_OBJECTS_RESPONSE); } else if (requestObject instanceof ExecuteChangesType) { ExecuteChangesType e = (ExecuteChangesType) requestObject; ObjectDeltaOperationListType objectDeltaOperationListType = ws.executeChanges(e.getDeltaList(), e.getOptions()); ExecuteChangesResponseType er = new ExecuteChangesResponseType(); er.setDeltaOperationList(objectDeltaOperationListType); - response = prismContext.serializeAnyDataToElement(er, ModelPort.EXECUTE_CHANGES_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(er, ModelPort.EXECUTE_CHANGES_RESPONSE); } else if (requestObject instanceof FindShadowOwnerType) { FindShadowOwnerType f = (FindShadowOwnerType) requestObject; Holder userTypeHolder = new Holder<>(); @@ -167,29 +165,29 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { FindShadowOwnerResponseType fsr = new FindShadowOwnerResponseType(); fsr.setUser(userTypeHolder.value); fsr.setResult(operationResultTypeHolder.value); - response = prismContext.serializeAnyDataToElement(fsr, ModelPort.FIND_SHADOW_OWNER_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(fsr, ModelPort.FIND_SHADOW_OWNER_RESPONSE); } else if (requestObject instanceof TestResourceType) { TestResourceType tr = (TestResourceType) requestObject; OperationResultType operationResultType = ws.testResource(tr.getResourceOid()); TestResourceResponseType trr = new TestResourceResponseType(); trr.setResult(operationResultType); - response = prismContext.serializeAnyDataToElement(trr, ModelPort.TEST_RESOURCE_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(trr, ModelPort.TEST_RESOURCE_RESPONSE); } else if (requestObject instanceof ExecuteScriptsType) { ExecuteScriptsType es = (ExecuteScriptsType) requestObject; ExecuteScriptsResponseType esr = ws.executeScripts(es); - response = prismContext.serializeAnyDataToElement(esr, ModelPort.EXECUTE_SCRIPTS_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(esr, ModelPort.EXECUTE_SCRIPTS_RESPONSE); } else if (requestObject instanceof ImportFromResourceType) { ImportFromResourceType ifr = (ImportFromResourceType) requestObject; TaskType taskType = ws.importFromResource(ifr.getResourceOid(), ifr.getObjectClass()); ImportFromResourceResponseType ifrr = new ImportFromResourceResponseType(); ifrr.setTask(taskType); - response = prismContext.serializeAnyDataToElement(ifrr, ModelPort.IMPORT_FROM_RESOURCE_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(ifrr, ModelPort.IMPORT_FROM_RESOURCE_RESPONSE); } else if (requestObject instanceof NotifyChangeType) { NotifyChangeType nc = (NotifyChangeType) requestObject; TaskType taskType = ws.notifyChange(nc.getChangeDescription()); NotifyChangeResponseType ncr = new NotifyChangeResponseType(); ncr.setTask(taskType); - response = prismContext.serializeAnyDataToElement(ncr, ModelPort.NOTIFY_CHANGE_RESPONSE); + response = prismContext.domSerializer().serializeAnyData(ncr, ModelPort.NOTIFY_CHANGE_RESPONSE); } else { throw ws.createIllegalArgumentFault("Unsupported request type: " + requestObject); } @@ -208,39 +206,9 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { } private void serializeFaultMessage(Detail detail, FaultMessage faultMessage) { - try { - XNode faultMessageXnode = prismContext.getBeanConverter().marshall(faultMessage.getFaultInfo()); - RootXNode xroot = new RootXNode(SchemaConstants.FAULT_MESSAGE_ELEMENT_NAME, faultMessageXnode); - xroot.setExplicitTypeDeclaration(true); - QName faultType = prismContext.getBeanConverter().determineTypeForClass(faultMessage.getFaultInfo().getClass()); - xroot.setTypeQName(faultType); - prismContext.getParserDom().serializeUnderElement(xroot, SchemaConstants.FAULT_MESSAGE_ELEMENT_NAME, detail); - } catch (SchemaException e) { - LOGGER.error("Error serializing fault message (SOAP fault detail): {}", e.getMessage(), e); - } + MiscSchemaUtil.serializeFaultMessage(detail, faultMessage, prismContext, LOGGER); } -// private DOMSource serializeFaultMessage(FaultMessage faultMessage) { -// Element faultElement = DOMUtil.createElement(SOAP11_FAULT); -// Element faultCodeElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULTCODE); -// faultCodeElement.setTextContent(SOAP11_FAULTCODE_SERVER); // todo here is a constant until we have a mechanism to determine the correct value (client / server) -// Element faultStringElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULTSTRING); -// faultStringElement.setTextContent(faultMessage.getMessage()); -// Element faultActorElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULTACTOR); -// faultActorElement.setTextContent("TODO"); // todo -// Element faultDetailElement = DOMUtil.createSubElement(faultElement, SOAP11_FAULT_DETAIL); -// faultDetailElement.setTextContent(getStackTraceAsString(faultMessage)); -// return new DOMSource(faultElement.getOwnerDocument()); -// } - - private String getStackTraceAsString(FaultMessage faultMessage) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - faultMessage.printStackTrace(pw); - pw.close(); - return sw.toString(); - } - private void throwFault(Exception ex, OperationResultType resultType) throws FaultMessage { if (resultType != null) { ws.throwFault(ex, OperationResult.createOperationResult(resultType)); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java index 6cf2c4588cb..8ea4f612dd8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelDiagController.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration; import com.evolveum.midpoint.model.impl.dataModel.DataModelVisualizer; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.security.api.SecurityEnforcer; @@ -267,10 +268,9 @@ private void repositorySelfTestUser(Task task, OperationResult testResult) { OperationResult subresult = result.createSubresult(result.getOperation()+".searchObjects.fullName"); try { - ObjectQuery query = new ObjectQuery(); - ObjectFilter filter = EqualFilter.createEqual(UserType.F_FULL_NAME, UserType.class, prismContext, null, - toPolyString(USER_FULL_NAME)); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME).eq(toPolyString(USER_FULL_NAME)) + .build(); subresult.addParam("query", query); List> foundObjects = repositoryService.searchObjects(UserType.class, query , null, subresult); if (LOGGER.isTraceEnabled()) { @@ -292,11 +292,9 @@ private void repositorySelfTestUser(Task task, OperationResult testResult) { { OperationResult subresult = result.createSubresult(result.getOperation()+".searchObjects.employeeType"); try { - - ObjectQuery query = new ObjectQuery(); - ObjectFilter filter = EqualFilter.createEqual(UserType.F_EMPLOYEE_TYPE, UserType.class, prismContext, null, - USER_EMPLOYEE_TYPE[0]); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_EMPLOYEE_TYPE).eq(USER_EMPLOYEE_TYPE[0]) + .build(); subresult.addParam("query", query); List> foundObjects = repositoryService.searchObjects(UserType.class, query , null, subresult); if (LOGGER.isTraceEnabled()) { @@ -318,11 +316,9 @@ private void repositorySelfTestUser(Task task, OperationResult testResult) { { OperationResult subresult = result.createSubresult(result.getOperation()+".searchObjects.organization"); try { - - ObjectQuery query = new ObjectQuery(); - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, null, - toPolyString(USER_ORGANIZATION[1])); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ORGANIZATION).eq(toPolyString(USER_ORGANIZATION[1])) + .build(); subresult.addParam("query", query); List> foundObjects = repositoryService.searchObjects(UserType.class, query, null, subresult); if (LOGGER.isTraceEnabled()) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java index edb812485a4..949a17879df 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java @@ -19,10 +19,12 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.model.api.*; import com.evolveum.midpoint.model.api.visualizer.Scene; import com.evolveum.midpoint.model.common.SystemObjectCache; import com.evolveum.midpoint.model.impl.visualizer.Visualizer; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; import org.jetbrains.annotations.NotNull; @@ -30,24 +32,12 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.LayerRefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.LayerRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.api.util.MergeDeltas; import com.evolveum.midpoint.model.impl.ModelObjectResolver; import com.evolveum.midpoint.model.impl.lens.ContextFactory; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.projector.Projector; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -277,7 +267,7 @@ public PrismObjectDefinition getEditObjectDefinition(P } RefinedObjectClassDefinition refinedObjectClassDefinition = getEditObjectClassDefinition(shadow, resource, phase); if (refinedObjectClassDefinition != null) { - objectDefinition.getComplexTypeDefinition().replaceDefinition(ShadowType.F_ATTRIBUTES, + ((ComplexTypeDefinitionImpl) objectDefinition.getComplexTypeDefinition()).replaceDefinition(ShadowType.F_ATTRIBUTES, refinedObjectClassDefinition.toResourceAttributeContainerDefinition()); } } @@ -293,7 +283,7 @@ public PrismObjectDefinition getEditShadowDefinition(ResourceShadowD // Make a dummy shadow instance here and evaluate the schema for that. It is not 100% correct. But good enough for now. // TODO: refactor when we add better support for multi-tenancy - PrismObject shadow = prismContext.getSchemaRegistry().instantiate(ShadowType.class); + PrismObject shadow = prismContext.createObject(ShadowType.class); ShadowType shadowType = shadow.asObjectable(); ObjectReferenceType resourceRef = new ObjectReferenceType(); if (discr != null) { @@ -312,7 +302,7 @@ public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject eqFilt } return null; } - + @Override public AuthenticationsPolicyType getAuthenticationPolicy(PrismObject user, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { // TODO: check for user membership in an organization (later versions) - + OperationResult result = parentResult.createMinorSubresult(GET_AUTHENTICATIONS_POLICY); return resolvePolicyTypeFromSecurityPolicy(AuthenticationsPolicyType.class, SecurityPolicyType.F_AUTHENTICATION, user, task, result); - + } - + @Override public RegistrationsPolicyType getRegistrationPolicy(PrismObject user, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { // TODO: check for user membership in an organization (later versions) - + OperationResult result = parentResult.createMinorSubresult(GET_REGISTRATIONS_POLICY); return resolvePolicyTypeFromSecurityPolicy(RegistrationsPolicyType.class, SecurityPolicyType.F_REGISTRATION, user, task, result); } @@ -621,12 +611,12 @@ public CredentialsPolicyType getCredentialsPolicy(PrismObject user, Ta OperationResult result = parentResult.createMinorSubresult(GET_CREDENTIALS_POLICY); return resolvePolicyTypeFromSecurityPolicy(CredentialsPolicyType.class, SecurityPolicyType.F_CREDENTIALS, user, task, result); - + } - + private C resolvePolicyTypeFromSecurityPolicy(Class type, QName path, PrismObject user, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { - + SecurityPolicyType securityPolicyType = getSecurityPolicy(user, task, parentResult); if (securityPolicyType == null) { return null; @@ -635,8 +625,8 @@ private C resolvePolicyTypeFromSecurityPolicy(Class containerValue = container.getValue(); parentResult.recordSuccess(); return containerValue.asContainerable(); - - + + } @Override @@ -651,13 +641,13 @@ public SecurityPolicyType getSecurityPolicy(PrismObject user, Task tas ObjectReferenceType secPolicyRef = systemConfiguration.asObjectable().getGlobalSecurityPolicyRef(); if (secPolicyRef == null) { result.recordNotApplicableIfUnknown(); - return null; + return null; } - + SecurityPolicyType securityPolicyType = objectResolver.resolve(secPolicyRef, SecurityPolicyType.class, null, "security policy referred from system configuration", task, result); if (securityPolicyType == null) { result.recordNotApplicableIfUnknown(); - return null; + return null; } return securityPolicyType; }catch (ObjectNotFoundException | SchemaException e) { @@ -761,7 +751,7 @@ public MergeDeltas mergeObjectsPreviewDeltas(Class result.computeStatus(); return mergeDeltas; - } catch (ObjectNotFoundException | SchemaException | ConfigurationException | ExpressionEvaluationException | + } catch (ObjectNotFoundException | SchemaException | ConfigurationException | ExpressionEvaluationException | CommunicationException | SecurityViolationException | RuntimeException | Error e) { result.recordFatalError(e); throw e; @@ -777,7 +767,7 @@ public PrismObject mergeObjectsPreviewObject(Class try { MergeDeltas mergeDeltas = objectMerger.computeMergeDeltas(type, leftOid, rightOid, mergeConfigurationName, task, result); - + if (LOGGER.isTraceEnabled()) { LOGGER.trace("Merge preview {} + {} deltas:\n{}", leftOid, rightOid, mergeDeltas.debugDump(1)); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java index b8461b93cf3..eede8c3d4ba 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.List; +import com.evolveum.midpoint.model.api.ModelService; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -113,7 +114,7 @@ public class ObjectMerger { // But cannot fix it right now. TODO: later refactor. // MID-3459 @Autowired(required = true) - private ModelController modelController; + private ModelService modelController; public Collection> mergeObjects(Class type, String leftOid, String rightOid, String mergeConfigurationName, Task task, OperationResult result) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java index 004107af559..76ee4bbc438 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java @@ -17,8 +17,7 @@ import java.util.*; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.internals.InternalsConfig; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -30,16 +29,7 @@ import com.evolveum.midpoint.common.crypto.CryptoUtil; import com.evolveum.midpoint.model.api.ModelAuthorizationAction; import com.evolveum.midpoint.model.common.SystemObjectCache; -import com.evolveum.midpoint.prism.ConsistencyCheckScope; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -259,7 +249,7 @@ public void applySecurityConstraints(List> items, ObjectSecurityConstr AuthorizationDecisionType defaultReadDecision, AuthorizationDecisionType defaultAddDecision, AuthorizationDecisionType defaultModifyDecision, AuthorizationPhaseType phase) { LOGGER.trace("applySecurityConstraints(items): items={}, phase={}, defaults R={}, A={}, M={}", - new Object[]{items, phase, defaultReadDecision, defaultAddDecision, defaultModifyDecision}); + items, phase, defaultReadDecision, defaultAddDecision, defaultModifyDecision); if (items == null) { return; } @@ -271,17 +261,17 @@ public void applySecurityConstraints(List> items, ObjectSecurityConstr AuthorizationDecisionType itemAddDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.ADD.getUrl(), defaultReadDecision, phase); AuthorizationDecisionType itemModifyDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultReadDecision, phase); LOGGER.trace("applySecurityConstraints(item): {}: decisions R={}, A={}, M={}", - new Object[]{itemPath, itemReadDecision, itemAddDecision, itemModifyDecision}); + itemPath, itemReadDecision, itemAddDecision, itemModifyDecision); ItemDefinition itemDef = item.getDefinition(); if (itemDef != null) { if (itemReadDecision != AuthorizationDecisionType.ALLOW) { - itemDef.setCanRead(false); + ((ItemDefinitionImpl) itemDef).setCanRead(false); } if (itemAddDecision != AuthorizationDecisionType.ALLOW) { - itemDef.setCanAdd(false); + ((ItemDefinitionImpl) itemDef).setCanAdd(false); } if (itemModifyDecision != AuthorizationDecisionType.ALLOW) { - itemDef.setCanModify(false); + ((ItemDefinitionImpl) itemDef).setCanModify(false); } } if (item instanceof PrismContainer) { @@ -351,13 +341,13 @@ private void applySecurityConstraintsItemDef(D itemDe LOGGER.trace("applySecurityConstraints(itemDef): {}: decisions R={}, A={}, M={}", new Object[]{itemPath, readDecision, addDecision, modifyDecision}); if (readDecision != AuthorizationDecisionType.ALLOW) { - itemDefinition.setCanRead(false); + ((ItemDefinitionImpl) itemDefinition).setCanRead(false); } if (addDecision != AuthorizationDecisionType.ALLOW) { - itemDefinition.setCanAdd(false); + ((ItemDefinitionImpl) itemDefinition).setCanAdd(false); } if (modifyDecision != AuthorizationDecisionType.ALLOW) { - itemDefinition.setCanModify(false); + ((ItemDefinitionImpl) itemDefinition).setCanModify(false); } if (itemDefinition instanceof PrismContainerDefinition) { @@ -486,17 +476,17 @@ private void applyObjectTempla String displayName = templateItemDefType.getDisplayName(); if (displayName != null) { - itemDef.setDisplayName(displayName); + ((ItemDefinitionImpl) itemDef).setDisplayName(displayName); } Integer displayOrder = templateItemDefType.getDisplayOrder(); if (displayOrder != null) { - itemDef.setDisplayOrder(displayOrder); + ((ItemDefinitionImpl) itemDef).setDisplayOrder(displayOrder); } Boolean emphasized = templateItemDefType.isEmphasized(); if (emphasized != null) { - itemDef.setEmphasized(emphasized); + ((ItemDefinitionImpl) itemDef).setEmphasized(emphasized); } List limitations = templateItemDefType.getLimitations(); @@ -504,24 +494,24 @@ private void applyObjectTempla PropertyLimitationsType limitationsType = MiscSchemaUtil.getLimitationsType(limitations, LayerType.PRESENTATION); if (limitationsType != null) { if (limitationsType.getMinOccurs() != null) { - itemDef.setMinOccurs(XsdTypeMapper.multiplicityToInteger(limitationsType.getMinOccurs())); + ((ItemDefinitionImpl) itemDef).setMinOccurs(XsdTypeMapper.multiplicityToInteger(limitationsType.getMinOccurs())); } if (limitationsType.getMaxOccurs() != null) { - itemDef.setMaxOccurs(XsdTypeMapper.multiplicityToInteger(limitationsType.getMaxOccurs())); + ((ItemDefinitionImpl) itemDef).setMaxOccurs(XsdTypeMapper.multiplicityToInteger(limitationsType.getMaxOccurs())); } if (limitationsType.isIgnore() != null) { - itemDef.setIgnored(limitationsType.isIgnore()); + ((ItemDefinitionImpl) itemDef).setIgnored(limitationsType.isIgnore()); } PropertyAccessType accessType = limitationsType.getAccess(); if (accessType != null) { if (accessType.isAdd() != null) { - itemDef.setCanAdd(accessType.isAdd()); + ((ItemDefinitionImpl) itemDef).setCanAdd(accessType.isAdd()); } if (accessType.isModify() != null) { - itemDef.setCanModify(accessType.isModify()); + ((ItemDefinitionImpl) itemDef).setCanModify(accessType.isModify()); } if (accessType.isRead() != null) { - itemDef.setCanRead(accessType.isRead()); + ((ItemDefinitionImpl) itemDef).setCanRead(accessType.isRead()); } } } @@ -530,7 +520,7 @@ private void applyObjectTempla ObjectReferenceType valueEnumerationRef = templateItemDefType.getValueEnumerationRef(); if (valueEnumerationRef != null) { PrismReferenceValue valueEnumerationRVal = MiscSchemaUtil.objectReferenceTypeToReferenceValue(valueEnumerationRef); - itemDef.setValueEnumerationRef(valueEnumerationRVal); + ((ItemDefinitionImpl) itemDef).setValueEnumerationRef(valueEnumerationRVal); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/DataModelVisualizerImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/DataModelVisualizerImpl.java index d74674ad7b3..19e7ce5f344 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/DataModelVisualizerImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/DataModelVisualizerImpl.java @@ -1,9 +1,6 @@ package com.evolveum.midpoint.model.impl.dataModel; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; @@ -93,7 +90,7 @@ public String visualize(ResourceType resource, Task task, OperationResult result private void processResourceMappings(VisualizationContext ctx, List> resources) throws SchemaException { for (PrismObject resource : resources) { LOGGER.debug("Processing {}", ObjectTypeUtil.toShortString(resource)); - RefinedResourceSchema refinedResourceSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedResourceSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (refinedResourceSchema == null) { LOGGER.debug("Refined resource schema is null, skipping the resource."); continue; @@ -115,7 +112,7 @@ private void processResourceMappings(VisualizationContext ctx, List associationDefinitions = refinedDefinition.getAssociations(); + Collection associationDefinitions = refinedDefinition.getAssociationDefinitions(); for (RefinedAssociationDefinition associationDefinition : associationDefinitions) { if (associationDefinition.isIgnored()) { continue; @@ -177,12 +174,12 @@ private void processBidirectionalMapping(VisualizationContext ctx, String oid, S private void createDataItems(VisualizationContext ctx, List> resources) throws SchemaException { LOGGER.debug("createDataItems starting"); for (PrismObject resource : resources) { - final ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + final ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); if (resourceSchema == null) { LOGGER.debug("Resource schema is null, skipping the resource."); continue; } - RefinedResourceSchema refinedResourceSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedResourceSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (refinedResourceSchema == null) { LOGGER.debug("Refined resource schema is null, skipping the resource."); // actually shouldn't be null if resource schema exists continue; @@ -210,7 +207,7 @@ private void createDataItems(VisualizationContext ctx, List associationDefinitions = refinedDefinition.getAssociations(); + Collection associationDefinitions = refinedDefinition.getAssociationDefinitions(); for (RefinedAssociationDefinition associationDefinition : associationDefinitions) { if (associationDefinition.isIgnored()) { continue; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/VisualizationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/VisualizationContext.java index 75e7d5ab815..fcbfcbc0890 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/VisualizationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/dataModel/VisualizationContext.java @@ -3,6 +3,7 @@ import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.path.ItemPath; @@ -67,7 +68,7 @@ public RefinedResourceSchema getRefinedResourceSchema(String resourceOid) { return null; } try { - return RefinedResourceSchema.getRefinedSchema(resource, prismContext); + return RefinedResourceSchemaImpl.getRefinedSchema(resource, prismContext); } catch (SchemaException e) { throw new SystemException("Unexpected exception: " + e.getMessage(), e); } @@ -164,7 +165,7 @@ public String exportDot() { ResourceDataItem item = findResourceItem(resource.getOid(), def.getKind(), def.getIntent(), new ItemPath(attrDef.getName())); previousNodeName = addResourceItem(itemsShown, indent, sb1, previousNodeName, item); } - for (RefinedAssociationDefinition assocDef : def.getAssociations()) { + for (RefinedAssociationDefinition assocDef : def.getAssociationDefinitions()) { if (assocDef.isIgnored()) { continue; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java index dbe0d572111..2b1fff7e9f7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.model.impl.ModelObjectResolver; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -75,7 +76,7 @@ public String evaluateExpression(ShadowType shadow, ExpressionType expressionTyp ExpressionVariables variables = getDefaultXPathVariables(null, shadow, resource); - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition<>(ExpressionConstants.OUTPUT_ELMENT_NAME, + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_STRING, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, outputDefinition, shortDesc, task, result); @@ -107,7 +108,7 @@ public boolean evaluateConfirmationExpression(UserType user, ShadowType shadow, ExpressionVariables variables = getDefaultXPathVariables(user, shadow, resource); String shortDesc = "confirmation expression for "+resource.asPrismObject(); - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition<>(ExpressionConstants.OUTPUT_ELMENT_NAME, + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, outputDefinition, shortDesc, task, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java index 8f34cabfef0..4d3d78f7e25 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision; import com.evolveum.midpoint.model.api.expr.MidpointFunctions; @@ -28,13 +29,14 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.match.DefaultMatchingRule; import com.evolveum.midpoint.prism.match.PolyStringOrigMatchingRule; -import com.evolveum.midpoint.prism.parser.XPathHolder; +import com.evolveum.midpoint.prism.marshaller.XPathHolder; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.DeltaConvertor; @@ -502,15 +504,14 @@ public Integer countAccounts(ResourceType resourceType, String attributeName private Integer countAccounts(ResourceType resourceType, QName attributeName, T attributeValue, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); RefinedObjectClassDefinition rAccountDef = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); RefinedAttributeDefinition attrDef = rAccountDef.findAttributeDefinition(attributeName); - EqualFilter idFilter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName()), attrDef, attributeValue); - EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, - rAccountDef.getObjectClassDefinition().getTypeName()); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resourceType); - AndFilter filter = AndFilter.createAnd(idFilter, ocFilter, resourceRefFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getName()).eq(attributeValue) + .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccountDef.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) + .build(); return modelObjectResolver.countObjects(ShadowType.class, query, null, task, result); } @@ -554,8 +555,9 @@ private List getObjectsInConflictOnPropertyValue(fi matchingRule = DefaultMatchingRule.NAME; } } - EqualFilter filter = EqualFilter.createEqual(propertyPath, propertyDefinition, matchingRule, propertyValue); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(objectType.getClass(), prismContext) + .item(propertyPath, propertyDefinition).eq(propertyValue).matching(matchingRule) + .build(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Determining uniqueness of property {} using query:\n{}", propertyPath, query.debugDump()); } @@ -601,16 +603,17 @@ private boolean isUniqueAccountValue(ResourceType resourceType, final Shadow Validate.notNull(shadowType, "Null shadow"); Validate.notNull(attributeName, "Null attribute name"); Validate.notNull(attributeValue, "Null attribute value"); - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); RefinedObjectClassDefinition rAccountDef = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); RefinedAttributeDefinition attrDef = rAccountDef.findAttributeDefinition(attributeName); - EqualFilter idFilter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName()), attrDef, attributeValue); - EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, - null, rAccountDef.getObjectClassDefinition().getTypeName()); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resourceType); - AndFilter filter = AndFilter.createAnd(idFilter, ocFilter, resourceRefFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - LOGGER.trace("Determining uniqueness of attribute {} using query:\n{}", attributeName, query.debugDump()); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getName()).eq(attributeValue) + .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccountDef.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) + .build(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Determining uniqueness of attribute {} using query:\n{}", attributeName, query.debugDump()); + } final Holder isUniqueHolder = new Holder(true); ResultHandler handler = new ResultHandler() { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java index 804ae6c7331..85178193a65 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -275,22 +276,17 @@ public Collection getManagersOfOrg(String orgOid, boolean preAuthorize Set retval = new HashSet(); OperationResult result = new OperationResult("getManagerOfOrg"); - PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); - PrismReferenceDefinition parentOrgRefDef = userDef.findReferenceDefinition(ObjectType.F_PARENT_ORG_REF); - PrismReference parentOrgRef = parentOrgRefDef.instantiate(); PrismReferenceValue parentOrgRefVal = new PrismReferenceValue(orgOid, OrgType.COMPLEX_TYPE); parentOrgRefVal.setRelation(SchemaConstants.ORG_MANAGER); - parentOrgRef.add(parentOrgRefVal); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(RefFilter.createReferenceEqual( - new ItemPath(ObjectType.F_PARENT_ORG_REF), parentOrgRef)); + ObjectQuery objectQuery = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(ObjectType.F_PARENT_ORG_REF).ref(parentOrgRefVal) + .build(); List> members = searchObjects(ObjectType.class, objectQuery, result, preAuthorized); for (PrismObject member : members) { if (member.asObjectable() instanceof UserType) { UserType user = (UserType) member.asObjectable(); -// if (isManagerOf(user, orgOid)) { retval.add(user); -// } } } return retval; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java index 4892dfa4229..c75677aae94 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java @@ -20,6 +20,8 @@ import javax.annotation.PostConstruct; import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -115,7 +117,7 @@ public ImportAccountsFromResourceTaskHandler() { @PostConstruct private void initialize() { // this call must not be in the constructor, because prismContext is not yet initialized at that moment - objectclassPropertyDefinition = new PrismPropertyDefinition<>(ModelConstants.OBJECTCLASS_PROPERTY_NAME, + objectclassPropertyDefinition = new PrismPropertyDefinitionImpl<>(ModelConstants.OBJECTCLASS_PROPERTY_NAME, DOMUtil.XSD_QNAME, prismContext); taskManager.registerHandler(HANDLER_URI, this); @@ -194,7 +196,7 @@ private SynchronizeAccountResultHandler createHandler(ResourceType resource, Pri RefinedResourceSchema refinedSchema; ObjectClassComplexTypeDefinition objectClass; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, LayerType.MODEL, prismContext); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Refined schema:\n{}", refinedSchema.debugDump()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java index c3dc55491c4..8ce22676573 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportObjectsFromFileTaskHandler.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.provisioning.api.ChangeNotificationDispatcher; import com.evolveum.midpoint.provisioning.api.ResourceObjectChangeListener; import com.evolveum.midpoint.schema.result.OperationConstants; @@ -80,7 +81,7 @@ public ImportObjectsFromFileTaskHandler() { @PostConstruct private void initialize() { - filenamePropertyDefinition = new PrismPropertyDefinition(ModelConstants.FILENAME_PROPERTY_NAME, + filenamePropertyDefinition = new PrismPropertyDefinitionImpl(ModelConstants.FILENAME_PROPERTY_NAME, DOMUtil.XSD_STRING, prismContext); // must not be in the constructor, because prismContext is null at that time taskManager.registerHandler(HANDLER_URI, this); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java index 87fa5c394ff..2417cd30a75 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java @@ -31,6 +31,9 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.schema.PrismSchema; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationConstants; @@ -439,7 +442,7 @@ protected void validateWithDynamicSchemas(PrismObject return; } try { - connectorSchema = PrismSchema.parse(connectorSchemaElement, true, "schema for " + connector, prismContext); + connectorSchema = PrismSchemaImpl.parse(connectorSchemaElement, true, "schema for " + connector, prismContext); } catch (SchemaException e) { result.recordFatalError("Error parsing connector schema for " + connector + ": "+e.getMessage(), e); return; @@ -501,7 +504,7 @@ private void checkSchema(XmlSchemaType dynamicSchema, String schemaName, Operati } try { - PrismSchema.parse(xsdElement, true, schemaName, prismContext); + PrismSchemaImpl.parse(xsdElement, true, schemaName, prismContext); } catch (SchemaException e) { result.recordFatalError("Error during " + schemaName + " schema integrity check: " + e.getMessage(), e); return; @@ -530,7 +533,7 @@ private PrismContainer validateDynamicSchema(List contentElements, QName com.evolveum.midpoint.prism.schema.PrismSchema schema = null; try { - schema = com.evolveum.midpoint.prism.schema.PrismSchema.parse(xsdElement, true, schemaName, prismContext); + schema = com.evolveum.midpoint.prism.schema.PrismSchemaImpl.parse(xsdElement, true, schemaName, prismContext); } catch (SchemaException e) { result.recordFatalError("Error during " + schemaName + " schema parsing: " + e.getMessage(), e); LOGGER.trace("Validation error: {}" + e.getMessage()); @@ -557,4 +560,4 @@ private void generateIdentifiers(PrismObject object, R } } - + diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java index 4dfb4ff0e01..f5c179b1120 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.common.SystemObjectCache; import com.evolveum.midpoint.model.impl.sync.SynchronizationService; import com.evolveum.midpoint.model.impl.util.AbstractSearchIterativeResultHandler; @@ -39,6 +40,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -371,7 +373,7 @@ private void checkShadow(ShadowCheckResult checkResult, PrismObject } if (checkOwners) { - List owners = searchOwners(shadow, result); + List> owners = searchOwners(shadow, result); if (owners != null) { shadow.setUserData(KEY_OWNERS, owners); if (owners.size() > 1) { @@ -403,7 +405,7 @@ private void checkShadow(ShadowCheckResult checkResult, PrismObject context.setResource(resource); RefinedResourceSchema resourceSchema; try { - resourceSchema = RefinedResourceSchema.getRefinedSchema(context.getResource(), LayerType.MODEL, prismContext); + resourceSchema = RefinedResourceSchemaImpl.getRefinedSchema(context.getResource(), LayerType.MODEL, prismContext); } catch (SchemaException e) { checkResult.recordError(Statistics.CANNOT_GET_REFINED_SCHEMA, new SchemaException("Couldn't derive resource schema: " + e.getMessage(), e)); return; @@ -478,18 +480,18 @@ private void checkShadow(ShadowCheckResult checkResult, PrismObject } } - private List searchOwners(PrismObject shadow, OperationResult result) { + private List> searchOwners(PrismObject shadow, OperationResult result) { try { - PrismReferenceValue refValue = new PrismReferenceValue(shadow.getOid(), ShadowType.COMPLEX_TYPE); - RefFilter ownerFilter = RefFilter.createReferenceEqual(new ItemPath(FocusType.F_LINK_REF), FocusType.class, prismContext, refValue); - ObjectQuery ownerQuery = ObjectQuery.createObjectQuery(ownerFilter); - List owners = repositoryService.searchObjects(FocusType.class, ownerQuery, null, result); + ObjectQuery ownerQuery = QueryBuilder.queryFor(FocusType.class, prismContext) + .item(FocusType.F_LINK_REF).ref(shadow.getOid()) + .build(); + List> owners = repositoryService.searchObjects(FocusType.class, ownerQuery, null, result); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Owners for {}: {}", ObjectTypeUtil.toShortString(shadow), owners); } return owners; - } catch (SchemaException e) { - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't create owners query for shadow {}", e, ObjectTypeUtil.toShortString(shadow)); + } catch (SchemaException|RuntimeException e) { + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't create/execute owners query for shadow {}", e, ObjectTypeUtil.toShortString(shadow)); return null; } } @@ -721,7 +723,7 @@ private void deleteShadows(DuplicateShadowsTreatmentInstruction instruction, Str sb.append(" --> deleted redundant shadow").append(skippedForDryRun()).append(" ").append(ObjectTypeUtil.toShortString(shadowToDelete)).append("\n"); String oid = shadowToDelete.getOid(); - List owners; + List> owners; if (checkOwners) { owners = (List) shadowToDelete.getUserData(KEY_OWNERS); } else { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java index dff93d9f4cc..7b610ee193e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java @@ -34,21 +34,10 @@ import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.model.impl.lens.projector.MappingEvaluator; import com.evolveum.midpoint.model.impl.util.Utils; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.OriginType; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContainerable; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.PlusMinusZero; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -744,7 +733,7 @@ public PrismValueDeltaSetTriple> evaluateMappingAsCo .sourceContext(focusOdo) .originType(OriginType.ASSIGNMENTS) .originObject(source) - .defaultTargetDefinition(new PrismPropertyDefinition(CONDITION_OUTPUT_NAME, DOMUtil.XSD_BOOLEAN, prismContext)); + .defaultTargetDefinition(new PrismPropertyDefinitionImpl<>(CONDITION_OUTPUT_NAME, DOMUtil.XSD_BOOLEAN, prismContext)); builder.addVariableDefinition(ExpressionConstants.VAR_USER, focusOdo); builder.addVariableDefinition(ExpressionConstants.VAR_FOCUS, focusOdo); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java index b5a16364ee8..f9a03cbe98d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java @@ -35,16 +35,7 @@ import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.model.impl.lens.projector.FocusConstraintsChecker; import com.evolveum.midpoint.model.impl.util.Utils; -import com.evolveum.midpoint.prism.ConsistencyCheckScope; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismReference; -import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -1522,7 +1513,7 @@ private void evaluateScriptArgument(ProvisioningScriptArgumentType argument, QName FAKE_SCRIPT_ARGUMENT_NAME = new QName(SchemaConstants.NS_C, "arg"); - PrismPropertyDefinition scriptArgumentDefinition = new PrismPropertyDefinition<>( + PrismPropertyDefinition scriptArgumentDefinition = new PrismPropertyDefinitionImpl<>( FAKE_SCRIPT_ARGUMENT_NAME, DOMUtil.XSD_STRING, prismContext); String shortDesc = "Provisioning script argument expression"; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index b49c17f4ea5..7e7c5f0e98c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -53,10 +53,11 @@ import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.provisioning.api.ChangeNotificationDispatcher; import com.evolveum.midpoint.provisioning.api.ProvisioningService; @@ -634,8 +635,9 @@ private HookOperationMode triggerReconcileAffected(LensCo PrismPropertyDefinition propertyDef = prismContext.getSchemaRegistry() .findPropertyDefinitionByElementName(SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY); PrismReferenceValue referenceValue = new PrismReferenceValue(context.getFocusContext().getOid(), RoleType.COMPLEX_TYPE); - ObjectFilter refFilter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), - UserType.class, prismContext, referenceValue); + ObjectFilter refFilter = QueryBuilder.queryFor(FocusType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(referenceValue) + .buildFilter(); SearchFilterType filterType = QueryConvertor.createSearchFilterType(refFilter, prismContext); QueryType queryType = new QueryType(); queryType.setFilter(filterType); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java index 7e3f179cf6a..65d90803fb8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java @@ -22,10 +22,7 @@ import javax.xml.namespace.QName; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.model.common.expression.ExpressionUtil; import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject; @@ -44,7 +41,7 @@ import com.evolveum.midpoint.prism.OriginType; import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.util.ItemPathUtil; @@ -451,7 +448,7 @@ private void evaluateKindIntentObjectClass(Task task, OperationResult result) "The specified resource and the resource in construction does not match"); } - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); if (refinedSchema == null) { // Refined schema may be null in some error-related border cases @@ -627,7 +624,7 @@ private Mapping, PrismContainerDefini .originType(OriginType.ASSIGNMENTS) .originObject(source); - RefinedAssociationDefinition rAssocDef = refinedObjectClassDefinition.findAssociation(assocName); + RefinedAssociationDefinition rAssocDef = refinedObjectClassDefinition.findAssociationDefinition(assocName); if (rAssocDef == null) { throw new SchemaException("No association " + assocName + " in object class " + refinedObjectClassDefinition.getHumanReadableName() + " in construction in " + source); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index a4df0405727..407b61a70eb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -25,6 +25,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ItemDelta; @@ -40,10 +41,6 @@ import org.jvnet.jaxb2_commons.lang.Validate; import com.evolveum.midpoint.common.crypto.CryptoUtil; -import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.api.context.ModelProjectionContext; import com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision; import com.evolveum.midpoint.prism.delta.ChangeType; @@ -566,14 +563,14 @@ public ResourceObjectTypeDefinitionType getResourceObjectTypeDefinitionType() { } private ResourceSchema getResourceSchema() throws SchemaException { - return RefinedResourceSchema.getResourceSchema(resource, getNotNullPrismContext()); + return RefinedResourceSchemaImpl.getResourceSchema(resource, getNotNullPrismContext()); } public RefinedResourceSchema getRefinedResourceSchema() throws SchemaException { if (resource == null) { return null; } - return RefinedResourceSchema.getRefinedSchema(resource, LayerType.MODEL, getNotNullPrismContext()); + return RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, getNotNullPrismContext()); } public RefinedObjectClassDefinition getStructuralObjectClassDefinition() throws SchemaException { @@ -617,7 +614,7 @@ public CompositeRefinedObjectClassDefinition getCompositeObjectClassDefinition() if (compositeObjectClassDefinition == null) { RefinedObjectClassDefinition structuralObjectClassDefinition = getStructuralObjectClassDefinition(); if (structuralObjectClassDefinition != null) { - compositeObjectClassDefinition = new CompositeRefinedObjectClassDefinition( + compositeObjectClassDefinition = new CompositeRefinedObjectClassDefinitionImpl( structuralObjectClassDefinition, getAuxiliaryObjectClassDefinitions()); } } @@ -758,9 +755,9 @@ public void recompute() throws SchemaException { } if (base == null && accDelta.isModify()) { - RefinedObjectClassDefinition rAccountDef = getCompositeObjectClassDefinition(); - if (rAccountDef != null) { - base = (PrismObject) rAccountDef.createBlankShadow(); + RefinedObjectClassDefinition rOCD = getCompositeObjectClassDefinition(); + if (rOCD != null) { + base = rOCD.createBlankShadow(); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java index e33614e35c6..d79837756b5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java @@ -27,9 +27,12 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.model.common.SystemObjectCache; import com.evolveum.midpoint.model.common.expression.*; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.polystring.PrismDefaultPolyStringNormalizer; +import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.util.ObjectResolver; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.*; @@ -72,6 +75,7 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.jetbrains.annotations.NotNull; /** * @author semancik @@ -122,7 +126,7 @@ public static ResourceType getResourceReadOnly(LensContex } public static String refineProjectionIntent(ShadowKindType kind, String intent, ResourceType resource, PrismContext prismContext) throws SchemaException { - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, LayerType.MODEL, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); RefinedObjectClassDefinition rObjClassDef = refinedSchema.getRefinedDefinition(kind, intent); if (rObjClassDef == null) { throw new SchemaException("No projection definition for kind="+kind+" intent="+intent+" in "+resource); @@ -558,7 +562,7 @@ public static Object getIterationVariableValue(LensProjectionContext accCtx) { if (iterationOld == null) { return accCtx.getIteration(); } - PrismPropertyDefinition propDef = new PrismPropertyDefinition(ExpressionConstants.VAR_ITERATION, + PrismPropertyDefinition propDef = new PrismPropertyDefinitionImpl<>(ExpressionConstants.VAR_ITERATION, DOMUtil.XSD_INT, accCtx.getPrismContext()); PrismProperty propOld = propDef.instantiate(); propOld.setRealValue(iterationOld); @@ -579,7 +583,7 @@ public static Object getIterationTokenVariableValue(LensProjectionContext accCtx if (iterationTokenOld == null) { return accCtx.getIterationToken(); } - PrismPropertyDefinition propDef = new PrismPropertyDefinition( + PrismPropertyDefinition propDef = new PrismPropertyDefinitionImpl<>( ExpressionConstants.VAR_ITERATION_TOKEN, DOMUtil.XSD_STRING, accCtx.getPrismContext()); PrismProperty propOld = propDef.instantiate(); propOld.setRealValue(iterationTokenOld); @@ -759,12 +763,12 @@ public static String formatIterationToken(LensContext if (tokenExpressionType == null) { return formatIterationTokenDefault(iteration); } - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition(ExpressionConstants.VAR_ITERATION_TOKEN, + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.VAR_ITERATION_TOKEN, DOMUtil.XSD_STRING, context.getPrismContext()); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(tokenExpressionType, outputDefinition , "iteration token expression in "+accountContext.getHumanReadableName(), task, result); Collection> sources = new ArrayList<>(); - PrismPropertyDefinition inputDefinition = new PrismPropertyDefinition(ExpressionConstants.VAR_ITERATION, + PrismPropertyDefinitionImpl inputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.VAR_ITERATION, DOMUtil.XSD_INT, context.getPrismContext()); inputDefinition.setMaxOccurs(1); PrismProperty input = inputDefinition.instantiate(); @@ -817,7 +821,8 @@ public static boolean evaluateIterationCondition(LensCont if (expressionType == null) { return true; } - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition(ExpressionConstants.OUTPUT_ELMENT_NAME, + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>( + ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, context.getPrismContext()); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, outputDefinition , desc, task, result); @@ -1209,21 +1214,16 @@ private static void checkObjectPolicy(LensFocusContext } } - public static PrismContainer createAssignmentSingleValueContainerClone(AssignmentType assignmentType) throws SchemaException { - PrismContainerValue assignmentCVal = assignmentType.asPrismContainerValue(); - PrismContainerDefinition def = assignmentCVal.getParent().getDefinition().clone(); + public static PrismContainer createAssignmentSingleValueContainerClone(@NotNull AssignmentType assignmentType) throws SchemaException { // Make it appear to be single-value. Therefore paths without segment IDs will work. - def.setMaxOccurs(1); - PrismContainer assignmentCont = def.instantiate(); - assignmentCont.add(assignmentCVal.clone()); - return assignmentCont; + return assignmentType.asPrismContainerValue().asSingleValuedContainer(SchemaConstantsGenerated.C_ASSIGNMENT); } public static AssignmentType getAssignmentType(ItemDeltaItem,PrismContainerDefinition> assignmentIdi, boolean old) { if (old) { - return ((PrismContainer)assignmentIdi.getItemOld()).getValue(0).asContainerable(); + return assignmentIdi.getItemOld().getValue(0).asContainerable(); } else { - return ((PrismContainer)assignmentIdi.getItemNew()).getValue(0).asContainerable(); + return assignmentIdi.getItemNew().getValue(0).asContainerable(); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java index ff8c393e538..805c3ed145e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java @@ -26,14 +26,7 @@ import com.evolveum.midpoint.model.impl.lens.LensProjectionContext; import com.evolveum.midpoint.model.impl.lens.LensUtil; import com.evolveum.midpoint.model.impl.lens.SynchronizationIntent; -import com.evolveum.midpoint.prism.OriginType; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.prism.delta.PropertyDelta; @@ -530,7 +523,7 @@ public void process(ItemPath mappingOutputPath, params.setFixTarget(true); params.setContext(context); - PrismPropertyDefinition shadowExistsDef = new PrismPropertyDefinition<>( + PrismPropertyDefinitionImpl shadowExistsDef = new PrismPropertyDefinitionImpl<>( SHADOW_EXISTS_PROPERTY_NAME, DOMUtil.XSD_BOOLEAN, prismContext); shadowExistsDef.setMinOccurs(1); @@ -657,7 +650,7 @@ private ItemDeltaItem,PrismPropertyDefinition, PrismPropertyDefinition> createBooleanIdi( QName propertyName, Boolean old, Boolean current) throws SchemaException { - PrismPropertyDefinition definition = new PrismPropertyDefinition<>(propertyName, DOMUtil.XSD_BOOLEAN, prismContext); + PrismPropertyDefinitionImpl definition = new PrismPropertyDefinitionImpl<>(propertyName, DOMUtil.XSD_BOOLEAN, prismContext); definition.setMinOccurs(1); definition.setMaxOccurs(1); PrismProperty property = definition.instantiate(); @@ -698,7 +691,7 @@ private ItemDeltaItem,PrismPr } } - PrismPropertyDefinition existsDef = new PrismPropertyDefinition(FOCUS_EXISTS_PROPERTY_NAME, + PrismPropertyDefinitionImpl existsDef = new PrismPropertyDefinitionImpl<>(FOCUS_EXISTS_PROPERTY_NAME, DOMUtil.XSD_BOOLEAN, prismContext); existsDef.setMinOccurs(1); existsDef.setMaxOccurs(1); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java index 489956d4003..6428e3b7334 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java @@ -29,6 +29,8 @@ import javax.xml.datatype.XMLGregorianCalendar; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; import org.springframework.beans.factory.annotation.Autowired; @@ -1593,16 +1595,12 @@ private void checkAssigneeConstraints(LensContext conte } private int countAssignees(PrismObject target, String selfOid, OperationResult result) throws SchemaException { - ObjectFilter refFilter = RefFilter.createReferenceEqual( - new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, target.getOid()); - ObjectFilter filter; - if (selfOid == null) { - filter = refFilter; - } else { - InOidFilter oidFilter = InOidFilter.createInOid(selfOid); - filter = AndFilter.createAnd(refFilter, NotFilter.createNot(oidFilter)); + S_AtomicFilterExit q = QueryBuilder.queryFor(FocusType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(target.getOid()); + if (selfOid != null) { + q = q.and().not().id(selfOid); } - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = q.build(); return repositoryService.countObjects(FocusType.class, query, result); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java index b6c13d58562..7828e061e26 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java @@ -16,11 +16,7 @@ package com.evolveum.midpoint.model.impl.lens.projector; -import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.model.api.PolicyViolationException; import com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision; import com.evolveum.midpoint.model.common.mapping.Mapping; @@ -323,7 +319,7 @@ public boolean isSourceless() { throw new IllegalStateException("Structural object class definition for " + discr + " not found in the context, but it should be there"); } - RefinedObjectClassDefinition rOcDef = new CompositeRefinedObjectClassDefinition( + RefinedObjectClassDefinition rOcDef = new CompositeRefinedObjectClassDefinitionImpl( structuralObjectClassDefinition, auxOcDefs); if (LOGGER.isTraceEnabled()) { @@ -405,7 +401,7 @@ private ContainerDelta consolidate ItemPath itemPath = new ItemPath(ShadowType.F_ASSOCIATION); PrismContainerDefinition asspcContainerDef = getAssociationDefinition(); - RefinedAssociationDefinition associationDef = rOcDef.findAssociation(associationName); + RefinedAssociationDefinition associationDef = rOcDef.findAssociationDefinition(associationName); Comparator> comparator = new Comparator>() { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusConstraintsChecker.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusConstraintsChecker.java index e29514bf704..f814548031f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusConstraintsChecker.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusConstraintsChecker.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.caching.AbstractCache; @@ -125,8 +126,9 @@ private boolean checkPropertyUniqueness(PrismObject objectNew, ItemPath p } String oid = objectNew.getOid(); - ObjectQuery query = ObjectQuery.createObjectQuery( - EqualFilter.createEqual(propPath, property.clone())); + ObjectQuery query = QueryBuilder.queryFor(objectNew.getCompileTimeClass(), prismContext) + .itemAs(property) + .build(); List> foundObjects = repositoryService.searchObjects(objectNew.getCompileTimeClass(), query, null, result); if (LOGGER.isTraceEnabled()) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java index bb5d5d65ffb..66b4138a534 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java @@ -204,7 +204,7 @@ private void processInboundExpressionsForProjection(LensCo attributeAPrioriDelta = null; } - RefinedAttributeDefinition attrDef = accountDefinition.getAttributeDefinition(accountAttributeName); + RefinedAttributeDefinition attrDef = accountDefinition.findAttributeDefinition(accountAttributeName); if (attrDef.isIgnored(LayerType.MODEL)) { LOGGER.trace("Skipping inbound for attribute {} in {} because the attribute is ignored", @@ -345,7 +345,7 @@ private PrismObject loadProjection(LensContext private boolean hasAnyStrongMapping(RefinedObjectClassDefinition objectDefinition) { for (QName attributeName : objectDefinition.getNamesOfAttributesWithInboundExpressions()) { - RefinedAttributeDefinition attributeDefinition = objectDefinition.getAttributeDefinition(attributeName); + RefinedAttributeDefinition attributeDefinition = objectDefinition.findAttributeDefinition(attributeName); for (MappingType inboundMapping : attributeDefinition.getInboundMappingTypes()){ if (inboundMapping.getStrength() == MappingStrengthType.STRONG) { return true; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java index f8fee9a3d3b..d7f8e94a06e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java @@ -123,7 +123,7 @@ public void processOutbound(LensContext context, LensPr String operation = projCtx.getOperation().getValue(); for (QName attributeName : rOcDef.getNamesOfAttributesWithOutboundExpressions()) { - RefinedAttributeDefinition refinedAttributeDefinition = rOcDef.getAttributeDefinition(attributeName); + RefinedAttributeDefinition refinedAttributeDefinition = rOcDef.findAttributeDefinition(attributeName); final MappingType outboundMappingType = refinedAttributeDefinition.getOutboundMappingType(); if (outboundMappingType == null) { @@ -149,7 +149,7 @@ public void processOutbound(LensContext context, LensPr } for (QName assocName : rOcDef.getNamesOfAssociationsWithOutboundExpressions()) { - RefinedAssociationDefinition associationDefinition = rOcDef.findAssociation(assocName); + RefinedAssociationDefinition associationDefinition = rOcDef.findAssociationDefinition(assocName); final MappingType outboundMappingType = associationDefinition.getOutboundMappingType(); if (outboundMappingType == null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java index 9089a268aae..c70ad558d59 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java @@ -518,7 +518,7 @@ private void reconcileProjectionAssociations( for (QName assocName : associationNames) { LOGGER.trace("Association reconciliation processing association {}", assocName); - RefinedAssociationDefinition associationDefinition = accountDefinition.findAssociation(assocName); + RefinedAssociationDefinition associationDefinition = accountDefinition.findAssociationDefinition(assocName); if (associationDefinition == null) { throw new SchemaException("No definition for association " + assocName + " in " + projCtx.getResourceShadowDiscriminator()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/rest/MidpointXmlProvider.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/rest/MidpointXmlProvider.java index f89bedbbf32..703053242ab 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/rest/MidpointXmlProvider.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/rest/MidpointXmlProvider.java @@ -5,6 +5,7 @@ import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; +import java.util.Collection; import java.util.List; import javax.ws.rs.Consumes; @@ -15,18 +16,25 @@ import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; +import javax.xml.bind.JAXBException; +import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.util.logging.LoggingUtils; import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.provider.AbstractConfigurableProvider; +import org.apache.cxf.jaxrs.provider.JAXBElementProvider; import org.springframework.beans.factory.annotation.Autowired; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.result.OperationResult; 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.xml.ns._public.common.api_types_3.ObjectModificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; @Produces({"application/xml", "application/*+xml", "text/xml" }) @@ -66,21 +74,23 @@ public void writeTo(T object, Class type, Type genericType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { - - String marhaledObj = null; - - if (object instanceof PrismObject){ - marhaledObj = prismContext.getJaxbDomHack().silentMarshalObject(((PrismObject) object).asObjectable(), LOGGER); - } else if (object instanceof OperationResult){ - OperationResultType operationResultType = ((OperationResult) object).createOperationResultType(); - marhaledObj = prismContext.getJaxbDomHack().silentMarshalObject(operationResultType, LOGGER); - } else{ - marhaledObj = prismContext.getJaxbDomHack().silentMarshalObject(object, LOGGER); + + // TODO implement in the standard serializer; also change root name + QName fakeQName = new QName(PrismConstants.NS_PREFIX + "debug", "debugPrintObject"); + String xml; + try { + if (object instanceof PrismObject) { + xml = prismContext.xmlSerializer().serialize((PrismObject) object); + } else if (object instanceof OperationResult) { + OperationResultType operationResultType = ((OperationResult) object).createOperationResultType(); + xml = prismContext.xmlSerializer().serializeAnyData(operationResultType, fakeQName); + } else { + xml = prismContext.xmlSerializer().serializeAnyData(object, fakeQName); + } + entityStream.write(xml.getBytes("utf-8")); + } catch (SchemaException | RuntimeException e) { + LoggingUtils.logException(LOGGER, "Couldn't marshal element to string: {}", e, object); } - - entityStream.write(marhaledObj.getBytes("utf-8")); - - } @Override @@ -108,9 +118,9 @@ public T readFrom(Class type, Type genericType, try { if (type.isAssignableFrom(PrismObject.class)){ - object = (T) prismContext.parseObject(entityStream, PrismContext.LANG_XML); + object = (T) prismContext.parserFor(entityStream).xml().parse(); } else { - object = prismContext.parseAnyValue(entityStream, PrismContext.LANG_XML); + object = prismContext.parserFor(entityStream).xml().parseRealValue(); //object = (T) prismContext.getJaxbDomHack().unmarshalObject(entityStream); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/Data.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/Data.java index d9a5f2ce2fa..36c0fcd91d3 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/Data.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/Data.java @@ -17,17 +17,12 @@ package com.evolveum.midpoint.model.impl.scripting; import com.evolveum.midpoint.model.api.ScriptExecutionException; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismReference; -import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.EventHandlerType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; @@ -107,32 +102,50 @@ public String getDataAsSingleString() throws ScriptExecutionException { } } - public static Data createProperty(Object object, PrismContext prismContext) { - return createProperty(Collections.singletonList(object), object.getClass(), prismContext); - } - - public static Data createProperty(List objects, Class clazz, PrismContext prismContext) { + public static Data createItem(PrismValue value, PrismContext prismContext) throws SchemaException { // TODO fix this temporary solution (haven't we somewhere universal method to do this?) - QName elementName; - QName typeName; - if (String.class.isAssignableFrom(clazz)) { - elementName = PLAIN_STRING_ELEMENT_NAME; - typeName = DOMUtil.XSD_STRING; - } else if (ObjectDeltaType.class.isAssignableFrom(clazz)) { - elementName = SchemaConstants.T_OBJECT_DELTA; - typeName = SchemaConstants.T_OBJECT_DELTA_TYPE; - } else if (EventHandlerType.class.isAssignableFrom(clazz)) { - elementName = SchemaConstants.C_EVENT_HANDLER; - typeName = EventHandlerType.COMPLEX_TYPE; + if (value instanceof PrismReferenceValue) { + PrismReference ref = new PrismReference(new QName("reference")); + ref.add((PrismReferenceValue) value); + return create(ref); + } else if (value instanceof PrismContainerValue) { + PrismContainerValue pcv = (PrismContainerValue) value; + return create(pcv.asSingleValuedContainer(new QName("container"))); + } else if (value instanceof PrismPropertyValue) { + if (value.isRaw()) { + throw new IllegalArgumentException("Value cannot be raw at this point: " + value); + } + Class clazz = value.getRealClass(); + assert clazz != null; + PrismPropertyDefinition propertyDefinition; + List defs = prismContext.getSchemaRegistry() + .findItemDefinitionsByCompileTimeClass(clazz, PrismPropertyDefinition.class); + if (defs.size() == 1) { + propertyDefinition = defs.get(0); + } else if (String.class.isAssignableFrom(clazz)) { + propertyDefinition = new PrismPropertyDefinitionImpl<>(PLAIN_STRING_ELEMENT_NAME, DOMUtil.XSD_STRING, prismContext); + } else if (ObjectDeltaType.class.isAssignableFrom(clazz)) { + propertyDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstants.T_OBJECT_DELTA, SchemaConstants.T_OBJECT_DELTA_TYPE, prismContext); + } else if (EventHandlerType.class.isAssignableFrom(clazz)) { + propertyDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstants.C_EVENT_HANDLER, EventHandlerType.COMPLEX_TYPE, prismContext); + } else { + // maybe determine type from class would be sufficient + TypeDefinition td = prismContext.getSchemaRegistry().findTypeDefinitionByCompileTimeClass(clazz, TypeDefinition.class); + if (td != null) { + propertyDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstants.C_VALUE, td.getTypeName(), prismContext); + } else { + throw new IllegalStateException( + "Unsupported data class (to be put into scripting data as property): " + clazz); + } + } + PrismProperty property = propertyDefinition.instantiate(); + property.add((PrismPropertyValue) value); + return create(property); + } else if (value == null) { + return createEmpty(); } else { - throw new IllegalStateException("Unsupported data class (to be put into scripting data as property): " + clazz); - } - PrismPropertyDefinition propertyDefinition = new PrismPropertyDefinition<>(elementName, typeName, prismContext); - PrismProperty property = propertyDefinition.instantiate(); - for (Object object : objects) { - property.addRealValue(object); + throw new IllegalArgumentException("Unsupported prism value: " + value); } - return create(property); } public Collection getDataAsReferences(QName defaultTargetType) throws ScriptExecutionException { @@ -144,7 +157,7 @@ public Collection getDataAsReferences(QName defaultTargetTy ref.setOid(((PrismObject) item).getOid()); // todo check if oid is present retval.add(ref); } else if (item instanceof PrismProperty) { - for (Object value : ((PrismProperty) item).getRealValues()) { + for (Object value : item.getRealValues()) { if (value instanceof String) { ObjectReferenceType ref = new ObjectReferenceType(); ref.setType(defaultTargetType); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java index 581f0c2d2c7..0701f656a76 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java @@ -20,10 +20,8 @@ import com.evolveum.midpoint.model.impl.scripting.expressions.SearchEvaluator; import com.evolveum.midpoint.model.impl.scripting.expressions.SelectEvaluator; import com.evolveum.midpoint.model.impl.scripting.helpers.JaxbHelper; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.ParsingContext; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -46,6 +44,8 @@ import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -254,15 +254,36 @@ private Data executeSequence(ExpressionSequenceType sequence, Data input, Execut return lastOutput; } - public Data evaluateConstantExpression(RawType constant, ExecutionContext context, OperationResult result) throws ScriptExecutionException { + public Data evaluateConstantExpression(@NotNull RawType constant, @Nullable Class expectedClass, ExecutionContext context, String desc, OperationResult result) throws ScriptExecutionException { try { - Object value = prismContext.getXnodeProcessor().parseAnyData(constant.getXnode(), ParsingContext.createDefault()); - if (value instanceof Item) { - return Data.create((Item) value); + // TODO fix this brutal hacking + PrismValue value; + if (expectedClass == null) { + value = constant.getParsedValue(null, null); } else { - return Data.createProperty(value, prismContext); + Object object = constant.getParsedRealValue(expectedClass); + if (object instanceof Referencable) { + value = ((Referencable) object).asReferenceValue(); + } else if (object instanceof Containerable) { + value = ((Containerable) object).asPrismContainerValue(); + } else { + value = new PrismPropertyValue<>(object); + } } + if (value.isRaw()) { + throw new IllegalStateException("Raw value while " + desc + ": " + value + ". Please specify type of the value."); + } + return Data.createItem(value, prismContext); + } catch (SchemaException e) { + throw new ScriptExecutionException(e.getMessage(), e); + } + } + + public Data evaluateConstantStringExpression(RawType constant, ExecutionContext context, OperationResult result) throws ScriptExecutionException { + try { + String value = constant.getParsedRealValue(String.class); + return Data.createItem(new PrismPropertyValue<>(value), prismContext); } catch (SchemaException e) { throw new ScriptExecutionException(e.getMessage(), e); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java index 03163ca00ab..4e4880e1722 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/AssignExecutor.java @@ -72,7 +72,7 @@ public Data execute(ActionExpressionType expression, Data input, ExecutionContex Collection resources; if (resourceParameterValue != null) { - Data data = expressionHelper.evaluateParameter(resourceParameterValue, input, context, result); + Data data = expressionHelper.evaluateParameter(resourceParameterValue, null, input, context, result); resources = data.getDataAsReferences(ResourceType.COMPLEX_TYPE); } else { resources = null; @@ -80,7 +80,7 @@ public Data execute(ActionExpressionType expression, Data input, ExecutionContex Collection roles; if (roleParameterValue != null) { - Data data = expressionHelper.evaluateParameter(roleParameterValue, input, context, result); + Data data = expressionHelper.evaluateParameter(roleParameterValue, null, input, context, result); roles = data.getDataAsReferences(RoleType.COMPLEX_TYPE); } else { roles = null; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java index 97eace7b192..31662da74d5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -138,12 +139,10 @@ private void determineConnectorMappings(Map rebindMap, ConnectorT LOGGER.trace("Finding obsolete versions for connector: {}", connectorType.asPrismObject().debugDump()); } - AndFilter filter = AndFilter.createAnd( - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_FRAMEWORK, ConnectorType.class, prismContext, null, connectorType.getFramework()), - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE, ConnectorType.class, prismContext, null, connectorType.getConnectorType())); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(ConnectorType.class, prismContext) + .item(SchemaConstants.C_CONNECTOR_FRAMEWORK).eq(connectorType.getFramework()) + .and().item(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE).eq(connectorType.getConnectorType()) + .build(); List> foundConnectors; try { foundConnectors = modelService.searchObjects(ConnectorType.class, query, null, null, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ModifyExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ModifyExecutor.java index 1969a6c328b..dc9c33749f7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ModifyExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ModifyExecutor.java @@ -61,7 +61,7 @@ public Data execute(ActionExpressionType expression, Data input, ExecutionContex boolean dryRun = getParamDryRun(expression, input, context, result); ActionParameterValueType deltaParameterValue = expressionHelper.getArgument(expression.getParameter(), PARAM_DELTA, true, true, NAME); - Data deltaData = expressionHelper.evaluateParameter(deltaParameterValue, input, context, result); + Data deltaData = expressionHelper.evaluateParameter(deltaParameterValue, ObjectDeltaType.class, input, context, result); for (Item item : input.getData()) { if (item instanceof PrismObject) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/TestResourceExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/TestResourceExecutor.java index 77cf6304bef..3335a8f6093 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/TestResourceExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/TestResourceExecutor.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.exception.CommunicationException; @@ -128,13 +129,10 @@ private void determineConnectorMappings(Map rebindMap, ConnectorT if (LOGGER.isTraceEnabled()) { LOGGER.trace("Finding obsolete versions for connector: {}", connectorType.asPrismObject().debugDump()); } - - AndFilter filter = AndFilter.createAnd( - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_FRAMEWORK, ConnectorType.class, prismContext, null, connectorType.getFramework()), - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE, ConnectorType.class, prismContext, null, connectorType.getConnectorType())); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(ConnectorType.class, prismContext) + .item(SchemaConstants.C_CONNECTOR_FRAMEWORK).eq(connectorType.getFramework()) + .and().item(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE).eq(connectorType.getConnectorType()) + .build(); List> foundConnectors; try { foundConnectors = modelService.searchObjects(ConnectorType.class, query, null, null, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java index d334ffe7ccb..bcfe24bf3af 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java @@ -22,7 +22,7 @@ import com.evolveum.midpoint.model.impl.scripting.helpers.ExpressionHelper; import com.evolveum.midpoint.model.impl.scripting.helpers.OperationsHelper; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/ExpressionHelper.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/ExpressionHelper.java index 7e4c8c563a0..439e6a4bfc8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/ExpressionHelper.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/ExpressionHelper.java @@ -28,6 +28,7 @@ import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ActionParameterValueType; import com.evolveum.prism.xml.ns._public.types_3.RawType; import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -78,7 +79,7 @@ public String getArgumentAsString(List arguments, Stri return data.getDataAsSingleString(); } } else if (parameterValue.getValue() != null) { - Data data = scriptingExpressionEvaluator.evaluateConstantExpression((RawType) parameterValue.getValue(), context, parentResult); + Data data = scriptingExpressionEvaluator.evaluateConstantStringExpression((RawType) parameterValue.getValue(), context, parentResult); if (data != null) { return data.getDataAsSingleString(); } @@ -103,13 +104,13 @@ public Boolean getArgumentAsBoolean(List arguments, St } } - public Data evaluateParameter(ActionParameterValueType parameter, Data input, ExecutionContext context, OperationResult result) + public Data evaluateParameter(ActionParameterValueType parameter, @Nullable Class expectedClass, Data input, ExecutionContext context, OperationResult result) throws ScriptExecutionException { Validate.notNull(parameter, "parameter"); if (parameter.getExpression() != null) { return scriptingExpressionEvaluator.evaluateExpression(parameter.getExpression(), input, context, result); } else if (parameter.getValue() != null) { - return scriptingExpressionEvaluator.evaluateConstantExpression((RawType) parameter.getValue(), context, result); + return scriptingExpressionEvaluator.evaluateConstantExpression((RawType) parameter.getValue(), expectedClass, context, "evaluating parameter " + parameter.getName(), result); } else { throw new IllegalStateException("No expression nor value specified"); } @@ -121,7 +122,7 @@ public T getSingleArgumentValue(List arguments, St if (paramValue == null) { return null; } - Data paramData = evaluateParameter(paramValue, input, executionContext, result); + Data paramData = evaluateParameter(paramValue, clazz, input, executionContext, result); if (paramData.getData().size() != 1) { throw new ScriptExecutionException("Exactly one item was expected in '" + parameterName + "' parameter. Got " + paramData.getData().size()); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java index 9cc381a7b17..7a72649ad3d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java @@ -184,66 +184,65 @@ private void initializePrincipalFromAssignments(MidPointPrincipal principal, Pri UserType userType = principal.getUser(); Collection authorizations = principal.getAuthorities(); - Collection adminGuiConfigurations = new ArrayList<>(); + List adminGuiConfigurations = new ArrayList<>(); Task task = taskManager.createTaskInstance(UserProfileServiceImpl.class.getName() + ".addAuthorizations"); OperationResult result = task.getResult(); principal.setApplicableSecurityPolicy(locateSecurityPolicy(principal, systemConfiguration, task, result)); - - if (userType.getAssignment().isEmpty()) { - if (systemConfiguration != null) { - principal.setAdminGuiConfiguration(systemConfiguration.asObjectable().getAdminGuiConfiguration()); - } - return; - } - - AssignmentEvaluator assignmentEvaluator = new AssignmentEvaluator<>(); - assignmentEvaluator.setRepository(repositoryService); - assignmentEvaluator.setFocusOdo(new ObjectDeltaObject(userType.asPrismObject(), null, userType.asPrismObject())); - assignmentEvaluator.setChannel(null); - assignmentEvaluator.setObjectResolver(objectResolver); - assignmentEvaluator.setSystemObjectCache(systemObjectCache); - assignmentEvaluator.setPrismContext(prismContext); - assignmentEvaluator.setMappingFactory(mappingFactory); - assignmentEvaluator.setMappingEvaluator(mappingEvaluator); - assignmentEvaluator.setActivationComputer(activationComputer); - assignmentEvaluator.setNow(clock.currentTimeXMLGregorianCalendar()); - - // We do need only authorizations. Therefore we not need to evaluate constructions, - // so switching it off is faster. It also avoids nasty problems with resources being down, - // resource schema not available, etc. - assignmentEvaluator.setEvaluateConstructions(false); - - // We do not have real lens context here. But the push methods in ModelExpressionThreadLocalHolder - // will need something to push on the stack. So give them context placeholder. - LensContext lensContext = new LensContextPlaceholder<>(prismContext); - assignmentEvaluator.setLensContext(lensContext); - - for(AssignmentType assignmentType: userType.getAssignment()) { - try { - ItemDeltaItem,PrismContainerDefinition> assignmentIdi = new ItemDeltaItem<>(); - assignmentIdi.setItemOld(LensUtil.createAssignmentSingleValueContainerClone(assignmentType)); - assignmentIdi.recompute(); - EvaluatedAssignment assignment = assignmentEvaluator.evaluate(assignmentIdi, false, userType, userType.toString(), task, result); - if (assignment.isValid()) { - authorizations.addAll(assignment.getAuthorizations()); - adminGuiConfigurations.addAll(assignment.getAdminGuiConfigurations()); + + if (!userType.getAssignment().isEmpty()) { + AssignmentEvaluator assignmentEvaluator = new AssignmentEvaluator<>(); + assignmentEvaluator.setRepository(repositoryService); + assignmentEvaluator.setFocusOdo(new ObjectDeltaObject<>(userType.asPrismObject(), null, userType.asPrismObject())); + assignmentEvaluator.setChannel(null); + assignmentEvaluator.setObjectResolver(objectResolver); + assignmentEvaluator.setSystemObjectCache(systemObjectCache); + assignmentEvaluator.setPrismContext(prismContext); + assignmentEvaluator.setMappingFactory(mappingFactory); + assignmentEvaluator.setMappingEvaluator(mappingEvaluator); + assignmentEvaluator.setActivationComputer(activationComputer); + assignmentEvaluator.setNow(clock.currentTimeXMLGregorianCalendar()); + + // We do need only authorizations. Therefore we not need to evaluate constructions, + // so switching it off is faster. It also avoids nasty problems with resources being down, + // resource schema not available, etc. + assignmentEvaluator.setEvaluateConstructions(false); + + // We do not have real lens context here. But the push methods in ModelExpressionThreadLocalHolder + // will need something to push on the stack. So give them context placeholder. + LensContext lensContext = new LensContextPlaceholder<>(prismContext); + assignmentEvaluator.setLensContext(lensContext); + + for (AssignmentType assignmentType: userType.getAssignment()) { + try { + ItemDeltaItem,PrismContainerDefinition> assignmentIdi = new ItemDeltaItem<>(); + assignmentIdi.setItemOld(LensUtil.createAssignmentSingleValueContainerClone(assignmentType)); + assignmentIdi.recompute(); + EvaluatedAssignment assignment = assignmentEvaluator.evaluate(assignmentIdi, false, userType, userType.toString(), task, result); + if (assignment.isValid()) { + authorizations.addAll(assignment.getAuthorizations()); + adminGuiConfigurations.addAll(assignment.getAdminGuiConfigurations()); + } + } catch (SchemaException e) { + LOGGER.error("Schema violation while processing assignment of {}: {}; assignment: {}", + userType, e.getMessage(), assignmentType, e); + } catch (ObjectNotFoundException e) { + LOGGER.error("Object not found while processing assignment of {}: {}; assignment: {}", + userType, e.getMessage(), assignmentType, e); + } catch (ExpressionEvaluationException e) { + LOGGER.error("Evaluation error while processing assignment of {}: {}; assignment: {}", + userType, e.getMessage(), assignmentType, e); + } catch (PolicyViolationException e) { + LOGGER.error("Policy violation while processing assignment of {}: {}; assignment: {}", + userType, e.getMessage(), assignmentType, e); } - } catch (SchemaException e) { - LOGGER.error("Schema violation while processing assignment of {}: {}; assignment: {}", - new Object[]{userType, e.getMessage(), assignmentType, e}); - } catch (ObjectNotFoundException e) { - LOGGER.error("Object not found while processing assignment of {}: {}; assignment: {}", - new Object[]{userType, e.getMessage(), assignmentType, e}); - } catch (ExpressionEvaluationException e) { - LOGGER.error("Evaluation error while processing assignment of {}: {}; assignment: {}", - new Object[]{userType, e.getMessage(), assignmentType, e}); - } catch (PolicyViolationException e) { - LOGGER.error("Policy violation while processing assignment of {}: {}; assignment: {}", - new Object[]{userType, e.getMessage(), assignmentType, e}); } - } + } + if (userType.getAdminGuiConfiguration() != null) { + // config from the user object should go last (to be applied as the last one) + adminGuiConfigurations.add(userType.getAdminGuiConfiguration()); + } principal.setAdminGuiConfiguration(AdminGuiConfigTypeUtil.compileAdminGuiConfiguration(adminGuiConfigurations, systemConfiguration)); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java index b1e4c5ffd67..16b26fe4822 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java @@ -21,6 +21,7 @@ import java.util.List; import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; +import com.evolveum.midpoint.prism.*; import org.apache.commons.lang.Validate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -32,11 +33,6 @@ import com.evolveum.midpoint.model.common.expression.ExpressionUtil; import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.impl.util.Utils; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -158,10 +154,10 @@ private boolean satisfyCondition(ShadowType currentShadow, ConditionalSearchFilt ExpressionType condition = conditionalFilter.getCondition(); ExpressionVariables variables = Utils.getDefaultExpressionVariables(null,currentShadow, resourceType, configurationType); - ItemDefinition outputDefinition = new PrismPropertyDefinition( + ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl( ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, prismContext); - PrismPropertyValue satisfy = ExpressionUtil.evaluateExpression(variables, + PrismPropertyValue satisfy = (PrismPropertyValue) ExpressionUtil.evaluateExpression(variables, outputDefinition, condition, expressionFactory, shortDesc, task, parentResult); if (satisfy.getValue() == null) { return false; @@ -390,7 +386,7 @@ public boolean evaluateConfirmationExpression(Class foc ExpressionVariables variables = Utils.getDefaultExpressionVariables(user, shadow, resource, configuration); String shortDesc = "confirmation expression for "+resource.asPrismObject(); - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition<>(ExpressionConstants.OUTPUT_ELMENT_NAME, + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, outputDefinition, shortDesc, task, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java index 08f3516c1cf..e04753f485a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/LiveSyncTaskHandler.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.impl.sync; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.impl.ModelConstants; import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.PrismContext; @@ -153,7 +154,7 @@ private TaskRunResult runInternal(Task task) { RefinedResourceSchema refinedSchema; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, LayerType.MODEL, prismContext); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); } catch (SchemaException e) { LOGGER.error("Live Sync: Schema error during processing account definition: {}",e.getMessage()); opResult.recordFatalError("Schema error during processing account definition: "+e.getMessage(),e); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java index 9ce7126e7c9..2ea90d5ca7b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java @@ -15,16 +15,6 @@ */ package com.evolveum.midpoint.model.impl.sync; -import java.util.Collection; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.xml.namespace.QName; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.audit.api.AuditEventStage; import com.evolveum.midpoint.audit.api.AuditEventType; @@ -32,24 +22,17 @@ import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.impl.ModelConstants; import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.LessFilter; -import com.evolveum.midpoint.prism.query.NotFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.OrFilter; -import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.provisioning.api.ChangeNotificationDispatcher; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; @@ -67,29 +50,26 @@ import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.schema.util.ShadowUtil; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.task.api.TaskCategory; -import com.evolveum.midpoint.task.api.TaskHandler; -import com.evolveum.midpoint.task.api.TaskManager; -import com.evolveum.midpoint.task.api.TaskRunResult; +import com.evolveum.midpoint.task.api.*; import com.evolveum.midpoint.task.api.TaskRunResult.TaskRunResultStatus; import com.evolveum.midpoint.util.Holder; import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; /** * The task hander for reconciliation. @@ -195,7 +175,7 @@ public TaskRunResult runInternal(Task coordinatorTask) { try { resource = provisioningService.getObject(ResourceType.class, resourceOid, null, coordinatorTask, opResult); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, LayerType.MODEL, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext); objectclassDef = Utils.determineObjectClass(refinedSchema, coordinatorTask); } catch (ObjectNotFoundException ex) { @@ -539,17 +519,14 @@ private boolean performShadowReconciliation(final PrismObject reso LOGGER.trace("Shadow reconciliation starting for {}, {} -> {}", new Object[]{resource, startTimestamp, endTimestamp}); OperationResult opResult = result.createSubresult(OperationConstants.RECONCILIATION+".shadowReconciliation"); - LessFilter timestampFilter = LessFilter.createLess(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP, ShadowType.class, prismContext, - XmlTypeConverter.createXMLGregorianCalendar(startTimestamp) , true); - PrismObjectDefinition shadowDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); - EqualFilter nullTimestamptFilter = EqualFilter.createNullEqual(new ItemPath(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP), shadowDef.findPropertyDefinition(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP), null); - OrFilter fullTimestampFilter = OrFilter.createOr(timestampFilter, nullTimestamptFilter); - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(resource); - ObjectFilter filter = AndFilter.createAnd(fullTimestampFilter, - RefFilter.createReferenceEqual(new ItemPath(ShadowType.F_RESOURCE_REF), ShadowType.class, prismContext, ref.asReferenceValue()), - EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, objectclassDef.getTypeName())); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .block() + .item(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP).le(XmlTypeConverter.createXMLGregorianCalendar(startTimestamp)) + .or().item(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP).isNull() + .endBlock() + .and().item(ShadowType.F_RESOURCE_REF).ref(ObjectTypeUtil.createObjectRef(resource).asReferenceValue()) + .and().item(ShadowType.F_OBJECT_CLASS).eq(objectclassDef.getTypeName()) + .build(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Shadow recon query:\n{}", query.debugDump()); } @@ -682,13 +659,11 @@ private boolean scanForUnfinishedOperations(Task task, String resourceOid, Recon OperationResult opResult = result.createSubresult(OperationConstants.RECONCILIATION+".repoReconciliation"); opResult.addParam("reconciled", true); - NotFilter notNull = NotFilter.createNot(createFailedOpFilter(null)); - AndFilter andFilter = AndFilter.createAnd(notNull, RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - prismContext, resourceOid)); - ObjectQuery query = ObjectQuery.createObjectQuery(andFilter); - - List> shadows = repositoryService.searchObjects( - ShadowType.class, query, null, opResult); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .block().not().item(ShadowType.F_FAILED_OPERATION_TYPE).isNull().endBlock() + .and().item(ShadowType.F_RESOURCE_REF).ref(resourceOid) + .build(); + List> shadows = repositoryService.searchObjects(ShadowType.class, query, null, opResult); task.setExpectedTotal((long) shadows.size()); // for this phase, obviously @@ -758,10 +733,6 @@ private boolean scanForUnfinishedOperations(Task task, String resourceOid, Recon return task.canRun(); } - private ObjectFilter createFailedOpFilter(FailedOperationTypeType failedOp) throws SchemaException{ - return EqualFilter.createEqual(ShadowType.F_FAILED_OPERATION_TYPE, ShadowType.class, prismContext, null, failedOp); - } - @Override public Long heartbeat(Task task) { // TODO Auto-generated method stub diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/trigger/TriggerScannerTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/trigger/TriggerScannerTaskHandler.java index fe8eadb3260..02ecf04496f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/trigger/TriggerScannerTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/trigger/TriggerScannerTaskHandler.java @@ -24,7 +24,6 @@ import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.LessFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; @@ -129,8 +128,9 @@ protected ObjectQuery createQuery(AbstractScannerResultHandler handl PrismContainerDefinition triggerContainerDef = focusObjectDef.findContainerDefinition(F_TRIGGER); if (handler.getLastScanTimestamp() == null) { - filter = LessFilter.createLess(new ItemPath(F_TRIGGER, F_TIMESTAMP), focusObjectDef, - handler.getThisScanTimestamp(), true); + filter = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(F_TRIGGER, F_TIMESTAMP).le(handler.getThisScanTimestamp()) + .buildFilter(); } else { filter = QueryBuilder.queryFor(ObjectType.class, prismContext) .exists(F_TRIGGER) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java index 91d2c749310..715c0a97f52 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractScannerTaskHandler.java @@ -19,6 +19,7 @@ import javax.xml.datatype.XMLGregorianCalendar; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -82,7 +83,7 @@ protected boolean initializeRun(H handler, TaskRunResult runResult, protected void finish(H handler, TaskRunResult runResult, Task task, OperationResult opResult) throws SchemaException { super.finish(handler, runResult, task, opResult); - PrismPropertyDefinition lastScanTimestampDef = new PrismPropertyDefinition( + PrismPropertyDefinition lastScanTimestampDef = new PrismPropertyDefinitionImpl<>( SchemaConstants.MODEL_EXTENSION_LAST_SCAN_TIMESTAMP_PROPERTY_NAME, DOMUtil.XSD_DATETIME, prismContext); PropertyDelta lastScanTimestampDelta = new PropertyDelta( diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java index 36b0ca1a7cb..1876e86c7a7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java @@ -36,7 +36,7 @@ import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.*; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.ObjectDeltaOperation; @@ -325,7 +325,7 @@ private static boolean containExpression(ObjectFilter filter){ return true; } - if (filter instanceof PropertyValueFilter && ((PropertyValueFilter) filter).getExpression() != null){ + if (filter instanceof ValueFilter && ((ValueFilter) filter).getExpression() != null){ return true; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java index aa06a37c4c2..c9e82af693a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java @@ -17,6 +17,7 @@ package com.evolveum.midpoint.model.impl.validator; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.api.validator.Issue; import com.evolveum.midpoint.model.api.validator.ResourceValidator; import com.evolveum.midpoint.model.api.validator.Scope; @@ -123,7 +124,7 @@ public ValidationResult validate(@NotNull PrismObject resourceObje ResourceSchema resourceSchema = null; try { - resourceSchema = RefinedResourceSchema.getResourceSchema(resourceObject, prismContext); + resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceObject, prismContext); } catch (Throwable t) { vr.add(Issue.Severity.WARNING, CAT_SCHEMA, C_NO_SCHEMA, getString(bundle, CLASS_DOT + C_NO_SCHEMA, t.getMessage()), diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java index ea233f6ab33..a53d3983869 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java @@ -119,8 +119,10 @@ private SceneImpl visualize(PrismContainerValue containerValue, SceneImpl own scene.setName(name); scene.setSourceRelPath(EMPTY_PATH); scene.setSourceAbsPath(EMPTY_PATH); - if (containerValue.getConcreteTypeDefinition() != null) { - scene.setSourceDefinition(containerValue.getConcreteTypeDefinition()); + if (containerValue.getComplexTypeDefinition() != null) { + // TEMPORARY!!! + PrismContainerDefinition pcd = prismContext.getSchemaRegistry().findContainerDefinitionByType(containerValue.getComplexTypeDefinition().getTypeName()); + scene.setSourceDefinition(pcd); } else if (containerValue.getParent() != null && containerValue.getParent().getDefinition() != null) { scene.setSourceDefinition(containerValue.getParent().getDefinition()); } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/TestRefinedSchema.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/TestRefinedSchema.java index c8b749b9092..fb03816ce03 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/TestRefinedSchema.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/TestRefinedSchema.java @@ -25,16 +25,13 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.*; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; import org.testng.annotations.Test; -import com.evolveum.midpoint.common.refinery.LayerRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.LayerRefinedResourceSchema; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; @@ -84,7 +81,7 @@ public void test000Sanity() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // WHEN - refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceDummyType, prismContext); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceDummyType, prismContext); display("Dummy refined schema", refinedSchema); @@ -98,7 +95,7 @@ public void test010SanityModel() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // WHEN - refinedSchemaModel = RefinedResourceSchema.getRefinedSchema(resourceDummyType, LayerType.MODEL, prismContext); + refinedSchemaModel = RefinedResourceSchemaImpl.getRefinedSchema(resourceDummyType, LayerType.MODEL, prismContext); display("Dummy refined schema (MODEL)", refinedSchemaModel); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandlerImplTest.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandlerImplTest.java index 4d9180f04b5..f4697403b0a 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandlerImplTest.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandlerImplTest.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.prism.ParsingContext; import com.evolveum.midpoint.prism.xnode.MapXNode; +import com.evolveum.midpoint.prism.xnode.RootXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.security.api.MidPointPrincipal; import org.springframework.beans.factory.annotation.Autowired; @@ -128,10 +129,9 @@ public void testEvaluateExpression() throws Exception { for (ConditionalSearchFilterType filter : synchronization.getCorrelation()){ MapXNode clauseXNode = filter.getFilterClauseXNode(); // key = q:equal, value = map (path + expression) - XNode expressionNode = ((MapXNode) clauseXNode.getSingleSubEntry("filter value").getValue()).get(new QName(SchemaConstants.NS_C, "expression")); + RootXNode expressionNode = ((MapXNode) clauseXNode.getSingleSubEntry("filter value").getValue()).getEntryAsRoot(new QName(SchemaConstants.NS_C, "expression")); - ExpressionType expression = PrismTestUtil.getPrismContext().getXnodeProcessor().parseAtomicValue(expressionNode, ExpressionType.COMPLEX_TYPE, - ParsingContext.createDefault()); + ExpressionType expression = PrismTestUtil.getPrismContext().parserFor(expressionNode).parseRealValue(ExpressionType.class); LOGGER.debug("Expression: {}",SchemaDebugUtil.prettyPrint(expression)); OperationResult result = new OperationResult("testCorrelationRule"); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/TestModelExpressions.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/TestModelExpressions.java index 0aab9c96e63..7e2c1fc91f6 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/TestModelExpressions.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/expr/TestModelExpressions.java @@ -28,6 +28,8 @@ import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; +import com.evolveum.midpoint.model.api.ModelService; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import org.springframework.beans.factory.annotation.Autowired; @@ -41,10 +43,8 @@ import com.evolveum.midpoint.model.common.expression.script.ScriptExpression; import com.evolveum.midpoint.model.common.expression.script.ScriptExpressionFactory; import com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.model.impl.controller.ModelController; +import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.constants.ExpressionConstants; @@ -147,7 +147,7 @@ public void testGetManagersOids() throws Exception { PrismObject chef = repositoryService.getObject(UserType.class, CHEF_OID, null, result); ScriptExpressionEvaluatorType scriptType = parseScriptType("expression-" + TEST_NAME + ".xml"); - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition<>(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext()); + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext()); ScriptExpression scriptExpression = scriptExpressionFactory.createScriptExpression(scriptType, outputDefinition, TEST_NAME); ExpressionVariables variables = new ExpressionVariables(); variables.addVariableDefinition(new QName(SchemaConstants.NS_C, "user"), chef); @@ -180,7 +180,7 @@ public void testIsUniquePropertyValue() throws Exception { PrismObject chef = repositoryService.getObject(UserType.class, CHEF_OID, null, result); ScriptExpressionEvaluatorType scriptType = parseScriptType("expression-" + TEST_NAME + ".xml"); - PrismPropertyDefinition outputDefinition = new PrismPropertyDefinition<>(PROPERTY_NAME, DOMUtil.XSD_BOOLEAN, PrismTestUtil.getPrismContext()); + PrismPropertyDefinition outputDefinition = new PrismPropertyDefinitionImpl<>(PROPERTY_NAME, DOMUtil.XSD_BOOLEAN, PrismTestUtil.getPrismContext()); ScriptExpression scriptExpression = scriptExpressionFactory.createScriptExpression(scriptType, outputDefinition, TEST_NAME); ExpressionVariables variables = new ExpressionVariables(); variables.addVariableDefinition(new QName(SchemaConstants.NS_C, "user"), chef); @@ -298,7 +298,7 @@ private String executeScriptExpressionString(final String TEST_NAME, ExpressionV OperationResult result = new OperationResult(TestModelExpressions.class.getName() + "." + TEST_NAME); ScriptExpressionEvaluatorType scriptType = parseScriptType("expression-" + TEST_NAME + ".xml"); - ItemDefinition outputDefinition = new PrismPropertyDefinition(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext()); + ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext()); ScriptExpression scriptExpression = scriptExpressionFactory.createScriptExpression(scriptType, outputDefinition, TEST_NAME); if (variables == null) { variables = new ExpressionVariables(); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java index 09e6b5fa9b6..dd8740172ca 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java @@ -122,12 +122,12 @@ public void test010SerializeAddUserBarbossa() throws Exception { System.out.println("Context before serialization = " + context.debugDump()); PrismContainer lensContextType = context.toPrismContainer(); - String xml = prismContext.serializeContainerValueToString(lensContextType.getValue(), lensContextType.getElementName(), PrismContext.LANG_XML); + String xml = prismContext.xmlSerializer().serialize(lensContextType.getValue(), lensContextType.getElementName()); System.out.println("Serialized form = " + xml); - PrismContainer unmarshalledContainer = prismContext.parseContainer(xml, LensContextType.class, PrismContext.LANG_XML); - LensContext context2 = LensContext.fromLensContextType(unmarshalledContainer.getValue().asContainerable(), context.getPrismContext(), provisioningService, result); + LensContextType unmarshalledContainer = prismContext.parserFor(xml).xml().parseRealValue(LensContextType.class); + LensContext context2 = LensContext.fromLensContextType(unmarshalledContainer, context.getPrismContext(), provisioningService, result); System.out.println("Context after deserialization = " + context.debugDump()); @@ -304,12 +304,12 @@ private void assignAccountToJackAsync(String testName, boolean serialize) throws System.out.println("Context before serialization = " + context.debugDump()); PrismContainer lensContextType = context.toPrismContainer(); - String xml = prismContext.serializeContainerValueToString(lensContextType.getValue(), lensContextType.getElementName(), PrismContext.LANG_XML); + String xml = prismContext.xmlSerializer().serialize(lensContextType.getValue(), lensContextType.getElementName()); System.out.println("Serialized form = " + xml); - PrismContainer unmarshalledContainer = prismContext.parseContainer(xml, LensContextType.class, PrismContext.LANG_XML); - context = LensContext.fromLensContextType(unmarshalledContainer.getValue().asContainerable(), context.getPrismContext(), provisioningService, result); + LensContextType unmarshalledContainer = prismContext.parserFor(xml).xml().parseRealValue(LensContextType.class); + context = LensContext.fromLensContextType(unmarshalledContainer, context.getPrismContext(), provisioningService, result); System.out.println("Context after deserialization = " + context.debugDump()); diff --git a/model/model-impl/src/test/resources/expr/account-xpath-evaluation.xml b/model/model-impl/src/test/resources/expr/account-xpath-evaluation.xml index a394b00ab2b..fc15a8b9139 100644 --- a/model/model-impl/src/test/resources/expr/account-xpath-evaluation.xml +++ b/model/model-impl/src/test/resources/expr/account-xpath-evaluation.xml @@ -334,6 +334,7 @@ jan prvy uid=janko nemenny,ou=people,dc=example,dc=com prvy + janco James Jr. unchanged James Jr. diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java index b0a78bf631e..500ed5a96bf 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java @@ -15,13 +15,18 @@ */ package com.evolveum.midpoint.model.intest; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceSchema; +import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.task.api.Task; @@ -67,6 +72,11 @@ private enum FocusOperation { RECONCILE, RECOMPUTE } private enum ShadowOperation { KEEP, DELETE, UNLINK, UNLINK_AND_TOMBSTONE } private enum ResourceObjectOperation { KEEP, DELETE } + private ObjectClassComplexTypeDefinition getAccountObjectClassDefinition() throws SchemaException { + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resourceDummyType, prismContext); + return schema.findObjectClassDefinition(dummyResourceCtl.getAccountObjectClassQName()); + } + @Test public void test100Reconcile_Keep_Keep() throws Exception { executeTest("test100Reconcile_Keep_Keep", FocusOperation.RECONCILE, ShadowOperation.KEEP, ResourceObjectOperation.KEEP); @@ -271,7 +281,8 @@ private void cleanUpAfterTest(Task task, OperationResult result) throws Exceptio private List> getJacksShadows(OperationResult result) throws SchemaException { ObjectQuery shadowQuery = QueryBuilder.queryFor(ShadowType.class, prismContext) .item(ShadowType.F_RESOURCE_REF).ref(RESOURCE_DUMMY_OID) - .and().item(ShadowType.F_ATTRIBUTES, SchemaConstants.ICFS_NAME).eq("jack") + .and().item(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstants.ICFS_NAME), + getAccountObjectClassDefinition().findAttributeDefinition(SchemaConstants.ICFS_NAME)).eq("jack") .build(); return repositoryService.searchObjects(ShadowType.class, shadowQuery, null, result); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java index 49d3cb1b12c..fb153b36788 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIteration.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; @@ -2354,8 +2355,9 @@ private void assertNoUserNick(String accountName, String accountFullName, String private String lookupIterationTokenByAdditionalName(String additionalName) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(TestIteration.class.getName() + ".lookupIterationTokenByAdditionalName"); OperationResult result = task.getResult(); - EqualFilter filter = EqualFilter.createEqual(UserType.F_ADDITIONAL_NAME, UserType.class, prismContext, null, PrismTestUtil.createPolyString(additionalName)); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ADDITIONAL_NAME).eq(PrismTestUtil.createPolyString(additionalName)) + .build(); List> objects = modelService.searchObjects(UserType.class, query, null, task, result); if (objects.isEmpty()) { return null; diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java index 56348ac7a85..1a9d815fe79 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java @@ -134,7 +134,7 @@ public void test200ExportUsers() throws Exception { Document xmlDocument = DOMUtil.parseDocument(xmlString); Schema javaxSchema = prismContext.getSchemaRegistry().getJavaxSchema(); Validator validator = javaxSchema.newValidator(); - validator.setResourceResolver(prismContext.getSchemaRegistry()); + validator.setResourceResolver(prismContext.getEntityResolver()); validator.validate(new DOMSource(xmlDocument)); PrismObject parsedUser = prismContext.parseObject(xmlString); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java index 3de340a3da5..9842fbc8a48 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java @@ -33,6 +33,7 @@ import javax.xml.namespace.QName; import com.evolveum.icf.dummy.resource.BreakMode; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.notifications.api.transports.Message; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.PropertyDelta; @@ -484,7 +485,7 @@ public void test106SearchAccountWithoutResourceSchema() throws Exception { // create weapon attribute definition - NOT SUPPORTED, use only when you know what you're doing! QName accountObjectClassQName = dummyResourceCtl.getAccountObjectClassQName(); QName weaponQName = dummyResourceCtl.getAttributeWeaponQName(); - PrismPropertyDefinition weaponFakeDef = new PrismPropertyDefinition(weaponQName, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinition weaponFakeDef = new PrismPropertyDefinitionImpl(weaponQName, DOMUtil.XSD_STRING, prismContext); ObjectQuery q = QueryBuilder.queryFor(ShadowType.class, prismContext) .item(ShadowType.F_RESOURCE_REF).ref(RESOURCE_DUMMY_OID) @@ -2355,7 +2356,7 @@ public void test191ModifyUserJackModifyAssignment() throws Exception { PrismObject dummyResource = repositoryService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, result); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(dummyResource, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(dummyResource, prismContext); // This explicitly parses the schema, therefore ... assertResourceSchemaParseCountIncrement(1); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java index 05ab685c02e..7af2dd55c39 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java @@ -28,6 +28,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -204,10 +205,10 @@ public void test010SearchReuqestableRoles() throws Exception { Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - ObjectFilter filter = EqualFilter.createEqual(RoleType.F_REQUESTABLE, RoleType.class, prismContext, null, true); - ObjectQuery query = new ObjectQuery(); - query.setFilter(filter); - + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(RoleType.F_REQUESTABLE).eq(true) + .build(); + // WHEN List> requestableRoles = modelService.searchObjects(RoleType.class, query, null, task, result); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java index 52f11f9a1f9..851f5225d28 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java @@ -29,6 +29,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -38,13 +40,6 @@ import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.model.api.PolicyViolationException; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; @@ -823,9 +818,9 @@ public void test850ModifyConfiguration() throws Exception { Task task = taskManager.createTaskInstance(TestResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - ItemPath propPath = new ItemPath(ResourceType.F_CONNECTOR_CONFIGURATION, + ItemPath propPath = new ItemPath(ResourceType.F_CONNECTOR_CONFIGURATION, SchemaConstants.ICF_CONFIGURATION_PROPERTIES, IntegrationTestTools.RESOURCE_DUMMY_CONFIGURATION_USELESS_STRING_ELEMENT_NAME); - PrismPropertyDefinition propDef = new PrismPropertyDefinition(IntegrationTestTools.RESOURCE_DUMMY_CONFIGURATION_USELESS_STRING_ELEMENT_NAME, + PrismPropertyDefinition propDef = new PrismPropertyDefinitionImpl<>(IntegrationTestTools.RESOURCE_DUMMY_CONFIGURATION_USELESS_STRING_ELEMENT_NAME, DOMUtil.XSD_STRING, prismContext); PropertyDelta propDelta = PropertyDelta.createModificationReplaceProperty(propPath, propDef, "whatever wherever"); ObjectDelta resourceDelta = ObjectDelta.createModifyDelta(RESOURCE_DUMMY_OID, propDelta, ResourceType.class, prismContext); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java index fbe392c9bdc..e7dd50fa5fa 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java @@ -34,6 +34,8 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.springframework.test.annotation.DirtiesContext; @@ -45,15 +47,8 @@ import com.evolveum.icf.dummy.resource.BreakMode; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.midpoint.model.api.PolicyViolationException; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.model.api.ProgressListener; +import com.evolveum.midpoint.notifications.api.transports.Message; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -701,19 +696,17 @@ private void searchDeGhoulash(String testName, QName propName, T propValue) assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); // Simple query - ObjectFilter filter = EqualFilter.createEqual(new ItemPath(UserType.F_EXTENSION, propName), UserType.class, prismContext, - propValue); - ObjectQuery query = new ObjectQuery(); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_EXTENSION, propName).eq(propValue) + .build(); // WHEN, THEN searchDeGhoulash(testName, query, task, result); // Complex query, combine with a name. This results in join down in the database - filter = AndFilter.createAnd( - EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, null, USER_DEGHOULASH_NAME), - EqualFilter.createEqual(new ItemPath(UserType.F_EXTENSION, propName), UserType.class, prismContext, propValue) - ); - query.setFilter(filter); + query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_NAME).eq(USER_DEGHOULASH_NAME) + .and().item(UserType.F_EXTENSION, propName).eq(propValue) + .build(); // WHEN, THEN searchDeGhoulash(testName, query, task, result); } @@ -1178,16 +1171,15 @@ public void test520ShipReadBad() throws Exception { PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); PrismContainerDefinition extensionDefinition = userDef.getExtensionDefinition(); List extensionDefs = extensionDefinition.getComplexTypeDefinition().getDefinitions(); - Iterator iterator = extensionDefs.iterator(); - while (iterator.hasNext()) { - ItemDefinition itemDefinition = iterator.next(); - if (itemDefinition.getName().equals(PIRACY_SHIP)) { - iterator.remove(); - } - } + for (ItemDefinition itemDefinition : extensionDefs) { + if (itemDefinition.getName().equals(PIRACY_SHIP)) { + //iterator.remove(); // not possible as the collection is unmodifiable + ((ItemDefinitionImpl) itemDefinition).setName(new QName(NS_PIRACY, "ship-broken")); + } + } // WHEN - PrismObject user = modelService.getObject(UserType.class, USER_GUYBRUSH_OID, null, task, result); + modelService.getObject(UserType.class, USER_GUYBRUSH_OID, null, task, result); // THEN TestUtil.displayThen(TEST_NAME); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java index 291bbcd96fb..133b338f635 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java @@ -29,6 +29,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.apache.commons.lang.StringUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; @@ -112,7 +113,7 @@ public void test010RefinedSchemaWhite() throws Exception { // WHEN PrismObject resourceWhite = getObject(ResourceType.class, RESOURCE_DUMMY_WHITE_OID); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceWhite, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceWhite, prismContext); display("Refined schema", refinedSchema); RefinedObjectClassDefinition accountDef = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestModelWebServiceNegative.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestModelWebServiceNegative.java index e25ffc0d325..5a25f2df944 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestModelWebServiceNegative.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestModelWebServiceNegative.java @@ -20,7 +20,7 @@ import javax.xml.namespace.QName; -import com.evolveum.midpoint.prism.parser.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -138,7 +138,8 @@ public void test200ModifyAccountWrongExplicitType() throws Exception { deltaList.getDelta().add(objectChange); // WHEN, THEN - assertExecuteChangesFailure(deltaList, null, SchemaViolationFaultType.class, "The value of type", "cannot be applied to attribute"); + //assertExecuteChangesFailure(deltaList, null, SchemaViolationFaultType.class, "The value of type", "cannot be applied to attribute"); + assertExecuteChangesFailure(deltaList, null, SchemaViolationFaultType.class, "Expected", "but got class"); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java index 364030d9d51..4511815affa 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java @@ -31,6 +31,7 @@ import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.util.LogfileTestTailer; import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; @@ -43,6 +44,7 @@ import org.testng.collections.Sets; import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -140,7 +142,7 @@ public void test120Log() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty logAction = (PrismProperty) prismContext.parseAnyData(LOG_FILE); + PrismProperty logAction = parseAnyData(LOG_FILE); LogfileTestTailer tailer = new LogfileTestTailer(LoggingConfigurationManager.AUDIT_LOGGER_NAME); tailer.tail(); @@ -157,6 +159,10 @@ public void test120Log() throws Exception { tailer.assertExpectedMessage(); } + private PrismProperty parseAnyData(File file) throws IOException, SchemaException { + return (PrismProperty) prismContext.parserFor(file).parseItemOrRealValue(); + } + @Test public void test200SearchUser() throws Exception { final String TEST_NAME = "test200SearchUser"; @@ -164,7 +170,7 @@ public void test200SearchUser() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_USERS_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_USERS_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -184,7 +190,7 @@ public void test205SearchForResources() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_RESOURCES_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_RESOURCES_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -203,7 +209,7 @@ public void test206SearchForRoles() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_ROLES_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_ROLES_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -222,7 +228,7 @@ public void test210SearchForShadows() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_SHADOWS_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_SHADOWS_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -242,7 +248,7 @@ public void test215SearchForShadowsNoFetch() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_SHADOWS_NOFETCH_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_SHADOWS_NOFETCH_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -262,7 +268,7 @@ public void test220SearchForUsersAccounts() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_USERS_ACCOUNTS_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_USERS_ACCOUNTS_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -282,7 +288,7 @@ public void test225SearchForUsersAccountsNoFetch() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SEARCH_FOR_USERS_ACCOUNTS_NOFETCH_FILE); + PrismProperty expression = parseAnyData(SEARCH_FOR_USERS_ACCOUNTS_NOFETCH_FILE); // WHEN Data output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result).getFinalOutput(); @@ -302,7 +308,7 @@ public void test300DisableJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(DISABLE_JACK_FILE); + PrismProperty expression = parseAnyData(DISABLE_JACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -323,7 +329,7 @@ public void test310EnableJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(ENABLE_JACK_FILE); + PrismProperty expression = parseAnyData(ENABLE_JACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -344,7 +350,7 @@ public void test320DeleteAndAddJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(DELETE_AND_ADD_JACK_FILE); + PrismProperty expression = parseAnyData(DELETE_AND_ADD_JACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -365,7 +371,7 @@ public void test330ModifyJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(MODIFY_JACK_FILE); + PrismProperty expression = parseAnyData(MODIFY_JACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -387,7 +393,7 @@ public void test340ModifyJackBack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(MODIFY_JACK_BACK_FILE); + PrismProperty expression = parseAnyData(MODIFY_JACK_BACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -409,7 +415,7 @@ public void test350RecomputeJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(RECOMPUTE_JACK_FILE); + PrismProperty expression = parseAnyData(RECOMPUTE_JACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -430,7 +436,7 @@ public void test360AssignToJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(ASSIGN_TO_JACK_FILE); + PrismProperty expression = parseAnyData(ASSIGN_TO_JACK_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -455,7 +461,7 @@ public void test370AssignToJackInBackground() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(ASSIGN_TO_JACK_2_FILE); + PrismProperty expression = parseAnyData(ASSIGN_TO_JACK_2_FILE); // WHEN Task task = taskManager.createTaskInstance(); @@ -506,7 +512,7 @@ public void test400PurgeSchema() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); Task task = taskManager.createTaskInstance(); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(PURGE_DUMMY_BLACK_SCHEMA_FILE); + PrismProperty expression = parseAnyData(PURGE_DUMMY_BLACK_SCHEMA_FILE); // ResourceType dummy = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_BLACK_OID, null, task, result).asObjectable(); // IntegrationTestTools.display("dummy resource before purge schema", dummy.asPrismObject()); @@ -542,7 +548,7 @@ public void test410TestResource() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(TEST_DUMMY_RESOURCE_FILE); + PrismProperty expression = parseAnyData(TEST_DUMMY_RESOURCE_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); @@ -566,7 +572,7 @@ public void test420NotificationAboutJack() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(NOTIFICATION_ABOUT_JACK_FILE); + PrismProperty expression = parseAnyData(NOTIFICATION_ABOUT_JACK_FILE); prepareNotifications(); // WHEN @@ -594,7 +600,7 @@ public void test430NotificationAboutJackType2() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(NOTIFICATION_ABOUT_JACK_TYPE2_FILE); + PrismProperty expression = parseAnyData(NOTIFICATION_ABOUT_JACK_TYPE2_FILE); prepareNotifications(); // WHEN @@ -627,7 +633,7 @@ public void test500ScriptingUsers() throws Exception { // GIVEN OperationResult result = new OperationResult(DOT_CLASS + TEST_NAME); - PrismProperty expression = (PrismProperty) prismContext.parseAnyData(SCRIPTING_USERS_FILE); + PrismProperty expression = parseAnyData(SCRIPTING_USERS_FILE); // WHEN ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(expression.getAnyValue().getValue(), result); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java index 9c14adc0612..7116d0d28bf 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java @@ -29,6 +29,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinitionImpl; import org.apache.commons.lang.mutable.MutableInt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @@ -312,7 +315,7 @@ public void test001SanityAzure() throws Exception { display("Dummy resource azure", dummyResourceAzure); // WHEN - ResourceSchema resourceSchemaAzure = RefinedResourceSchema.getResourceSchema(resourceDummyAzureType, prismContext); + ResourceSchema resourceSchemaAzure = RefinedResourceSchemaImpl.getResourceSchema(resourceDummyAzureType, prismContext); display("Dummy azure resource schema", resourceSchemaAzure); @@ -329,7 +332,7 @@ public void test002SanityAzureRefined() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // WHEN - RefinedResourceSchema refinedSchemaAzure = RefinedResourceSchema.getRefinedSchema(resourceDummyAzureType, prismContext); + RefinedResourceSchema refinedSchemaAzure = RefinedResourceSchemaImpl.getRefinedSchema(resourceDummyAzureType, prismContext); display("Dummy azure refined schema", refinedSchemaAzure); @@ -2510,15 +2513,14 @@ public void test610SearchDummyAccountsNameSubstring() throws Exception { // GIVEN Task task = createTask(TestImportRecon.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - - ObjectFilter ocFilter = ObjectQueryUtil.createResourceAndObjectClassFilter(RESOURCE_DUMMY_OID, - new QName(RESOURCE_DUMMY_NAMESPACE,"AccountObjectClass"), prismContext); - SubstringFilter subStringFilter = SubstringFilter.createSubstring( - new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstants.ICFS_NAME), - new ResourceAttributeDefinition(SchemaConstants.ICFS_NAME, DOMUtil.XSD_STRING, prismContext), "s"); - AndFilter andFilter = AndFilter.createAnd(ocFilter, subStringFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(andFilter); - + + ObjectQuery query = + ObjectQueryUtil.createResourceAndObjectClassFilterPrefix(RESOURCE_DUMMY_OID, new QName(RESOURCE_DUMMY_NAMESPACE, "AccountObjectClass"), prismContext) + .and().item(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstants.ICFS_NAME), + new ResourceAttributeDefinitionImpl(SchemaConstants.ICFS_NAME, DOMUtil.XSD_STRING, prismContext)) + .contains("s") + .build(); + // WHEN TestUtil.displayWhen(TEST_NAME); SearchResultList> objects = modelService.searchObjects(ShadowType.class, query, null, task, result); diff --git a/model/model-intest/src/test/resources/common/connector-dummy.xml b/model/model-intest/src/test/resources/common/connector-dummy.xml index 25e71f280ee..e3bea282790 100644 --- a/model/model-intest/src/test/resources/common/connector-dummy.xml +++ b/model/model-intest/src/test/resources/common/connector-dummy.xml @@ -19,7 +19,7 @@ xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:ns2="http://www.w3.org/2001/04/xmlenc#" - + xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#"> ICF com.evolveum.icf.dummy.connector.DummyConnector @@ -74,7 +74,7 @@ - + UI_INSTANCE_USELESS_GUARDED_STRING diff --git a/model/model-intest/src/test/resources/common/connector-ldap.xml b/model/model-intest/src/test/resources/common/connector-ldap.xml index 95952f4fc5f..59637581de8 100644 --- a/model/model-intest/src/test/resources/common/connector-ldap.xml +++ b/model/model-intest/src/test/resources/common/connector-ldap.xml @@ -16,6 +16,7 @@ --> ICF org.identityconnectors.ldap.LdapConnector http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/org.identityconnectors.ldap.LdapConnector @@ -77,7 +78,7 @@ - + Password Decryption Key @@ -85,7 +86,7 @@ - + Password diff --git a/model/model-intest/src/test/resources/schema/piracy.xsd b/model/model-intest/src/test/resources/schema/piracy.xsd index aadb365cfa4..8f2f3e483b7 100644 --- a/model/model-intest/src/test/resources/schema/piracy.xsd +++ b/model/model-intest/src/test/resources/schema/piracy.xsd @@ -124,6 +124,7 @@ + diff --git a/model/model-intest/src/test/resources/scripting/assign-to-jack-2.xml b/model/model-intest/src/test/resources/scripting/assign-to-jack-2.xml index 9ee8a9c33a5..a59685a616b 100644 --- a/model/model-intest/src/test/resources/scripting/assign-to-jack-2.xml +++ b/model/model-intest/src/test/resources/scripting/assign-to-jack-2.xml @@ -16,7 +16,9 @@ --> + xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xsd="http://www.w3.org/2001/XMLSchema"> c:UserType @@ -28,7 +30,7 @@ assign role - 12345678-d34d-b33f-f00d-555555556677 + 12345678-d34d-b33f-f00d-555555556677 \ No newline at end of file diff --git a/model/model-intest/src/test/resources/scripting/assign-to-jack.xml b/model/model-intest/src/test/resources/scripting/assign-to-jack.xml index 779a0d695b0..7b8ab173d49 100644 --- a/model/model-intest/src/test/resources/scripting/assign-to-jack.xml +++ b/model/model-intest/src/test/resources/scripting/assign-to-jack.xml @@ -16,7 +16,9 @@ --> + xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xsd="http://www.w3.org/2001/XMLSchema"> c:UserType @@ -28,11 +30,11 @@ assign role - 12345678-d34d-b33f-f00d-55555555cccc + 12345678-d34d-b33f-f00d-55555555cccc resource - 10000000-0000-0000-0000-000000000104 + 10000000-0000-0000-0000-000000000104 \ No newline at end of file diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index e61607344e4..f9602c6c220 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.model.api.ModelDiagnosticService; import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.model.api.ModelInteractionService; @@ -64,6 +65,7 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrgFilter; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; @@ -492,7 +494,7 @@ protected ObjectDelta createModifyUserAddAccount(String userOid, Prism ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resource.getOid()); account.asObjectable().setResourceRef(resourceRef); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); account.asObjectable().setObjectClass(refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT).getObjectClassDefinition().getTypeName()); ObjectDelta userDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, userOid, prismContext); @@ -595,7 +597,7 @@ protected PropertyDelta createAttributeDeleteDelta(PrismObject resource, QName attributeName) throws SchemaException { - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (refinedSchema == null) { throw new SchemaException("No refined schema for "+resource); } @@ -1014,16 +1016,16 @@ protected void assertAssignees(String targetOid, int expectedAssignees) throws S } protected int countAssignees(String targetOid, OperationResult result) throws SchemaException { - ObjectFilter filter = RefFilter.createReferenceEqual( - new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, targetOid); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(targetOid) + .build(); return repositoryService.countObjects(FocusType.class, query, result); } protected SearchResultList> listAssignees(String targetOid, OperationResult result) throws SchemaException { - ObjectFilter filter = RefFilter.createReferenceEqual( - new ItemPath(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, targetOid); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(targetOid) + .build(); return repositoryService.searchObjects(FocusType.class, query, null, result); } @@ -1150,19 +1152,16 @@ protected PrismObject findAccountByUsername(String username, PrismOb protected Collection> listAccounts(PrismObject resource, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition rAccount = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); Collection identifierDefs = rAccount.getPrimaryIdentifiers(); assert identifierDefs.size() == 1 : "Unexpected identifier set in "+resource+" refined schema: "+identifierDefs; ResourceAttributeDefinition identifierDef = identifierDefs.iterator().next(); - EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, - rAccount.getObjectClassDefinition().getTypeName()); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resource); - AndFilter filter = AndFilter.createAnd(ocFilter, resourceRefFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_OBJECT_CLASS).eq(rAccount.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) + .build(); List> accounts = modelService.searchObjects(ShadowType.class, query, null, task, result); - return accounts; } @@ -1230,19 +1229,17 @@ protected void assertHasShadow(String username, PrismObject resour } protected ObjectQuery createAccountShadowQuery(String username, PrismObject resource) throws SchemaException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition rAccount = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); Collection identifierDefs = rAccount.getPrimaryIdentifiers(); assert identifierDefs.size() == 1 : "Unexpected identifier set in "+resource+" refined schema: "+identifierDefs; ResourceAttributeDefinition identifierDef = identifierDefs.iterator().next(); //TODO: set matching rule instead of null - EqualFilter idFilter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()), identifierDef, username); - EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, - rAccount.getObjectClassDefinition().getTypeName()); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - resource); - AndFilter filter = AndFilter.createAnd(idFilter, ocFilter, resourceRefFilter); - return ObjectQuery.createObjectQuery(filter); + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(identifierDef, ShadowType.F_ATTRIBUTES, identifierDef.getName()).eq(username) + .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccount.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) + .build(); } protected String getSingleLinkOid(PrismObject focus) { @@ -1484,10 +1481,9 @@ protected void assertSubOrgs(PrismObject baseOrg, int expected) throws } protected List> getSubOrgs(String baseOrgOid, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - ObjectQuery query = new ObjectQuery(); - PrismReferenceValue baseOrgRef = new PrismReferenceValue(baseOrgOid); - ObjectFilter filter = OrgFilter.createOrg(baseOrgRef, OrgFilter.Scope.ONE_LEVEL); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(OrgType.class, prismContext) + .isDirectChildOf(baseOrgOid) + .build(); return modelService.searchObjects(OrgType.class, query, null, task, result); } @@ -1715,7 +1711,7 @@ protected PrismObject createAccount(PrismObject resour ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resource.getOid()); shadowType.setResourceRef(resourceRef); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition objectClassDefinition = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); shadowType.setObjectClass(objectClassDefinition.getTypeName()); shadowType.setKind(ShadowKindType.ACCOUNT); @@ -1913,8 +1909,9 @@ protected void purgeResourceSchema(String resourceOid) throws ObjectAlreadyExist } protected List> searchOrg(String baseOrgOid, OrgFilter.Scope scope, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - ObjectFilter filter = OrgFilter.createOrg(baseOrgOid, scope); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(OrgType.class, prismContext) + .isInScopeOf(baseOrgOid, scope) + .build(); return modelService.searchObjects(OrgType.class, query, null, task, result); } diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java index 0996f3dd9c5..fb9aaa88bab 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/SimpleSmsTransport.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.notifications.impl.NotificationFuctionsImpl; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -226,7 +227,7 @@ private String evaluateExpression(ExpressionType expressionType, ExpressionVaria String shortDesc, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException { QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, DOMUtil.XSD_STRING, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java index 935db573501..7f748964894 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/handlers/BaseHandler.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.notifications.impl.NotificationFuctionsImpl; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -128,7 +129,7 @@ protected boolean evaluateBooleanExpression(ExpressionType expressionType, Expre Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException { QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition<>(resultName, DOMUtil.XSD_BOOLEAN, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl<>(resultName, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); PrismValueDeltaSetTriple> exprResultTriple = ModelExpressionThreadLocalHolder.evaluateExpressionInContext(expression, params, task, result); @@ -166,14 +167,14 @@ private List evaluateExpression(ExpressionType expressionType, Expressio String shortDesc, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException { QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition<>(resultName, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl<>(resultName, DOMUtil.XSD_STRING, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); PrismValueDeltaSetTriple> exprResult = ModelExpressionThreadLocalHolder .evaluateExpressionInContext(expression, params, task, result); - List retval = new ArrayList(); + List retval = new ArrayList<>(); for (PrismPropertyValue item : exprResult.getZeroSet()) { retval.add(item.getValue()); } diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/helpers/BaseHelper.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/helpers/BaseHelper.java index 4da5ec95576..e1f14ff8616 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/helpers/BaseHelper.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/helpers/BaseHelper.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.notifications.impl.NotificationFuctionsImpl; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -122,7 +123,7 @@ protected boolean evaluateBooleanExpression(ExpressionType expressionType, Expre Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException { QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, DOMUtil.XSD_BOOLEAN, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); @@ -161,7 +162,7 @@ private List evaluateExpression(ExpressionType expressionType, Expressio String shortDesc, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException { QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, DOMUtil.XSD_STRING, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result); diff --git a/model/notifications-impl/src/test/resources/schema/piracy.xsd b/model/notifications-impl/src/test/resources/schema/piracy.xsd new file mode 100644 index 00000000000..8f2f3e483b7 --- /dev/null +++ b/model/notifications-impl/src/test/resources/schema/piracy.xsd @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + true + + + + + + + false + + + + + + + true + + + + + + + true + + + + + + + + + + true + + + + + + + false + + + + + + + + + + + + + + Peg Leg + + + + + + + No Eye + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/CustomDataWriter.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/CustomDataWriter.java index c29b4319e53..b76118458eb 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/CustomDataWriter.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/CustomDataWriter.java @@ -47,7 +47,7 @@ public void write(Object obj, MessagePartInfo part, XMLStreamWriter output) { QName rootElement = part.getElementQName(); Element serialized; try { - serialized = prismContex.serializeAnyDataToElement(obj, rootElement); + serialized = prismContex.domSerializer().serializeAnyData(obj, rootElement); StaxUtils.copy(serialized, output); // output.writeCharacters(serialized); } catch (SchemaException | XMLStreamException e) { diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java index dcfbeb8a336..f703b0c3ac0 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java @@ -29,6 +29,7 @@ import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.EqualFilter; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; @@ -280,25 +281,30 @@ List searchObjects(Class type, ObjectQuery query) { return ret; } - EqualFilter createEqualFilter(QName propertyName, Class type, T realValues) throws SchemaException { - return EqualFilter.createEqual(propertyName, type, prismContext, realValues); + ObjectFilter createEqualFilter(QName propertyName, Class type, T realValue) throws SchemaException { + return QueryBuilder.queryFor(type, prismContext) + .item(propertyName).eq(realValue) + .buildFilter(); } - EqualFilter createEqualFilter(ItemPath propertyPath, Class type, T realValues) throws SchemaException { - return EqualFilter.createEqual(propertyPath, type, prismContext, realValues); + ObjectFilter createEqualFilter(ItemPath propertyPath, Class type, T realValue) throws SchemaException { + return QueryBuilder.queryFor(type, prismContext) + .item(propertyPath).eq(realValue) + .buildFilter(); } - RefFilter createReferenceEqualFilter(QName propertyName, Class type, String... oids) { - return RefFilter.createReferenceEqual(propertyName, type, prismContext, oids); - } + // TODO implement if needed +// RefFilter createReferenceEqualFilter(QName propertyName, Class type, String... oids) { +// return RefFilter.createReferenceEqual(propertyName, type, prismContext, oids); +// } - RefFilter createReferenceEqualFilter(ItemPath propertyPath, Class type, String... oids) throws SchemaException { - return RefFilter.createReferenceEqual(propertyPath, type, prismContext, oids); - } +// RefFilter createReferenceEqualFilter(ItemPath propertyPath, Class type, String... oids) throws SchemaException { +// return RefFilter.createReferenceEqual(propertyPath, type, prismContext, oids); +// } - Object parseObjectFromXML (String xml) throws SchemaException { - return prismContext.parseAnyData(xml, PrismContext.LANG_XML); - } +// Object parseObjectFromXML (String xml) throws SchemaException { +// return prismContext.parserFor(xml).xml().parseAnyData(); +// } /** * Retrieves all definitions. diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportManagerImpl.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportManagerImpl.java index 8124e15f26c..d262e768f90 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportManagerImpl.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportManagerImpl.java @@ -16,31 +16,6 @@ package com.evolveum.midpoint.report.impl; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.xml.datatype.Duration; -import javax.xml.datatype.XMLGregorianCalendar; - -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JasperCompileManager; -import net.sf.jasperreports.engine.JasperReport; -import net.sf.jasperreports.engine.design.JasperDesign; -import net.sf.jasperreports.engine.xml.JRXmlLoader; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.api.context.ModelElementContext; @@ -53,9 +28,8 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.LessFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.report.api.ReportManager; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -66,22 +40,33 @@ import com.evolveum.midpoint.schema.util.ReportTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskManager; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPolicyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportOutputType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportParameterType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ThreadStopActionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperCompileManager; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.design.JasperDesign; +import net.sf.jasperreports.engine.xml.JRXmlLoader; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.xml.datatype.Duration; +import javax.xml.datatype.XMLGregorianCalendar; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; /** @@ -303,9 +288,9 @@ public void cleanupReports(CleanupPolicyType cleanupPolicy, OperationResult pare List> obsoleteReportOutputs = new ArrayList>(); try { - ObjectQuery obsoleteReportOutputsQuery = ObjectQuery.createObjectQuery(LessFilter.createLess( - new ItemPath(ReportOutputType.F_METADATA, MetadataType.F_CREATE_TIMESTAMP), - ReportOutputType.class, prismContext, timeXml, true)); + ObjectQuery obsoleteReportOutputsQuery = QueryBuilder.queryFor(ReportOutputType.class, prismContext) + .item(ReportOutputType.F_METADATA, MetadataType.F_CREATE_TIMESTAMP).le(timeXml) + .build(); obsoleteReportOutputs = modelService.searchObjects(ReportOutputType.class, obsoleteReportOutputsQuery, null, null, result); } catch (Exception e) { throw new SystemException("Couldn't get the list of obsolete report outputs: " + e.getMessage(), e); diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java index 87f4b183d58..4c206d11d15 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportServiceImpl.java @@ -44,7 +44,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.TypeFilter; @@ -111,8 +111,7 @@ public ObjectQuery parseQuery(String query, Map parameters) throw Task task = taskManager.createTaskInstance(); ModelExpressionThreadLocalHolder.pushCurrentResult(task.getResult()); ModelExpressionThreadLocalHolder.pushCurrentTask(task); - SearchFilterType filter = (SearchFilterType) prismContext.parseAtomicValue(query, - SearchFilterType.COMPLEX_TYPE); + SearchFilterType filter = prismContext.parserFor(query).parseRealValue(SearchFilterType.class); LOGGER.trace("filter {}", filter); ObjectFilter f = QueryConvertor.parseFilter(filter, UserType.class, prismContext); LOGGER.trace("f {}", f.debugDump()); diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java index 298f068b124..2f7e754815b 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportWebServiceRaw.java @@ -13,6 +13,7 @@ import javax.xml.ws.Provider; import javax.xml.ws.soap.SOAPFaultException; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.w3c.dom.Document; @@ -99,7 +100,7 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { Object requestObject; try { - requestObject = prismContext.parseAnyValue(rootElement); + requestObject = prismContext.parserFor(rootElement).parseRealValue(); } catch (SchemaException e) { throw new FaultMessage("Couldn't parse SOAP request body because of schema exception: " + e.getMessage()); // throw ws.createIllegalArgumentFault("Couldn't parse SOAP request body because of schema exception: " + e.getMessage()); @@ -114,19 +115,19 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { ObjectListType olt = reportService.evaluateScript(s.getScript(), s.getParameters()); EvaluateScriptResponseType sr = new EvaluateScriptResponseType(); sr.setObjectList(olt); - response = prismContext.serializeAnyDataToElement(sr, ReportPort.EVALUATE_SCRIPT_RESPONSE, ctx); + response = prismContext.domSerializer().context(ctx).serializeAnyData(sr, ReportPort.EVALUATE_SCRIPT_RESPONSE); } else if (requestObject instanceof EvaluateAuditScriptType){ EvaluateAuditScriptType s = (EvaluateAuditScriptType) requestObject; AuditEventRecordListType olt = reportService.evaluateAuditScript(s.getScript(), s.getParameters()); EvaluateAuditScriptResponseType sr = new EvaluateAuditScriptResponseType(); sr.setObjectList(olt); - response = prismContext.serializeAnyDataToElement(sr, ReportPort.EVALUATE_AUDIT_SCRIPT_RESPONSE, ctx); + response = prismContext.domSerializer().context(ctx).serializeAnyData(sr, ReportPort.EVALUATE_AUDIT_SCRIPT_RESPONSE); } else if (requestObject instanceof ProcessReportType){ ProcessReportType p = (ProcessReportType) requestObject; ObjectListType olt = reportService.processReport(p.getQuery(), p.getParameters(), p.getOptions()); ProcessReportResponseType pr = new ProcessReportResponseType(); pr.setObjectList(olt); - response = prismContext.serializeAnyDataToElement(pr, ReportPort.PROCESS_REPORT_RESPONSE, ctx); + response = prismContext.domSerializer().context(ctx).serializeAnyData(pr, ReportPort.PROCESS_REPORT_RESPONSE); } else { throw new FaultMessage("Unsupported request type: " + requestObject); } @@ -145,16 +146,7 @@ public DOMSource invokeAllowingFaults(DOMSource request) throws FaultMessage { } private void serializeFaultMessage(Detail detail, FaultMessage faultMessage) { - try { - XNode faultMessageXnode = prismContext.getBeanConverter().marshall(faultMessage.getFaultInfo()); - RootXNode xroot = new RootXNode(SchemaConstants.FAULT_MESSAGE_ELEMENT_NAME, faultMessageXnode); - xroot.setExplicitTypeDeclaration(true); - QName faultType = prismContext.getBeanConverter().determineTypeForClass(faultMessage.getFaultInfo().getClass()); - xroot.setTypeQName(faultType); - prismContext.getParserDom().serializeUnderElement(xroot, SchemaConstants.FAULT_MESSAGE_ELEMENT_NAME, detail); - } catch (SchemaException e) { - LOGGER.error("Error serializing fault message (SOAP fault detail): {}", e.getMessage(), e); - } + MiscSchemaUtil.serializeFaultMessage(detail, faultMessage, prismContext, LOGGER); } // private DOMSource serializeFaultMessage(FaultMessage faultMessage) { diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/InitializeLoopThroughApproversInLevel.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/InitializeLoopThroughApproversInLevel.java index bdac39773b0..760fb60db7a 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/InitializeLoopThroughApproversInLevel.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/InitializeLoopThroughApproversInLevel.java @@ -143,7 +143,7 @@ private Collection evaluateExpression(ExpressionType appro PrismContext prismContext = expressionFactory.getPrismContext(); QName approverOidName = new QName(SchemaConstants.NS_C, "approverOid"); - PrismPropertyDefinition approverOidDef = new PrismPropertyDefinition(approverOidName, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinition approverOidDef = new PrismPropertyDefinitionImpl(approverOidName, DOMUtil.XSD_STRING, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(approverExpression, approverOidDef, "approverExpression", task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, "approverExpression", task, result); PrismValueDeltaSetTriple> exprResult = ModelExpressionThreadLocalHolder.evaluateExpressionInContext(expression, params, task, result); @@ -166,7 +166,7 @@ private boolean evaluateBooleanExpression(ExpressionType expressionType, Express PrismContext prismContext = expressionFactory.getPrismContext(); QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, DOMUtil.XSD_BOOLEAN, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, "automatic approval expression", task, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, "automatic approval expression", task, result); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ItemApprovalSpecificContent.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ItemApprovalSpecificContent.java index 158be231b83..f8d550b535b 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ItemApprovalSpecificContent.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ItemApprovalSpecificContent.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.wf.impl.tasks.ProcessSpecificContent; import com.evolveum.midpoint.xml.ns._public.common.common_3.ItemApprovalProcessStateType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WfProcessSpecificStateType; +import org.jetbrains.annotations.NotNull; import java.util.Map; @@ -28,9 +29,14 @@ */ public class ItemApprovalSpecificContent implements ProcessSpecificContent { + @NotNull private final PrismContext prismContext; private String taskName; private ApprovalSchema approvalSchema; + public ItemApprovalSpecificContent(@NotNull PrismContext prismContext) { + this.prismContext = prismContext; + } + public void setTaskName(String taskName) { this.taskName = taskName; } @@ -56,8 +62,7 @@ public ApprovalSchema getApprovalSchema() { @Override public WfProcessSpecificStateType createProcessSpecificState() { - ItemApprovalProcessStateType state = new ItemApprovalProcessStateType(); - state.asPrismContainerValue().setConcreteType(ItemApprovalProcessStateType.COMPLEX_TYPE); + ItemApprovalProcessStateType state = new ItemApprovalProcessStateType(prismContext); state.setApprovalSchema(approvalSchema != null ? approvalSchema.toApprovalSchemaType() : null); return state; } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpExpressionHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpExpressionHelper.java index 47627a0498c..38f9cb9141b 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpExpressionHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpExpressionHelper.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -80,7 +81,7 @@ private boolean evaluateBooleanExpression(ExpressionType expressionType, Express PrismContext prismContext = expressionFactory.getPrismContext(); QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, DOMUtil.XSD_BOOLEAN, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, DOMUtil.XSD_BOOLEAN, prismContext); Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, opContext, taskFromModel, result); ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, opContext, taskFromModel, result); PrismValueDeltaSetTriple> exprResultTriple = ModelExpressionThreadLocalHolder diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java index 0f477766390..2a3c605624d 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java @@ -50,7 +50,7 @@ protected PcpChildWfTaskCreationInstruction(ChangeProcessor changeProcessor, PI // useful shortcut public static PcpChildWfTaskCreationInstruction createItemApprovalInstruction(ChangeProcessor changeProcessor, String approvalTaskName, ApprovalRequest approvalRequest) { - ItemApprovalSpecificContent itemApprovalInstruction = new ItemApprovalSpecificContent(); + ItemApprovalSpecificContent itemApprovalInstruction = new ItemApprovalSpecificContent(changeProcessor.getPrismContext()); itemApprovalInstruction.setTaskName(approvalTaskName); itemApprovalInstruction.setApprovalSchema(approvalRequest.getApprovalSchema()); return new PcpChildWfTaskCreationInstruction<>(changeProcessor, itemApprovalInstruction); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessorSpecificContent.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessorSpecificContent.java index 686791bc414..7f104a0efb9 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessorSpecificContent.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessorSpecificContent.java @@ -33,7 +33,6 @@ public class PrimaryChangeProcessorSpecificContent implements ProcessorSpecificC public PrimaryChangeProcessorSpecificContent(PrismContext prismContext) { processorState = new WfPrimaryChangeProcessorStateType(prismContext); - processorState.asPrismContainerValue().setConcreteType(WfPrimaryChangeProcessorStateType.COMPLEX_TYPE); } public WfPrimaryChangeProcessorStateType createProcessorSpecificState() { diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java index 228bfb14734..133a6d59e5f 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java @@ -22,10 +22,7 @@ import com.evolveum.midpoint.model.common.expression.ExpressionFactory; import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -319,7 +316,7 @@ public boolean evaluateApplicabilityCondition(PcpAspectConfigurationType config, ExpressionType expressionType = config.getApplicabilityCondition(); QName resultName = new QName(SchemaConstants.NS_C, "result"); - PrismPropertyDefinition resultDef = new PrismPropertyDefinition(resultName, DOMUtil.XSD_BOOLEAN, prismContext); + PrismPropertyDefinition resultDef = new PrismPropertyDefinitionImpl(resultName, DOMUtil.XSD_BOOLEAN, prismContext); ExpressionVariables expressionVariables = new ExpressionVariables(); expressionVariables.addVariableDefinition(SchemaConstants.C_MODEL_CONTEXT, modelContext); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ResourceAssignmentHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ResourceAssignmentHelper.java index cbb5f9c0477..32ae381b4e1 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ResourceAssignmentHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ResourceAssignmentHelper.java @@ -79,7 +79,7 @@ protected ResourceType getAssignmentApprovalTarget(AssignmentType assignmentType protected AssignmentType cloneAndCanonicalizeAssignment(AssignmentType assignmentType) { AssignmentType assignmentClone = assignmentType.clone(); - PrismContainerValue.copyDefinition(assignmentClone, assignmentType); + PrismContainerValue.copyDefinition(assignmentClone, assignmentType, prismContext); ConstructionType constructionType = assignmentClone.getConstruction(); if (constructionType != null) { // it should always be non-null constructionType.setResource(null); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/RoleAssignmentHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/RoleAssignmentHelper.java index ed8ff54d691..7ecec237b3c 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/RoleAssignmentHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/RoleAssignmentHelper.java @@ -82,7 +82,7 @@ public ApprovalRequest createApprovalRequestForModificat // TODO is this ok? protected AssignmentType cloneAndCanonicalizeAssignment(AssignmentType assignmentType) { AssignmentType assignmentClone = assignmentType.clone(); - PrismContainerValue.copyDefinition(assignmentClone, assignmentType); + PrismContainerValue.copyDefinition(assignmentClone, assignmentType, prismContext); assignmentClone.setTarget(null); return assignmentClone; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java index 5748fad2d9a..1ef2fd1dc5b 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java @@ -182,7 +182,7 @@ public static String serializeObjectToXml(PrismObject obje public static String serializeContainerableToXml(Containerable containerable, PrismContext prismContext) { try { PrismContainerValue value = containerable.asPrismContainerValue(); - return prismContext.serializeContainerValueToString(value, value.getContainer().getElementName(), PrismContext.LANG_XML); + return prismContext.xmlSerializer().serialize(value, value.getContainer().getElementName()); } catch (SchemaException e) { throw new SystemException("Couldn't serialize a Containerable " + containerable + " into XML", e); } @@ -190,19 +190,19 @@ public static String serializeContainerableToXml(Containerable containerable, Pr public static ObjectType deserializeObjectFromXml(String xml, PrismContext prismContext) { try { - return (ObjectType) prismContext.parseObject(xml, PrismContext.LANG_XML).asObjectable(); + return (ObjectType) prismContext.parserFor(xml).xml().parse().asObjectable(); } catch (SchemaException e) { throw new SystemException("Couldn't deserialize a PrismObject from XML", e); } } - public static PrismContainer deserializeContainerFromXml(String xml, PrismContext prismContext) { - try { - return prismContext.parseContainer(xml, (Class) null, PrismContext.LANG_XML); - } catch (SchemaException e) { - throw new SystemException("Couldn't deserialize a Containerable from XML", e); - } - } +// public static PrismContainer deserializeContainerFromXml(String xml, PrismContext prismContext) { +// try { +// return prismContext.processorFor(xml).xml().unmarshallContainer(null); // TODO will 'null' work? +// } catch (SchemaException e) { +// throw new SystemException("Couldn't deserialize a Containerable from XML", e); +// } +// } public void resolveAssignmentTargetReferences(PrismObject object, OperationResult result) { for (AssignmentType assignmentType : object.asObjectable().getAssignment()) { diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/SingleItemSerializationSafeContainerImpl.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/SingleItemSerializationSafeContainerImpl.java index ff21915bcb6..ff4baaf469d 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/SingleItemSerializationSafeContainerImpl.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/SingleItemSerializationSafeContainerImpl.java @@ -74,7 +74,7 @@ public void setValue(T value) { checkPrismContext(); if (value != null && prismContext.canSerialize(value)) { try { - this.valueForStorageWhenEncoded = prismContext.serializeAnyData(value, new QName("value"), PrismContext.LANG_XML); + this.valueForStorageWhenEncoded = prismContext.xmlSerializer().serializeAnyData(value, new QName("value")); } catch (SchemaException e) { throw new SystemException("Couldn't serialize value of type " + value.getClass() + ": " + e.getMessage(), e); } @@ -115,7 +115,7 @@ public T getValue() { if (encodingScheme == EncodingScheme.PRISM) { try { - actualValue = (T) prismContext.parseAnyData(valueForStorageWhenEncoded, PrismContext.LANG_XML); + actualValue = (T) prismContext.parserFor(valueForStorageWhenEncoded).xml().parseItemOrRealValue(); if (actualValue instanceof Item) { Item item = (Item) actualValue; if (item.isEmpty()) { diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java index e0287b79faf..a50331117c5 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java @@ -39,6 +39,7 @@ import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.result.OperationResult; @@ -544,12 +545,12 @@ protected PrismObject findUserInRepo(String name, OperationResult resu } protected List> findUserInRepoUnchecked(String name, OperationResult result) throws SchemaException { - ObjectQuery q = ObjectQuery.createObjectQuery(EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, PolyStringOrigMatchingRule.NAME, new PolyString(name))); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, prismContext).item(UserType.F_NAME).eqPoly(name).matchingOrig().build(); return repositoryService.searchObjects(UserType.class, q, null, result); } protected List> findRoleInRepoUnchecked(String name, OperationResult result) throws SchemaException { - ObjectQuery q = ObjectQuery.createObjectQuery(EqualFilter.createEqual(RoleType.F_NAME, UserType.class, prismContext, PolyStringOrigMatchingRule.NAME, new PolyString(name))); + ObjectQuery q = QueryBuilder.queryFor(RoleType.class, prismContext).item(RoleType.F_NAME).eqPoly(name).matchingOrig().build(); return repositoryService.searchObjects(RoleType.class, q, null, result); } diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/ApprovingDummyResourceChangesScenarioBean.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/ApprovingDummyResourceChangesScenarioBean.java index 738b8f77149..f38cb75ceb0 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/ApprovingDummyResourceChangesScenarioBean.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/ApprovingDummyResourceChangesScenarioBean.java @@ -44,7 +44,7 @@ public class ApprovingDummyResourceChangesScenarioBean extends BaseGcpScenarioBe // PrismContainer extStateContainer = extDefinition.instantiate(); // ProcessSpecificState extState = extStateContainer.createNewValue().asContainerable(); // -// PrismPropertyDefinition deltaDefinition = new PrismPropertyDefinition( +// PrismPropertyDefinition deltaDefinition = new PrismPropertyDefinitionImpl( // DUMMY_RESOURCE_DELTA_QNAME, // new QName(SchemaConstantsGenerated.NS_TYPES, "ObjectDeltaType"), // prismContext); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java index de0d24a7289..55c13d0ed62 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java @@ -219,7 +219,7 @@ void completeWorkItem(WorkItemType workItem, String taskId, OperationResult resu // ObjectDeltaType deltaType = dummyResourceDelta.getRealValue(); // display("dummyResourceDelta", DeltaConvertor.createObjectDelta(deltaType, prismContext)); // -// PrismPropertyDefinition ppd = new PrismPropertyDefinition(new QName(SchemaConstants.NS_WFCF, "[Button]rejectAll"), +// PrismPropertyDefinition ppd = new PrismPropertyDefinitionImpl(new QName(SchemaConstants.NS_WFCF, "[Button]rejectAll"), // DOMUtil.XSD_BOOLEAN, prismContext); // PrismProperty rejectAll = ppd.instantiate(); // rejectAll.setRealValue(Boolean.TRUE); @@ -319,7 +319,7 @@ void completeWorkItem(WorkItemType workItem, String taskId, OperationResult resu // ObjectDeltaType deltaType = dummyResourceDelta.getRealValue(); // display("dummyResourceDelta", DeltaConvertor.createObjectDelta(deltaType, prismContext)); // -// PrismPropertyDefinition ppd = new PrismPropertyDefinition(new QName(SchemaConstants.NS_WFCF, "[Button]approve"), +// PrismPropertyDefinition ppd = new PrismPropertyDefinitionImpl(new QName(SchemaConstants.NS_WFCF, "[Button]approve"), // DOMUtil.XSD_BOOLEAN, prismContext); // PrismProperty approve = ppd.instantiate(); // approve.setRealValue(Boolean.TRUE); @@ -350,7 +350,7 @@ public void test000LoadContext() throws Exception { OperationResult result = new OperationResult("test000LoadContext"); - LensContextType lensContextType = prismContext.parseContainer(new File("src/test/resources/model-contexts/context-dummy-resource.xml"), LensContextType.class, PrismContext.LANG_XML).getValues().get(0).asContainerable(); + LensContextType lensContextType = prismContext.parserFor(new File("src/test/resources/model-contexts/context-dummy-resource.xml")).xml().parseRealValue(LensContextType.class); display("LensContextType", lensContextType); LensContext lensContext = LensContext.fromLensContextType(lensContextType, prismContext, provisioningService, result); display("LensContext", lensContext); diff --git a/model/workflow-impl/src/test/resources/common/connector-dummy.xml b/model/workflow-impl/src/test/resources/common/connector-dummy.xml index 02f95f41859..c3830460117 100644 --- a/model/workflow-impl/src/test/resources/common/connector-dummy.xml +++ b/model/workflow-impl/src/test/resources/common/connector-dummy.xml @@ -19,7 +19,7 @@ xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:ns2="http://www.w3.org/2001/04/xmlenc#" - + xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#"> ICF com.evolveum.icf.dummy.connector.DummyConnector @@ -66,7 +66,7 @@ - + UI_INSTANCE_USELESS_GUARDED_STRING diff --git a/model/workflow-impl/src/test/resources/model-context.obsolete.xml b/model/workflow-impl/src/test/resources/model-context.obsolete.xml index 6cbff767fea..80a770dd882 100644 --- a/model/workflow-impl/src/test/resources/model-context.obsolete.xml +++ b/model/workflow-impl/src/test/resources/model-context.obsolete.xml @@ -121,7 +121,7 @@ xmlns:wfpis="http://midpoint.evolveum.com/xml/ns/model/workflow/process-instance-state-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> @@ -229,7 +229,7 @@ xmlns:wfpis="http://midpoint.evolveum.com/xml/ns/model/workflow/process-instance-state-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> @@ -368,7 +368,7 @@ xmlns:wfpis="http://midpoint.evolveum.com/xml/ns/model/workflow/process-instance-state-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> @@ -532,7 +532,7 @@ c:credentials/c:password + xsi:type="t:ProtectedStringType"> @@ -597,7 +597,7 @@ - + diff --git a/model/workflow-impl/src/test/resources/model-contexts/context-dummy-resource.xml b/model/workflow-impl/src/test/resources/model-contexts/context-dummy-resource.xml index 8627121cfdc..370c99a75c3 100644 --- a/model/workflow-impl/src/test/resources/model-contexts/context-dummy-resource.xml +++ b/model/workflow-impl/src/test/resources/model-contexts/context-dummy-resource.xml @@ -299,7 +299,7 @@ replace c:credentials/c:password - + diff --git a/model/workflow-impl/src/test/resources/task.obsolete.xml b/model/workflow-impl/src/test/resources/task.obsolete.xml index bd23ea349c9..1bc087f4f9f 100644 --- a/model/workflow-impl/src/test/resources/task.obsolete.xml +++ b/model/workflow-impl/src/test/resources/task.obsolete.xml @@ -127,7 +127,7 @@ xmlns:wfpis="http://midpoint.evolveum.com/xml/ns/model/workflow/process-instance-state-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> @@ -234,7 +234,7 @@ xmlns:wfpis="http://midpoint.evolveum.com/xml/ns/model/workflow/process-instance-state-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> @@ -368,7 +368,7 @@ xmlns:wfpis="http://midpoint.evolveum.com/xml/ns/model/workflow/process-instance-state-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> @@ -528,7 +528,7 @@ c:credentials/c:password + xsi:type="t:ProtectedStringType"> @@ -592,7 +592,7 @@ - + diff --git a/pom.xml b/pom.xml index 2fc64684342..de4d43d3477 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,11 @@ + + org.apache.maven.plugins + maven-plugin-plugin + 3.3 + org.eclipse.m2e lifecycle-mapping diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java index 2443cfe079d..94ffaade064 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/consistency/impl/ObjectAlreadyExistHandler.java @@ -20,6 +20,9 @@ import java.util.Collection; import java.util.List; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -129,22 +132,16 @@ private ObjectQuery createQueryByIcfName(ShadowType shadow) throws SchemaExcepti // TODO: error handling TODO TODO TODO set matching rule instead of null in equlas filter Collection> secondaryIdentifiers = ShadowUtil.getSecondaryIdentifiers(shadow); - List secondaryIdentifierFilters = new ArrayList(); - - for (ResourceAttribute secondaryIdentifier : secondaryIdentifiers){ - EqualFilter equal = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, secondaryIdentifier.getElementName()), secondaryIdentifier); - secondaryIdentifierFilters.add(equal); + S_AtomicFilterEntry q = QueryBuilder.queryFor(ShadowType.class, prismContext); + // secondary identifiers connected by 'or' clause + q = q.block(); + for (ResourceAttribute secondaryIdentifier : secondaryIdentifiers) { + q = q.itemAs(secondaryIdentifier).or(); } - OrFilter orSecondary = OrFilter.createOr((List)secondaryIdentifierFilters); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, - prismContext, shadow.getResourceRef().getOid()); - EqualFilter objectClassFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, - null, shadow.getObjectClass()); - - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(orSecondary, resourceRefFilter, - objectClassFilter)); - - return query; + q = q.none().endBlock().and(); + // resource + object class + q = q.item(ShadowType.F_RESOURCE_REF).ref(shadow.getResourceRef().getOid()).and(); + return q.item(ShadowType.F_OBJECT_CLASS).eq(shadow.getObjectClass()).build(); } private List> getExistingAccount(ObjectQuery query, Task task, OperationResult parentResult) diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java index 71c6fa4c05e..7adebc25d87 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConnectorManager.java @@ -23,6 +23,8 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -165,7 +167,7 @@ private ConnectorInstance createConfiguredConnectorInstance(PrismObject capabilities = ResourceTypeUtil.getNativeCapabilitiesCollection(resourceType); connector.initialize(resourceSchema, capabilities, ResourceTypeUtil.isCaseIgnoreAttributeNames(resourceType), result); @@ -416,12 +418,10 @@ public Set discoverConnectors(ConnectorHostType hostType, Operati } private boolean isInRepo(ConnectorType connectorType, OperationResult result) throws SchemaException { - AndFilter filter = AndFilter.createAnd( - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_FRAMEWORK, ConnectorType.class, prismContext, null, connectorType.getFramework()), - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE, ConnectorType.class, prismContext, null, connectorType.getConnectorType())); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(ConnectorType.class, prismContext) + .item(SchemaConstants.C_CONNECTOR_FRAMEWORK).eq(connectorType.getFramework()) + .and().item(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE).eq(connectorType.getConnectorType()) + .build(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Looking for connector in repository:\n{}", query.debugDump()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java index 951cb091bc3..cacd6e83fbd 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java @@ -28,6 +28,7 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrFilter; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.provisioning.api.ConstraintViolationConfirmer; import com.evolveum.midpoint.provisioning.api.ConstraintsCheckingResult; import com.evolveum.midpoint.provisioning.api.ProvisioningService; @@ -165,18 +166,17 @@ private boolean checkAttributeUniqueness(PrismProperty identifier, RefinedObject throw new SchemaException("Empty identifier "+identifier+" while checking uniqueness of "+oid+" ("+resourceType+")"); } - OrFilter isNotDead = OrFilter.createOr( - EqualFilter.createEqual(ShadowType.F_DEAD, ShadowType.class, prismContext, false), - EqualFilter.createEqual(ShadowType.F_DEAD, ShadowType.class, prismContext, null)); //TODO: set matching rule instead of null - ObjectQuery query = ObjectQuery.createObjectQuery( - AndFilter.createAnd( - RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, prismContext, resourceType.getOid()), - EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, accountDefinition.getTypeName()), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, identifier.getDefinition().getName()), identifier.getDefinition(), - PrismPropertyValue.cloneCollection(identifierValues)), - isNotDead)); - + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(identifier.getDefinition(), ShadowType.F_ATTRIBUTES, identifier.getDefinition().getName()) + .eq(PrismPropertyValue.cloneCollection(identifierValues)) + .and().item(ShadowType.F_OBJECT_CLASS).eq(accountDefinition.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) + .and().block() + .item(ShadowType.F_DEAD).eq(false) + .or().item(ShadowType.F_DEAD).isNull() + .endBlock() + .build(); boolean unique = checkUniqueness(oid, identifier, query, task, result); return unique; } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java index e8085b42f5e..88629271ae0 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java @@ -21,13 +21,11 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.prism.ModificationType; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; @@ -41,8 +39,6 @@ import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.util.PrismUtil; import com.evolveum.midpoint.provisioning.api.GenericConnectorException; @@ -106,10 +102,10 @@ public void postProcessEntitlementsRead(ProvisioningContext subjectCtx, ResourceType resourceType = subjectCtx.getResource(); LOGGER.trace("Starting postProcessEntitlementRead"); RefinedObjectClassDefinition objectClassDefinition = subjectCtx.getObjectClassDefinition(); - Collection entitlementAssociationDefs = objectClassDefinition.getEntitlementAssociations(); + Collection entitlementAssociationDefs = objectClassDefinition.getEntitlementAssociationDefinitions(); if (entitlementAssociationDefs != null) { ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(resourceObject); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); PrismContainerDefinition associationDef = resourceObject.getDefinition().findContainerDefinition(ShadowType.F_ASSOCIATION); PrismContainer associationContainer = associationDef.instantiate(); @@ -313,15 +309,12 @@ private ObjectQuery createQuery(RefinedAssociationDefinition assocDefTyp MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(assocDefType.getResourceObjectAssociationType().getMatchingRule(), assocAttrDef.getTypeName()); PrismPropertyValue converted = PrismUtil.convertPropertyValue(valueAttr.getValue(0), valueAttr.getDefinition(), assocAttrDef); - PrismPropertyValue normalized = converted; - if (matchingRule != null) { - TA normalizedRealValue = matchingRule.normalize(converted.getValue()); - normalized = new PrismPropertyValue(normalizedRealValue); - } - LOGGER.trace("Converted entitlement filter: {} ({}) def={}", - new Object[]{normalized, normalized.getValue().getClass(), assocAttrDef}); - ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, assocAttrDef.getName()), assocAttrDef, normalized); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + TA normalizedRealValue = matchingRule.normalize(converted.getValue()); + PrismPropertyValue normalized = new PrismPropertyValue(normalizedRealValue); + LOGGER.trace("Converted entitlement filter: {} ({}) def={}", normalized, normalized.getValue().getClass(), assocAttrDef); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(new ItemPath(ShadowType.F_ATTRIBUTES, assocAttrDef.getName()), assocAttrDef).eq(normalized) + .build(); query.setAllowPartialResults(true); return query; } @@ -400,14 +393,14 @@ public void collectEntitlementsAsObjectOperationDelete(ProvisioningContext s PrismObject subjectShadow, OperationResult parentResult) throws SchemaException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException { - Collection entitlementAssociationDefs = subjectCtx.getObjectClassDefinition().getEntitlementAssociations(); + Collection entitlementAssociationDefs = subjectCtx.getObjectClassDefinition().getEntitlementAssociationDefinitions(); if (entitlementAssociationDefs == null || entitlementAssociationDefs.isEmpty()) { // Nothing to do LOGGER.trace("No associations in deleted shadow"); return; } ResourceAttributeContainer subjectAttributesContainer = ShadowUtil.getAttributesContainer(subjectShadow); - for (final RefinedAssociationDefinition assocDefType: subjectCtx.getObjectClassDefinition().getEntitlementAssociations()) { + for (final RefinedAssociationDefinition assocDefType: subjectCtx.getObjectClassDefinition().getEntitlementAssociationDefinitions()) { if (assocDefType.getResourceObjectAssociationType().getDirection() != ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { // We can ignore these. They will die together with the object. No need to explicitly delete them. LOGGER.trace("Ignoring subject-to-object association in deleted shadow"); @@ -552,7 +545,7 @@ private void collectEntitlementToAttrDelta(ProvisioningContext ctx, Map PrismObject collectEntitlementAsObjectOperation(Prov if (associationName == null) { throw new SchemaException("No name in entitlement association "+associationCVal); } - RefinedAssociationDefinition assocDefType = subjectCtx.getObjectClassDefinition().findEntitlementAssociation(associationName); + RefinedAssociationDefinition assocDefType = subjectCtx.getObjectClassDefinition().findEntitlementAssociationDefinition(associationName); if (assocDefType == null) { throw new SchemaException("No entitlement association with name "+assocDefType+" in schema of "+resource); } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java index a20e5d3d68c..019b7fc4244 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java @@ -15,9 +15,7 @@ */ package com.evolveum.midpoint.provisioning.impl; -import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.provisioning.ucf.api.ConnectorInstance; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; @@ -146,7 +144,7 @@ public RefinedObjectClassDefinition getObjectClassDefinition() throws SchemaExce if (origObjectClassDefinition == null) { throw new SchemaException("No object class definition for "+shadowCoordinates.getObjectClass()+" in original resource schema for "+getResource()); } else { - objectClassDefinition = RefinedObjectClassDefinition.parseFromSchema(origObjectClassDefinition, getResource(), getRefinedSchema(), getResource().asPrismObject().getPrismContext(), + objectClassDefinition = RefinedObjectClassDefinitionImpl.parseFromSchema(origObjectClassDefinition, getResource(), getRefinedSchema(), getResource().asPrismObject().getPrismContext(), "objectclass "+origObjectClassDefinition+" in "+getResource()); } } @@ -169,7 +167,7 @@ public CompositeRefinedObjectClassDefinition computeCompositeObjectClassDefiniti } auxiliaryObjectClassDefinitions.add(auxObjectClassDef); } - return new CompositeRefinedObjectClassDefinition(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); + return new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxiliaryObjectClassDefinitions); } public RefinedObjectClassDefinition computeCompositeObjectClassDefinition(PrismObject shadow) diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java index 23f6f84814d..6e18518123b 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java @@ -22,6 +22,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; +import com.evolveum.midpoint.schema.processor.*; import com.evolveum.prism.xml.ns._public.types_3.SchemaDefinitionType; import org.apache.commons.lang.StringUtils; @@ -67,10 +70,6 @@ import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ConnectorTestOperation; import com.evolveum.midpoint.schema.internals.InternalMonitor; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceSchema; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ConnectorTypeUtil; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; @@ -342,8 +341,8 @@ private PrismObject completeResource(PrismObject rep try { // make sure it has parsed resource and refined schema. We are going to cache // it, so we want to cache it with the parsed schemas - RefinedResourceSchema.getResourceSchema(newResource, prismContext); - RefinedResourceSchema.getRefinedSchema(newResource); + RefinedResourceSchemaImpl.getResourceSchema(newResource, prismContext); + RefinedResourceSchemaImpl.getRefinedSchema(newResource); } catch (SchemaException e) { String message = "Schema error while processing schemaHandling section of "+newResource+": "+e.getMessage(); @@ -387,7 +386,7 @@ private void completeSchemaAndCapabilities(PrismObject resource, R if (resourceSchema == null) { // Try to get existing schema from resource. We do not want to override this if it exists // (but we still want to refresh the capabilities, that happens below) - resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); } if (resourceSchema == null || resourceSchema.isEmpty()) { @@ -678,7 +677,7 @@ public void testConnection(PrismObject resource, OperationResult p // Resource does not support schema // If there is a static schema in resource definition this may still be OK try { - schema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + schema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); } catch (SchemaException e) { modifyResourceAvailabilityStatus(resource, AvailabilityStatusType.BROKEN, parentResult); schemaResult.recordFatalError(e); @@ -788,9 +787,9 @@ private void adjustSchemaForSimulatedCapabilities(PrismObject reso .findAttributeDefinition(attributeName); if (attributeDefinition != null) { if (ignore != null && !ignore.booleanValue()) { - attributeDefinition.setIgnored(false); + ((ResourceAttributeDefinitionImpl) attributeDefinition).setIgnored(false); } else { - attributeDefinition.setIgnored(true); + ((ResourceAttributeDefinitionImpl) attributeDefinition).setIgnored(true); } } else { // simulated activation attribute points to something that is not in the schema @@ -925,13 +924,14 @@ public void applyDefinition(ObjectDelta delta, ResourceType resour return; } try { - connectorSchema = PrismSchema.parse(connectorSchemaElement, true, "schema for " + connector, prismContext); + connectorSchema = PrismSchemaImpl.parse(connectorSchemaElement, true, "schema for " + connector, prismContext); } catch (SchemaException e) { objectResult.recordFatalError("Error parsing connector schema for " + connector + ": "+e.getMessage(), e); return; } QName configContainerQName = new QName(connectorType.getNamespace(), ResourceType.F_CONNECTOR_CONFIGURATION.getLocalPart()); - PrismContainerDefinition configContainerDef = connectorSchema.findContainerDefinitionByElementName(configContainerQName); + PrismContainerDefinition configContainerDef = + connectorSchema.findContainerDefinitionByElementName(configContainerQName); if (configContainerDef == null) { objectResult.recordFatalError("Definition of configuration container " + configContainerQName + " not found in the schema of of " + connector); return; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java index 0efba76cf1a..301ab38865e 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java @@ -17,10 +17,7 @@ package com.evolveum.midpoint.provisioning.impl; import com.evolveum.midpoint.common.Clock; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; @@ -29,9 +26,8 @@ import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.JavaTypeConverter; import com.evolveum.midpoint.prism.util.PrismUtil; import com.evolveum.midpoint.provisioning.api.GenericConnectorException; @@ -173,14 +169,13 @@ public PrismObject locateResourceObject(ProvisioningContext ctx, if (secondaryIdentifierValues.size() > 1) { throw new IllegalStateException("Secondary identifier has more than one value: " + secondaryIdentifier.getValues()); } else if (secondaryIdentifierValues.size() == 1) { - secondaryIdentifierValue = secondaryIdentifierValues.get(0); + secondaryIdentifierValue = secondaryIdentifierValues.get(0).clone(); } else { secondaryIdentifierValue = null; } - ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, secondaryIdentifierDef.getName()), - secondaryIdentifierDef, secondaryIdentifierValue.clone()); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); -// query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(secondaryIdentifierDef, ShadowType.F_ATTRIBUTES, secondaryIdentifierDef.getName()).eq(secondaryIdentifierValue) + .build(); final Holder> shadowHolder = new Holder>(); ResultHandler handler = new ResultHandler() { @Override @@ -953,7 +948,7 @@ private PrismObject executeEntitlementChangesModify(ProvisioningCont if (associationName == null) { throw new IllegalStateException("No association name in " + associationValue); } - RefinedAssociationDefinition associationDefinition = ctx.getObjectClassDefinition().findAssociation(associationName); + RefinedAssociationDefinition associationDefinition = ctx.getObjectClassDefinition().findAssociationDefinition(associationName); if (associationDefinition == null) { throw new IllegalStateException("No association definition for " + associationValue); } @@ -2127,7 +2122,7 @@ private String getLockoutLockedValue(ActivationLockoutStatusCapabilityType capAc private RefinedObjectClassDefinition determineObjectClassDefinition(PrismObject shadow, ResourceType resource) throws SchemaException, ConfigurationException { ShadowType shadowType = shadow.asObjectable(); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, prismContext); if (refinedSchema == null) { throw new ConfigurationException("No schema definied for "+resource); } @@ -2157,7 +2152,7 @@ private RefinedObjectClassDefinition determineObjectClassDefinition(PrismObject< private ObjectClassComplexTypeDefinition determineObjectClassDefinition( ResourceShadowDiscriminator discriminator, ResourceType resource) throws SchemaException { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); // HACK FIXME ObjectClassComplexTypeDefinition objectClassDefinition = schema.findObjectClassDefinition(ShadowKindType.ACCOUNT, discriminator.getIntent()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 89e10e54fe9..f8b7e1382e4 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -15,63 +15,20 @@ */ package com.evolveum.midpoint.provisioning.impl; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.xml.datatype.XMLGregorianCalendar; -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.schema.util.ObjectQueryUtil; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.Validate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; - import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.ShadowDiscriminatorObjectDelta; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.Visitable; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.Visitor; -import com.evolveum.midpoint.prism.delta.ChangeType; -import com.evolveum.midpoint.prism.delta.ContainerDelta; -import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.delta.PropertyDelta; +import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.NameItemPathSegment; -import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.NaryLogicalFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectPaging; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.OrFilter; -import com.evolveum.midpoint.prism.query.RefFilter; -import com.evolveum.midpoint.prism.query.SubstringFilter; -import com.evolveum.midpoint.prism.query.ValueFilter; +import com.evolveum.midpoint.prism.query.*; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; -import com.evolveum.midpoint.provisioning.api.ChangeNotificationDispatcher; -import com.evolveum.midpoint.provisioning.api.GenericConnectorException; -import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; -import com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription; -import com.evolveum.midpoint.provisioning.api.ResourceOperationDescription; +import com.evolveum.midpoint.provisioning.api.*; import com.evolveum.midpoint.provisioning.consistency.api.ErrorHandler; import com.evolveum.midpoint.provisioning.consistency.api.ErrorHandler.FailedOperation; import com.evolveum.midpoint.provisioning.consistency.impl.ErrorHandlerFactory; @@ -81,22 +38,14 @@ import com.evolveum.midpoint.provisioning.ucf.api.ResultHandler; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.repo.api.RepositoryService; -import com.evolveum.midpoint.schema.DeltaConvertor; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.RetrieveOption; -import com.evolveum.midpoint.schema.SearchResultMetadata; -import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.internals.InternalsConfig; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; +import com.evolveum.midpoint.schema.processor.*; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; +import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.schema.util.SchemaDebugUtil; import com.evolveum.midpoint.schema.util.ShadowUtil; @@ -105,32 +54,24 @@ import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.Holder; import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.exception.TunnelException; +import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationProvisioningScriptsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsSimulateType; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; /** * Shadow cache is a facade that covers all the operations with shadows. It @@ -157,7 +98,7 @@ public abstract class ShadowCache { @Autowired(required = true) private ResourceManager resourceManager; - + @Autowired(required = true) private Clock clock; @@ -237,7 +178,7 @@ public PrismObject getShadow(String oid, PrismObject rep parentResult.recordFatalError("Provided OID is not equal to OID of repository shadow"); throw new IllegalArgumentException("Provided OID is not equal to OID of repository shadow"); } - + if (canReturnCached(options, repositoryShadow)) { applyDefinition(repositoryShadow, parentResult); return repositoryShadow; @@ -456,7 +397,7 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr applyAttributesDefinition(ctx, shadow); shadowManager.setKindIfNecessary(shadow.asObjectable(), ctx.getObjectClassDefinition()); accessChecker.checkAdd(ctx, shadow, parentResult); - + // RESOURCE OPERATION: add shadow = resouceObjectConverter.addResourceObject(ctx, shadow, scripts, parentResult); @@ -724,26 +665,23 @@ private void applyDefinition(final ProvisioningContext ctx, final ObjectQuery qu } final RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); final ItemPath attributesPath = new ItemPath(ShadowType.F_ATTRIBUTES); - com.evolveum.midpoint.prism.query.Visitor visitor = new com.evolveum.midpoint.prism.query.Visitor() { - @Override - public void visit(ObjectFilter filter) { - if (filter instanceof ValueFilter) { - ValueFilter valueFilter = (ValueFilter) filter; - ItemDefinition definition = valueFilter.getDefinition(); - if (definition == null) { - ItemPath itemPath = valueFilter.getFullPath(); - if (attributesPath.equivalent(valueFilter.getParentPath())) { - QName attributeName = valueFilter.getElementName(); - ResourceAttributeDefinition attributeDefinition = objectClassDefinition - .findAttributeDefinition(attributeName); - if (attributeDefinition == null) { - throw new TunnelException(new SchemaException("No definition for attribute " - + attributeName + " in query " + query)); - } - valueFilter.setDefinition(attributeDefinition); - } - } + com.evolveum.midpoint.prism.query.Visitor visitor = subfilter -> { + if (subfilter instanceof PropertyValueFilter) { + PropertyValueFilter valueFilter = (PropertyValueFilter) subfilter; + ItemDefinition definition = valueFilter.getDefinition(); + if (definition instanceof ResourceAttributeDefinition) { + return; // already has a resource-related definition + } + if (!attributesPath.equivalent(valueFilter.getParentPath())) { + return; + } + QName attributeName = valueFilter.getElementName(); + ResourceAttributeDefinition attributeDefinition = objectClassDefinition.findAttributeDefinition(attributeName); + if (attributeDefinition == null) { + throw new TunnelException(new SchemaException("No definition for attribute " + + attributeName + " in query " + query)); } + valueFilter.setDefinition(attributeDefinition); } }; try { @@ -980,7 +918,7 @@ private List createAttributeQueryInternal(List createAttributeQueryInternal(List completeShadow(ProvisioningContext ctx, ShadowAssociationType shadowAssociationType = associationCVal.asContainerable(); QName associationName = shadowAssociationType.getName(); RefinedAssociationDefinition rEntitlementAssociation = ctx.getObjectClassDefinition() - .findEntitlementAssociation(associationName); + .findEntitlementAssociationDefinition(associationName); if (rEntitlementAssociation == null) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Entitlement association with name {} couldn't be found in {} {}\nresource shadow:\n{}\nrepo shadow:\n{}", diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index f774602a910..3fe748c4977 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -24,10 +24,11 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; +import com.evolveum.midpoint.prism.query.builder.S_FilterEntry; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingStategyType; - +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -53,12 +54,9 @@ import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.OrFilter; -import com.evolveum.midpoint.prism.query.RefFilter; import com.evolveum.midpoint.prism.query.Visitor; import com.evolveum.midpoint.provisioning.api.ResourceOperationDescription; import com.evolveum.midpoint.provisioning.ucf.api.Change; @@ -86,10 +84,6 @@ import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectAssociationDirectionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; /** @@ -112,16 +106,16 @@ public class ShadowManager { @Autowired(required = true) @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; - + @Autowired(required = true) private Clock clock; - + @Autowired(required = true) private PrismContext prismContext; - + @Autowired(required = true) private TaskManager taskManager; - + @Autowired(required = true) private MatchingRuleRegistry matchingRuleRegistry; @@ -326,25 +320,20 @@ private List> lookupShadowsBySecondaryIdentifiers( LOGGER.trace("Shadow does not contain secondary identifier. Skipping lookup shadows according to name."); return null; } - - List secondaryEquals = new ArrayList<>(); + + S_FilterEntry q = QueryBuilder.queryFor(ShadowType.class, prismContext) + .block(); for (ResourceAttribute secondaryIdentifier : secondaryIdentifiers) { // There may be identifiers that come from associations and they will have parent set to association/identifiers // For the search to succeed we need all attribute to have "attributes" parent path. secondaryIdentifier = ShadowUtil.fixAttributePath(secondaryIdentifier); - secondaryEquals.add(createAttributeEqualFilter(ctx, secondaryIdentifier)); - } - - ObjectFilter secondaryIdentifierFilter = null; - if (secondaryEquals.size() > 1){ - secondaryIdentifierFilter = OrFilter.createOr((List) secondaryEquals); - } else { - secondaryIdentifierFilter = secondaryEquals.iterator().next(); + q = q.item(secondaryIdentifier.getPath(), secondaryIdentifier.getDefinition()) + .eq(getNormalizedValue(secondaryIdentifier, ctx.getObjectClassDefinition())) + .or(); } - - AndFilter filter = AndFilter.createAnd( - RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, ctx.getResource()), secondaryIdentifierFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = q.none().endBlock() + .and().item(ShadowType.F_RESOURCE_REF).ref(ctx.getResourceOid()) + .build(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Searching for shadow using filter on secondary identifier:\n{}", query.debugDump()); @@ -367,10 +356,12 @@ private void checkConsistency(PrismObject shadow) { ProvisioningUtil.checkShadowActivationConsistency(shadow); } - private EqualFilter createAttributeEqualFilter(ProvisioningContext ctx, + private ObjectFilter createAttributeEqualFilter(ProvisioningContext ctx, ResourceAttribute secondaryIdentifier) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { - return EqualFilter.createEqual(secondaryIdentifier.getPath(), secondaryIdentifier.getDefinition(), - null, getNormalizedValue(secondaryIdentifier, ctx.getObjectClassDefinition())); + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(secondaryIdentifier.getPath(), secondaryIdentifier.getDefinition()) + .eq(getNormalizedValue(secondaryIdentifier, ctx.getObjectClassDefinition())) + .buildFilter(); } private List> getNormalizedValue(PrismProperty attr, RefinedObjectClassDefinition rObjClassDef) throws SchemaException { @@ -379,14 +370,10 @@ private List> getNormalizedValue(PrismProperty attr MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(matchingRuleQName, refinedAttributeDefinition.getTypeName()); List> normalized = new ArrayList<>(); for (PrismPropertyValue origPValue : attr.getValues()){ - if (matchingRule != null) { - T normalizedValue = matchingRule.normalize(origPValue.getValue()); - PrismPropertyValue normalizedPValue = origPValue.clone(); - normalizedPValue.setValue(normalizedValue); - normalized.add(normalizedPValue); - } else { - normalized.add(origPValue); - } + T normalizedValue = matchingRule.normalize(origPValue.getValue()); + PrismPropertyValue normalizedPValue = origPValue.clone(); + normalizedPValue.setValue(normalizedValue); + normalized.add(normalizedPValue); } return normalized; @@ -553,7 +540,7 @@ public PrismObject findOrAddShadowFromChangeGlobalContext(Provisioni return newShadow; } - private PrismObject createNewAccountFromChange(ProvisioningContext ctx, Change change, + private PrismObject createNewAccountFromChange(ProvisioningContext ctx, Change change, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException { @@ -606,7 +593,9 @@ private List> searchShadowByIdenifiers(ProvisioningConte private ObjectQuery createSearchShadowQuery(ProvisioningContext ctx, Collection> identifiers, boolean primaryIdentifiersOnly, PrismContext prismContext, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { - List conditions = new ArrayList(); + + S_AtomicFilterEntry q = QueryBuilder.queryFor(ShadowType.class, prismContext); + RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); for (PrismProperty identifier : identifiers) { RefinedAttributeDefinition rAttrDef; @@ -628,41 +617,23 @@ private ObjectQuery createSearchShadowQuery(ProvisioningContext ctx, Collection< } String normalizedIdentifierValue = (String) getNormalizedAttributeValue(identifierValue, rAttrDef); - //new ItemPath(ShadowType.F_ATTRIBUTES) PrismPropertyDefinition def = (PrismPropertyDefinition) identifier.getDefinition(); - EqualFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, def.getName()), - def, new PrismPropertyValue(normalizedIdentifierValue)); - conditions.add(filter); + q = q.itemWithDef(def, ShadowType.F_ATTRIBUTES, def.getName()).eq(normalizedIdentifierValue).and(); } - if (conditions.size() < 1) { + if (identifiers.size() < 1) { throw new SchemaException("Identifier not specified. Cannot create search query by identifier."); } - - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, ctx.getResource()); - conditions.add(resourceRefFilter); - - if (objectClassDefinition != null) { - EqualFilter objectClassFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, - prismContext, objectClassDefinition.getTypeName()); - conditions.add(objectClassFilter); - } - ObjectFilter filter = null; - if (conditions.size() > 1) { - filter = AndFilter.createAnd(conditions); - } else { - filter = conditions.get(0); + if (objectClassDefinition != null) { + q = q.item(ShadowType.F_OBJECT_CLASS).eq(objectClassDefinition.getTypeName()).and(); } - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - return query; + return q.item(ShadowType.F_RESOURCE_REF).ref(ctx.getResourceOid()).build(); } private ObjectQuery createSearchShadowQuery(ProvisioningContext ctx, PrismObject resourceShadow, PrismContext prismContext, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException { - ResourceAttributeContainer attributesContainer = ShadowUtil - .getAttributesContainer(resourceShadow); + ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(resourceShadow); PrismProperty identifier = attributesContainer.getPrimaryIdentifier(); Collection> idValues = identifier.getValues(); @@ -677,21 +648,17 @@ private ObjectQuery createSearchShadowQuery(ProvisioningContext ctx, PrismObject } // We have all the data, we can construct the filter now - ObjectFilter filter = null; try { // TODO TODO TODO TODO: set matching rule instead of null PrismPropertyDefinition def = identifier.getDefinition(); - filter = AndFilter.createAnd( - EqualFilter.createEqual(new ItemPath(ShadowType.F_OBJECT_CLASS), resourceShadow.findProperty(ShadowType.F_OBJECT_CLASS)), - RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, ctx.getResource()), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, def.getName()), def, getNormalizedValue(identifier, ctx.getObjectClassDefinition()))); + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(def, ShadowType.F_ATTRIBUTES, def.getName()).eq(getNormalizedValue(identifier, ctx.getObjectClassDefinition())) + .and().item(ShadowType.F_OBJECT_CLASS).eq(resourceShadow.getPropertyRealValue(ShadowType.F_OBJECT_CLASS, QName.class)) + .and().item(ShadowType.F_RESOURCE_REF).ref(ctx.getResourceOid()) + .build(); } catch (SchemaException e) { throw new SchemaException("Schema error while creating search filter: " + e.getMessage(), e); } - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - return query; } public SearchResultMetadata searchObjectsIterativeRepository( @@ -742,10 +709,6 @@ private void processQueryMatchingRuleFilter(ObjectFilter filter, RefinedObje return; } MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(matchingRuleQName, rAttrDef.getTypeName()); - if (matchingRule == null) { - // TODO: warning? - return; - } List newValues = new ArrayList(); for (PrismPropertyValue ppval: eqFilter.getValues()) { T normalizedRealValue = matchingRule.normalize(ppval.getValue()); @@ -785,16 +748,16 @@ public PrismObject createRepositoryShadow(ProvisioningContext ctx, P for (PrismProperty p : primaryIdentifiers) { repoAttributesContainer.add(p.clone()); } - + Collection> secondaryIdentifiers = attributesContainer.getSecondaryIdentifiers(); for (PrismProperty p : secondaryIdentifiers) { repoAttributesContainer.add(p.clone()); } - + // Also add all the attributes that act as association identifiers. // We will need them when the shadow is deleted (to remove the shadow from entitlements). RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); - for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociations()) { + for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociationDefinitions()) { if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute(); if (repoAttributesContainer.findAttribute(valueAttributeName) == null) { @@ -805,17 +768,17 @@ public PrismObject createRepositoryShadow(ProvisioningContext ctx, P } } } - + repoShadowType.setCachingMetadata(null); - + ProvisioningUtil.cleanupShadowActivation(repoShadowType); - + } else if (cachingStrategy == CachingStategyType.PASSIVE) { // Do not need to clear anything. Just store all attributes and add metadata. CachingMetadataType cachingMetadata = new CachingMetadataType(); cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar()); repoShadowType.setCachingMetadata(cachingMetadata); - + } else { throw new ConfigurationException("Unknown caching strategy "+cachingStrategy); } @@ -857,13 +820,13 @@ public PrismObject createRepositoryShadow(ProvisioningContext ctx, P } @SuppressWarnings("unchecked") - public Collection updateShadow(ProvisioningContext ctx, PrismObject resourceShadow, + public Collection updateShadow(ProvisioningContext ctx, PrismObject resourceShadow, Collection aprioriDeltas, OperationResult result) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { PrismObject repoShadow = repositoryService.getObject(ShadowType.class, resourceShadow.getOid(), null, result); RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); Collection repoShadowChanges = new ArrayList(); CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx); - + for (RefinedAttributeDefinition attrDef: objectClassDefinition.getAttributeDefinitions()) { if (ProvisioningUtil.shouldStoreAtributeInShadow(objectClassDefinition, attrDef.getName(), cachingStrategy)) { ResourceAttribute resourceAttr = ShadowUtil.getAttribute(resourceShadow, attrDef.getName()); @@ -885,9 +848,9 @@ public Collection updateShadow(ProvisioningContext ctx, PrismObject updateShadow(ProvisioningContext ctx, PrismObject updateShadow(ProvisioningContext ctx, PrismObject currentResourceShadow, + public PrismObject updateShadow(ProvisioningContext ctx, PrismObject currentResourceShadow, PrismObject oldRepoShadow, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, CommunicationException { RefinedObjectClassDefinition ocDef = ctx.computeCompositeObjectClassDefinition(currentResourceShadow); ObjectDelta shadowDelta = oldRepoShadow.createModifyDelta(); PrismContainer currentResourceAttributesContainer = currentResourceShadow.findContainer(ShadowType.F_ATTRIBUTES); PrismContainer oldRepoAttributesContainer = oldRepoShadow.findContainer(ShadowType.F_ATTRIBUTES); - + CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx); - + for (Item currentResourceItem: currentResourceAttributesContainer.getValue().getItems()) { if (currentResourceItem instanceof PrismProperty) { PrismProperty currentResourceAttrProperty = (PrismProperty)currentResourceItem; @@ -958,8 +921,8 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject } } PropertyDelta attrDiff = oldRepoAttributeProperty.diff(normalizedCurrentResourceAttrProperty); - LOGGER.trace("DIFF:\n{}\n-\n{}\n=:\n{}", - oldRepoAttributeProperty==null?null:oldRepoAttributeProperty.debugDump(1), + LOGGER.trace("DIFF:\n{}\n-\n{}\n=:\n{}", + oldRepoAttributeProperty==null?null:oldRepoAttributeProperty.debugDump(1), normalizedCurrentResourceAttrProperty==null?null:normalizedCurrentResourceAttrProperty.debugDump(1), attrDiff==null?null:attrDiff.debugDump(1)); if (attrDiff != null && !attrDiff.isEmpty()) { @@ -1006,22 +969,22 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject if (oldRepoShadow.asObjectable().getCachingMetadata() != null) { shadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA); } - + } else if (cachingStrategy == CachingStategyType.PASSIVE) { - + compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, currentResourceShadow, oldRepoShadow); compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_FROM, currentResourceShadow, oldRepoShadow); compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_TO, currentResourceShadow, oldRepoShadow); compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS, currentResourceShadow, oldRepoShadow); - + CachingMetadataType cachingMetadata = new CachingMetadataType(); cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar()); shadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA, cachingMetadata); - + } else { throw new ConfigurationException("Unknown caching strategy "+cachingStrategy); } - + if (!shadowDelta.isEmpty()) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Updating repo shadow {} with delta:\n{}", oldRepoShadow, shadowDelta.debugDump(1)); @@ -1033,7 +996,7 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject // This should not happen for shadows throw new SystemException(e.getMessage(), e); } - + PrismObject newRepoShadow = oldRepoShadow.clone(); shadowDelta.applyTo(newRepoShadow); return newRepoShadow; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java index dc93e145eca..e866f61fc5d 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java @@ -39,6 +39,7 @@ import javax.net.ssl.TrustManager; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringUtils; import org.identityconnectors.common.Version; @@ -279,7 +280,7 @@ private PrismSchema getConnectorSchema(ConnectorType connectorType, String names if (xsdElement == null) { return null; } - PrismSchema connectorSchema = PrismSchema.parse(xsdElement, true, connectorType.toString(), prismContext); + PrismSchema connectorSchema = PrismSchemaImpl.parse(xsdElement, true, connectorType.toString(), prismContext); return connectorSchema; } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java index 790e28bbabb..08bb463b34c 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java @@ -17,15 +17,20 @@ import static com.evolveum.midpoint.provisioning.ucf.impl.IcfUtil.processIcfException; +import java.io.File; +import java.lang.reflect.Array; import java.util.*; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.OrderDirection; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; import com.evolveum.midpoint.provisioning.impl.StateReporter; import com.evolveum.midpoint.schema.SearchResultMetadata; +import com.evolveum.midpoint.schema.processor.*; import com.evolveum.midpoint.schema.statistics.ConnectorOperationalStatus; import com.evolveum.midpoint.schema.statistics.ProvisioningOperation; import com.evolveum.midpoint.util.DebugUtil; @@ -45,6 +50,7 @@ import org.identityconnectors.framework.api.ConnectorFacade; import org.identityconnectors.framework.api.ConnectorFacadeFactory; import org.identityconnectors.framework.api.ConnectorInfo; +import org.identityconnectors.framework.api.ResultsHandlerConfiguration; import org.identityconnectors.framework.api.operations.APIOperation; import org.identityconnectors.framework.api.operations.CreateApiOp; import org.identityconnectors.framework.api.operations.DeleteApiOp; @@ -89,17 +95,7 @@ import org.identityconnectors.framework.spi.Connector; import org.identityconnectors.framework.spi.PoolableConnector; -import com.evolveum.midpoint.prism.ComplexTypeDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -129,14 +125,6 @@ import com.evolveum.midpoint.schema.constants.ConnectorTestOperation; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalMonitor; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceObjectIdentification; -import com.evolveum.midpoint.schema.processor.ResourceSchema; -import com.evolveum.midpoint.schema.processor.SearchHierarchyConstraints; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.ActivationUtil; @@ -359,17 +347,17 @@ public PrismSchema generateConnectorSchema() { return null; } - connectorSchema = new PrismSchema(connectorType.getNamespace(), prismContext); + connectorSchema = new PrismSchemaImpl(connectorType.getNamespace(), prismContext); // Create configuration type - the type used by the "configuration" // element - PrismContainerDefinition configurationContainerDef = connectorSchema.createPropertyContainerDefinition( + PrismContainerDefinitionImpl configurationContainerDef = ((PrismSchemaImpl) connectorSchema).createPropertyContainerDefinition( ResourceType.F_CONNECTOR_CONFIGURATION.getLocalPart(), ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_CONFIGURATION_TYPE_LOCAL_NAME); // element with "ConfigurationPropertiesType" - the dynamic part of // configuration schema - ComplexTypeDefinition configPropertiesTypeDef = connectorSchema.createComplexTypeDefinition(new QName( + ComplexTypeDefinition configPropertiesTypeDef = ((PrismSchemaImpl) connectorSchema).createComplexTypeDefinition(new QName( connectorType.getNamespace(), ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_TYPE_LOCAL_NAME)); @@ -382,7 +370,7 @@ public PrismSchema generateConnectorSchema() { QName propXsdType = icfTypeToXsdType(icfProperty.getType(), icfProperty.isConfidential()); LOGGER.trace("{}: Mapping ICF config schema property {} from {} to {}", new Object[] { this, icfPropertyName, icfProperty.getType(), propXsdType }); - PrismPropertyDefinition propertyDefinifion = configPropertiesTypeDef.createPropertyDefinition( + PrismPropertyDefinitionImpl propertyDefinifion = ((ComplexTypeDefinitionImpl) configPropertiesTypeDef).createPropertyDefinition( icfPropertyName, propXsdType); propertyDefinifion.setDisplayName(icfProperty.getDisplayName(null)); propertyDefinifion.setHelp(icfProperty.getHelpMessage(null)); @@ -709,7 +697,7 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects AttributeInfo auxiliaryObjectClasseAttributeInfo = null; // New instance of midPoint schema object - setResourceSchema(new ResourceSchema(getSchemaNamespace(), prismContext)); + setResourceSchema(new ResourceSchemaImpl(getSchemaNamespace(), prismContext)); if (legacySchema == null) { legacySchema = detectLegacySchema(icfSchema); @@ -734,14 +722,14 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects // object class. // The important thing here is the last "type" parameter // (objectClassXsdName). The rest is more-or-less cosmetics. - ObjectClassComplexTypeDefinition ocDef = resourceSchema + ObjectClassComplexTypeDefinition ocDef = ((ResourceSchemaImpl) resourceSchema) .createObjectClassDefinition(objectClassXsdName); // The __ACCOUNT__ objectclass in ICF is a default account // objectclass. So mark it appropriately. if (ObjectClass.ACCOUNT_NAME.equals(objectClassInfo.getType())) { - ocDef.setKind(ShadowKindType.ACCOUNT); - ocDef.setDefaultInAKind(true); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).setKind(ShadowKindType.ACCOUNT); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).setDefaultInAKind(true); } ResourceAttributeDefinition uidDefinition = null; @@ -808,7 +796,7 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects // Create ResourceObjectAttributeDefinition, which is midPoint // way how to express attribute schema. - ResourceAttributeDefinition attrDef = new ResourceAttributeDefinition( + ResourceAttributeDefinitionImpl attrDef = new ResourceAttributeDefinitionImpl( attrXsdName, attrXsdType, prismContext); attrDef.setMatchingRuleQName(icfAttributeInfoToMatchingRule(attributeInfo)); @@ -834,7 +822,7 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects ResourceAttributeDefinition existingDefinition = ocDef.findAttributeDefinition(attrXsdName); if (existingDefinition != null) { hasUidDefinition = true; - existingDefinition.setDisplayOrder(ConnectorFactoryIcfImpl.ICFS_UID_DISPLAY_ORDER); + ((ResourceAttributeDefinitionImpl) existingDefinition).setDisplayOrder(ConnectorFactoryIcfImpl.ICFS_UID_DISPLAY_ORDER); uidDefinition = existingDefinition; continue; } else { @@ -897,38 +885,37 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects attrDef.setCanRead(canRead); if (!Uid.NAME.equals(icfName)) { - ocDef.add(attrDef); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).add(attrDef); } } if (uidDefinition == null) { // Every object has UID in ICF, therefore add a default definition if no other was specified - uidDefinition = new ResourceAttributeDefinition( + uidDefinition = new ResourceAttributeDefinitionImpl<>( ConnectorFactoryIcfImpl.ICFS_UID, DOMUtil.XSD_STRING, prismContext); // DO NOT make it mandatory. It must not be present on create hence it cannot be mandatory. - uidDefinition.setMinOccurs(0); - uidDefinition.setMaxOccurs(1); + ((ResourceAttributeDefinitionImpl) uidDefinition).setMinOccurs(0); + ((ResourceAttributeDefinitionImpl) uidDefinition).setMaxOccurs(1); // Make it read-only - uidDefinition.setReadOnly(); + ((ResourceAttributeDefinitionImpl) uidDefinition).setReadOnly(); // Set a default display name - uidDefinition.setDisplayName(ConnectorFactoryIcfImpl.ICFS_UID_DISPLAY_NAME); - uidDefinition.setDisplayOrder(ConnectorFactoryIcfImpl.ICFS_UID_DISPLAY_ORDER); + ((ResourceAttributeDefinitionImpl) uidDefinition).setDisplayName(ConnectorFactoryIcfImpl.ICFS_UID_DISPLAY_NAME); + ((ResourceAttributeDefinitionImpl) uidDefinition).setDisplayOrder(ConnectorFactoryIcfImpl.ICFS_UID_DISPLAY_ORDER); // Uid is a primary identifier of every object (this is the ICF way) } if (!hasUidDefinition) { - ocDef.add(uidDefinition); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).add(uidDefinition); } - ((Collection)ocDef.getPrimaryIdentifiers()).add(uidDefinition); + ((ObjectClassComplexTypeDefinitionImpl)ocDef).addPrimaryIdentifier(uidDefinition); if (uidDefinition != nameDefinition) { - ((Collection)ocDef.getSecondaryIdentifiers()).add(nameDefinition); + ((ObjectClassComplexTypeDefinitionImpl)ocDef).addSecondaryIdentifier(nameDefinition); } - // Add schema annotations - ocDef.setNativeObjectClass(objectClassInfo.getType()); - ocDef.setDisplayNameAttribute(nameDefinition.getName()); - ocDef.setNamingAttribute(nameDefinition.getName()); - ocDef.setAuxiliary(objectClassInfo.isAuxiliary()); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).setNativeObjectClass(objectClassInfo.getType()); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).setDisplayNameAttribute(nameDefinition.getName()); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).setNamingAttribute(nameDefinition.getName()); + ((ObjectClassComplexTypeDefinitionImpl) ocDef).setAuxiliary(objectClassInfo.isAuxiliary()); } @@ -2799,7 +2786,7 @@ private void addConvertedValues(Collection> pvals, attributes.add(ab.build()); } - private List getChangesFromSyncDeltas(ObjectClass connIdObjClass, Collection connIdDeltas, + private List getChangesFromSyncDeltas(ObjectClass connIdObjClass, Collection connIdDeltas, PrismSchema schema, OperationResult parentResult) throws SchemaException, GenericFrameworkException { List changeList = new ArrayList(); @@ -2919,7 +2906,7 @@ private PrismProperty createTokenProperty(T object) { Set> syncTokenValues = new HashSet>(); syncTokenValues.add(new PrismPropertyValue(object)); - PrismPropertyDefinition propDef = new PrismPropertyDefinition(SchemaConstants.SYNC_TOKEN, + PrismPropertyDefinitionImpl propDef = new PrismPropertyDefinitionImpl(SchemaConstants.SYNC_TOKEN, type, prismContext); propDef.setDynamic(true); PrismProperty property = propDef.instantiate(); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/query/ValueOperation.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/query/ValueOperation.java index eda8fb312e3..824cd5e1b2f 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/query/ValueOperation.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/query/ValueOperation.java @@ -33,7 +33,6 @@ import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.InFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.SubstringFilter; import com.evolveum.midpoint.prism.query.ValueFilter; @@ -58,7 +57,7 @@ public Filter interpret(ObjectFilter objectFilter, IcfNameMapper icfNameMapp OperationResult parentResult = new OperationResult("interpret"); ValueFilter valueFilter= (ValueFilter) objectFilter; - if (valueFilter.getParentPath() == null || valueFilter.getParentPath().isEmpty()) { + if (valueFilter.getParentPath().isEmpty()) { throw new UnsupportedOperationException("Empty path is not supported (filter: " + objectFilter+")"); } if (valueFilter.getParentPath().equivalent(new ItemPath(ShadowType.F_ATTRIBUTES))) { @@ -83,17 +82,6 @@ public Filter interpret(ObjectFilter objectFilter, IcfNameMapper icfNameMapp } } - } else if (objectFilter instanceof InFilter) { - InFilter in = (InFilter) objectFilter; - - Collection convertedValues = convertValues(propName, (List) in.getValues()); - if (convertedValues.isEmpty()) { - throw new IllegalArgumentException("In filter with a null value makes no sense"); - } else { - Attribute attr = AttributeBuilder.build(icfName, convertedValues); - return FilterBuilder.equalTo(attr); - } - } else if (objectFilter instanceof SubstringFilter) { SubstringFilter substring = (SubstringFilter) objectFilter; Collection convertedValues = convertValues(propName, substring.getValues()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java index b49927c8852..3f4ed9b0639 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java @@ -18,10 +18,7 @@ import com.evolveum.midpoint.common.ResourceObjectPattern; import com.evolveum.midpoint.common.StaticExpressionUtil; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; -import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.*; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.match.MatchingRule; @@ -123,7 +120,7 @@ public static ExecuteProvisioningScriptOperation convertToScriptOperation( ProvisioningScriptType scriptType, String desc, PrismContext prismContext) throws SchemaException { ExecuteProvisioningScriptOperation scriptOperation = new ExecuteProvisioningScriptOperation(); - PrismPropertyDefinition scriptArgumentDefinition = new PrismPropertyDefinition( + PrismPropertyDefinition scriptArgumentDefinition = new PrismPropertyDefinitionImpl( FAKE_SCRIPT_ARGUMENT_NAME, DOMUtil.XSD_STRING, prismContext); for (ProvisioningScriptArgumentType argument : scriptType.getArgument()) { @@ -252,7 +249,7 @@ public static PropertyDelta narrowPropertyDelta(PropertyDelta property } public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType) throws SchemaException, ConfigurationException { - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); if (refinedSchema == null) { throw new ConfigurationException("No schema for "+resourceType); } @@ -283,7 +280,7 @@ public static void setProtectedFlag(ProvisioningContext ctx, PrismObject resource) throws SchemaException, ConfigurationException { - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); if (refinedSchema == null) { throw new ConfigurationException("No schema for "+resource); } @@ -304,13 +301,13 @@ public static void logWarning(Trace logger, OperationResult opResult, String mes opResult.recordWarning(message, ex); } - public static boolean shouldStoreAtributeInShadow(RefinedObjectClassDefinition objectClassDefinition, QName attributeName, + public static boolean shouldStoreAtributeInShadow(RefinedObjectClassDefinition objectClassDefinition, QName attributeName, CachingStategyType cachingStrategy) throws ConfigurationException { if (cachingStrategy == CachingStategyType.NONE) { if (objectClassDefinition.isPrimaryIdentifier(attributeName) || objectClassDefinition.isSecondaryIdentifier(attributeName)) { return true; } - for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociations()) { + for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociationDefinitions()) { if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute(); if (QNameUtil.match(attributeName, valueAttributeName)) { @@ -319,11 +316,11 @@ public static boolean shouldStoreAtributeInShadow(RefinedObjectClassDefinition o } } return false; - + } else if (cachingStrategy == CachingStategyType.PASSIVE) { RefinedAttributeDefinition attrDef = objectClassDefinition.findAttributeDefinition(attributeName); return attrDef != null; - + } else { throw new ConfigurationException("Unknown caching strategy "+cachingStrategy); } @@ -380,8 +377,8 @@ public static void checkShadowActivationConsistency(PrismObject shad //throw new IllegalStateException(m); // use only for testing } } - - public static CachingStategyType getCachingStrategy(ProvisioningContext ctx) + + public static CachingStategyType getCachingStrategy(ProvisioningContext ctx) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException { CachingPolicyType caching = ctx.getResource().getCaching(); if (caching == null) { @@ -392,7 +389,7 @@ public static CachingStategyType getCachingStrategy(ProvisioningContext ctx) } return caching.getCachingStategy(); } - + public static boolean shouldDoRepoSearch(GetOperationOptions rootOptions) { return GetOperationOptions.isNoFetch(rootOptions) || GetOperationOptions.isMaxStaleness(rootOptions); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java index ee95d82fecf..a951fc2aa46 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java @@ -26,6 +26,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; +import org.apache.commons.lang.StringUtils; import org.w3c.dom.Element; import com.evolveum.midpoint.prism.Containerable; @@ -83,7 +85,7 @@ public static void assertConnectorSchemaSanity(ConnectorType conn, PrismContext // Try to parse the schema PrismSchema schema = null; try { - schema = PrismSchema.parse(xsdElement, true, "schema of "+conn, prismContext); + schema = PrismSchemaImpl.parse(xsdElement, true, "schema of "+conn, prismContext); } catch (SchemaException e) { throw new SchemaException("Error parsing schema of "+conn+": "+e.getMessage(),e); } @@ -126,7 +128,7 @@ public static void checkRepoEntitlementShadow(PrismObject repoShadow public static void checkRepoShadow(PrismObject repoShadow, ShadowKindType kind) { checkRepoShadow(repoShadow, kind, 2); } - + public static void checkRepoShadow(PrismObject repoShadow, ShadowKindType kind, Integer expectedNumberOfAttributes) { ShadowType repoShadowType = repoShadow.asObjectable(); assertNotNull("No OID in repo shadow "+repoShadow, repoShadowType.getOid()); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorDiscovery.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorDiscovery.java index eb2c5679b0e..870bde5b53c 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorDiscovery.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorDiscovery.java @@ -22,6 +22,7 @@ import java.util.List; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -133,13 +134,12 @@ public void testSearchConnectorAnd() throws SchemaException{ TestUtil.displayTestTile("testSearchConnectorAnd"); OperationResult result = new OperationResult(TestConnectorDiscovery.class.getName() + ".testSearchConnector"); - - Document doc = DOMUtil.getDocument(); - AndFilter filter = AndFilter.createAnd( - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_FRAMEWORK, ConnectorType.class, prismContext, null, ConnectorFactoryIcfImpl.ICF_FRAMEWORK_URI), - EqualFilter.createEqual(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE, ConnectorType.class, prismContext, null, LDAP_CONNECTOR_TYPE)); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + + ObjectQuery query = QueryBuilder.queryFor(ConnectorType.class, prismContext) + .item(SchemaConstants.C_CONNECTOR_FRAMEWORK).eq(ConnectorFactoryIcfImpl.ICF_FRAMEWORK_URI) + .and().item(SchemaConstants.C_CONNECTOR_CONNECTOR_TYPE).eq(LDAP_CONNECTOR_TYPE) + .build(); + System.out.println("Query:\n"+query.debugDump()); List> connectors = repositoryService.searchObjects(ConnectorType.class, query, null, result); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestCsvFile.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestCsvFile.java index 6c4e5a7f78e..54446f823d8 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestCsvFile.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestCsvFile.java @@ -31,6 +31,8 @@ import javax.xml.bind.JAXBElement; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @@ -199,7 +201,7 @@ public void test003Connection() throws ObjectNotFoundException, SchemaException assertNotNull("No serialNumber", cachingMetadata.getSerialNumber()); Element xsdElement = ObjectTypeUtil.findXsdElement(xmlSchemaTypeAfter); - ResourceSchema parsedSchema = ResourceSchema.parse(xsdElement, resourceBefore.toString(), prismContext); + ResourceSchema parsedSchema = ResourceSchemaImpl.parse(xsdElement, resourceBefore.toString(), prismContext); assertNotNull("No schema after parsing", parsedSchema); // schema will be checked in next test @@ -237,17 +239,17 @@ public void test005ParsedSchema() throws ObjectNotFoundException, CommunicationE // THEN // The returned type should have the schema pre-parsed - assertNotNull(RefinedResourceSchema.hasParsedSchema(resourceType)); + assertNotNull(RefinedResourceSchemaImpl.hasParsedSchema(resourceType)); // Also test if the utility method returns the same thing - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resourceType, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext); display("Parsed resource schema", returnedSchema); // Check whether it is reusing the existing schema and not parsing it all over again // Not equals() but == ... we want to really know if exactly the same // object instance is returned - assertTrue("Broken caching", returnedSchema == RefinedResourceSchema.getResourceSchema(resourceType, prismContext)); + assertTrue("Broken caching", returnedSchema == RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext)); IntegrationTestTools.assertIcfResourceSchemaSanity(returnedSchema, resourceType); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java index 262040b1c31..1c505083dd1 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.provisioning.impl.dummy; +import static org.testng.AssertJUnit.assertFalse; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; @@ -32,18 +33,24 @@ import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.schema.processor.*; import org.springframework.beans.factory.annotation.Autowired; import org.testng.AssertJUnit; import org.w3c.dom.Element; import com.evolveum.icf.dummy.resource.ConflictException; import com.evolveum.icf.dummy.resource.DummyAccount; +import com.evolveum.icf.dummy.resource.DummyAttributeDefinition; import com.evolveum.icf.dummy.resource.DummyGroup; import com.evolveum.icf.dummy.resource.DummyObject; +import com.evolveum.icf.dummy.resource.DummyObjectClass; import com.evolveum.icf.dummy.resource.DummyPrivilege; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.SchemaViolationException; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.Objectable; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; @@ -62,6 +69,7 @@ import com.evolveum.midpoint.provisioning.impl.mock.SynchornizationServiceMock; import com.evolveum.midpoint.provisioning.ucf.api.ConnectorInstance; import com.evolveum.midpoint.provisioning.ucf.impl.ConnectorFactoryIcfImpl; +import com.evolveum.midpoint.schema.internals.CachingStatistics; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.internals.InternalsConfig; import com.evolveum.midpoint.schema.processor.ResourceSchema; @@ -84,6 +92,8 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.XmlSchemaType; @@ -274,8 +284,9 @@ protected void checkConsistency(PrismObject object) throws LOGGER.info("item definition: {}", itemDef.debugDump()); //TODO: matching rule - EqualFilter equal = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, itemDef.getName()), itemDef, getWillRepoIcfName()); - ObjectQuery query = ObjectQuery.createObjectQuery(equal); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(itemDef, ShadowType.F_ATTRIBUTES, itemDef.getName()).eq(getWillRepoIcfName()) + .build(); System.out.println("Looking for shadows of \"" + getWillRepoIcfName() + "\" with filter " + query.debugDump()); @@ -301,7 +312,7 @@ protected void assertAttribute(PrismObject shadow, QName attrNam protected void assertAttribute(PrismObject shadow, MatchingRule matchingRule, QName attrName, T... expectedValues) throws SchemaException { ProvisioningTestUtil.assertAttribute(resource, shadow.asObjectable(), matchingRule, attrName, expectedValues); } - + protected void assertNoAttribute(PrismObject shadow, String attrName) { ProvisioningTestUtil.assertNoAttribute(resource, shadow.asObjectable(), attrName); } @@ -498,7 +509,7 @@ protected void assertHasSchema(PrismObject resource, String desc) assertNotNull("No serialNumber in "+desc, cachingMetadata.getSerialNumber()); Element xsdElement = ObjectTypeUtil.findXsdElement(xmlSchemaTypeAfter); - ResourceSchema parsedSchema = ResourceSchema.parse(xsdElement, resource.toString(), prismContext); + ResourceSchema parsedSchema = ResourceSchemaImpl.parse(xsdElement, resource.toString(), prismContext); assertNotNull("No schema after parsing in "+desc, parsedSchema); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java index 68b0f9960f4..81297747699 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java @@ -39,9 +39,13 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.query.OrFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; +import com.evolveum.midpoint.schema.processor.*; import org.apache.commons.lang.StringUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -101,11 +105,6 @@ import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceSchema; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.statistics.ConnectorOperationalStatus; @@ -287,7 +286,7 @@ public void test010ListConnectors() throws Exception { assertNotNull("No schema", connectorXsdSchemaElement); // Try to parse the schema - PrismSchema schema = PrismSchema.parse(connectorXsdSchemaElement, true, "connector schema " + conn, prismContext); + PrismSchema schema = PrismSchemaImpl.parse(connectorXsdSchemaElement, true, "connector schema " + conn, prismContext); assertNotNull("Cannot parse schema", schema); assertFalse("Empty schema", schema.isEmpty()); @@ -428,7 +427,7 @@ public void test020Connection() throws Exception { assertNotNull("No serialNumber", cachingMetadata.getSerialNumber()); Element xsdElement = ObjectTypeUtil.findXsdElement(xmlSchemaTypeAfter); - ResourceSchema parsedSchema = ResourceSchema.parse(xsdElement, resourceTypeBefore.toString(), prismContext); + ResourceSchema parsedSchema = ResourceSchemaImpl.parse(xsdElement, resourceTypeBefore.toString(), prismContext); assertNotNull("No schema after parsing", parsedSchema); // schema will be checked in next test @@ -501,10 +500,10 @@ public void test022ParsedSchema() throws Exception { // THEN // The returned type should have the schema pre-parsed - assertNotNull(RefinedResourceSchema.hasParsedSchema(resourceType)); + assertNotNull(RefinedResourceSchemaImpl.hasParsedSchema(resourceType)); // Also test if the utility method returns the same thing - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resourceType, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext); display("Parsed resource schema", returnedSchema); @@ -513,7 +512,7 @@ public void test022ParsedSchema() throws Exception { // Not equals() but == ... we want to really know if exactly the same // object instance is returned assertTrue("Broken caching", - returnedSchema == RefinedResourceSchema.getResourceSchema(resourceType, prismContext)); + returnedSchema == RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext)); assertSchemaSanity(returnedSchema, resourceType); @@ -528,7 +527,7 @@ public void test023RefinedSchema() throws Exception { // GIVEN // WHEN - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceType, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType, prismContext); display("Refined schema", refinedSchema); // Check whether it is reusing the existing schema and not parsing it @@ -536,7 +535,7 @@ public void test023RefinedSchema() throws Exception { // Not equals() but == ... we want to really know if exactly the same // object instance is returned assertTrue("Broken caching", - refinedSchema == RefinedResourceSchema.getRefinedSchema(resourceType, prismContext)); + refinedSchema == RefinedResourceSchemaImpl.getRefinedSchema(resourceType, prismContext)); RefinedObjectClassDefinition accountDef = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); assertNotNull("Account definition is missing", accountDef); @@ -738,7 +737,7 @@ public void test030ResourceAndConnectorCaching() throws Exception { ConnectorInstance configuredConnectorInstance = connectorManager.getConfiguredConnectorInstance( resource, false, result); assertNotNull("No configuredConnectorInstance", configuredConnectorInstance); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); assertNotNull("No resource schema", resourceSchema); // WHEN @@ -760,7 +759,7 @@ public void test030ResourceAndConnectorCaching() throws Exception { assertTrue("Configurations not equivalent", configurationContainer.equivalent(configurationContainerAgain)); // Check resource schema caching - ResourceSchema resourceSchemaAgain = RefinedResourceSchema.getResourceSchema(resourceAgain, prismContext); + ResourceSchema resourceSchemaAgain = RefinedResourceSchemaImpl.getResourceSchema(resourceAgain, prismContext); assertNotNull("No resource schema (again)", resourceSchemaAgain); assertTrue("Resource schema was not cached", resourceSchema == resourceSchemaAgain); @@ -818,7 +817,7 @@ public void test031ResourceAndConnectorCachingForceFresh() throws Exception { ConnectorInstance configuredConnectorInstance = connectorManager.getConfiguredConnectorInstance( resource, false, result); assertNotNull("No configuredConnectorInstance", configuredConnectorInstance); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); assertNotNull("No resource schema", resourceSchema); // WHEN @@ -839,7 +838,7 @@ public void test031ResourceAndConnectorCachingForceFresh() throws Exception { .findContainer(ResourceType.F_CONNECTOR_CONFIGURATION); assertTrue("Configurations not equivalent", configurationContainer.equivalent(configurationContainerAgain)); - ResourceSchema resourceSchemaAgain = RefinedResourceSchema.getResourceSchema(resourceAgain, prismContext); + ResourceSchema resourceSchemaAgain = RefinedResourceSchemaImpl.getResourceSchema(resourceAgain, prismContext); assertNotNull("No resource schema (again)", resourceSchemaAgain); assertTrue("Resource schema was not cached", resourceSchema == resourceSchemaAgain); @@ -2574,8 +2573,10 @@ public void test151SearchDisabledAccounts() throws Exception { OperationResult result = task.getResult(); ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID, ProvisioningTestUtil.getDefaultAccountObjectClass(resourceType), prismContext); - ObjectQueryUtil.filterAnd(query.getFilter(), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS), getShadowDefinition(), ActivationStatusType.DISABLED)); + ObjectQueryUtil.filterAnd(query.getFilter(), + QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.DISABLED) + .buildFilter()); syncServiceMock.reset(); @@ -2696,9 +2697,11 @@ public void test155SearchDisabledAccounts() throws Exception { OperationResult result = task.getResult(); ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID, ProvisioningTestUtil.getDefaultAccountObjectClass(resourceType), prismContext); - ObjectQueryUtil.filterAnd(query.getFilter(), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS), getShadowDefinition(), ActivationStatusType.DISABLED)); - + ObjectQueryUtil.filterAnd(query.getFilter(), + QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.DISABLED) + .buildFilter()); + syncServiceMock.reset(); // WHEN @@ -2915,8 +2918,10 @@ public void test160SearchLockedAccounts() throws Exception { OperationResult result = task.getResult(); ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID, ProvisioningTestUtil.getDefaultAccountObjectClass(resourceType), prismContext); - ObjectQueryUtil.filterAnd(query.getFilter(), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS), getShadowDefinition(), LockoutStatusType.LOCKED)); + ObjectQueryUtil.filterAnd(query.getFilter(), + QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).eq(LockoutStatusType.LOCKED) + .buildFilter()); syncServiceMock.reset(); @@ -3033,8 +3038,10 @@ public void test163SearchLockedAccounts() throws Exception { OperationResult result = task.getResult(); ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID, ProvisioningTestUtil.getDefaultAccountObjectClass(resourceType), prismContext); - ObjectQueryUtil.filterAnd(query.getFilter(), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS), getShadowDefinition(), LockoutStatusType.LOCKED)); + ObjectQueryUtil.filterAnd(query.getFilter(), + QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).eq(LockoutStatusType.LOCKED) + .buildFilter()); syncServiceMock.reset(); @@ -3254,23 +3261,18 @@ public boolean handle(PrismObject object, OperationResult parentResu } private ObjectQuery createOnOffQuery() throws SchemaException { - ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID, new QName(ResourceTypeUtil.getResourceNamespace(resourceType), - ConnectorFactoryIcfImpl.ACCOUNT_OBJECT_CLASS_LOCAL_NAME), prismContext); - - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition objectClassDef = resourceSchema.findObjectClassDefinition(SchemaTestConstants.ACCOUNT_OBJECT_CLASS_LOCAL_NAME); - ResourceAttributeDefinition attrDef = objectClassDef.findAttributeDefinition( dummyResourceCtl.getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); - ObjectFilter attrFilter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName()), attrDef, - "Sea Monkey"); - - ObjectFilter deadFilter = EqualFilter.createEqual(ShadowType.F_DEAD, ShadowType.class, prismContext, Boolean.TRUE); - - ObjectFilter filter = AndFilter.createAnd(query.getFilter(), attrFilter, deadFilter); - query.setFilter(filter); - display("Query", query); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_RESOURCE_REF).ref(RESOURCE_DUMMY_OID) + .and().item(ShadowType.F_OBJECT_CLASS).eq(new QName(ResourceTypeUtil.getResourceNamespace(resourceType), ConnectorFactoryIcfImpl.ACCOUNT_OBJECT_CLASS_LOCAL_NAME)) + .and().itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getName()).eq("Sea Monkey") + .and().item(ShadowType.F_DEAD).eq(true) + .build(); + display("Query", query); return query; } @@ -3282,37 +3284,27 @@ protected void testSeachIterativeSingleAttrFilter(final String TEST_NAME, St protected void testSeachIterativeSingleAttrFilter(final String TEST_NAME, QName attrQName, T attrVal, GetOperationOptions rootOptions, boolean fullShadow, String... expectedAccountNames) throws Exception { - PrismPropertyValue attrPVal = null; - if (attrVal != null) { - attrPVal = new PrismPropertyValue(attrVal); - } - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition objectClassDef = resourceSchema.findObjectClassDefinition(SchemaTestConstants.ACCOUNT_OBJECT_CLASS_LOCAL_NAME); ResourceAttributeDefinition attrDef = objectClassDef.findAttributeDefinition(attrQName); - ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName()), attrDef, attrPVal); - + ObjectFilter filter = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(attrDef, ShadowType.F_ATTRIBUTES, attrDef.getName()).eq(attrVal) + .buildFilter(); testSeachIterative(TEST_NAME, filter, rootOptions, fullShadow, true, false, expectedAccountNames); } protected void testSeachIterativeAlternativeAttrFilter(final String TEST_NAME, QName attr1QName, T attr1Val, QName attr2QName, T attr2Val, GetOperationOptions rootOptions, boolean fullShadow, String... expectedAccountNames) throws Exception { - PrismPropertyValue attr1PVal = null; - if (attr1Val != null) { - attr1PVal = new PrismPropertyValue(attr1Val); - } - PrismPropertyValue attr2PVal = null; - if (attr2Val != null) { - attr2PVal = new PrismPropertyValue(attr2Val); - } - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition objectClassDef = resourceSchema.findObjectClassDefinition(SchemaTestConstants.ACCOUNT_OBJECT_CLASS_LOCAL_NAME); ResourceAttributeDefinition attr1Def = objectClassDef.findAttributeDefinition(attr1QName); - ObjectFilter filter1 = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, attr1Def.getName()), attr1Def, attr1PVal); ResourceAttributeDefinition attr2Def = objectClassDef.findAttributeDefinition(attr2QName); - ObjectFilter filter2 = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, attr2Def.getName()), attr2Def, attr2PVal); - - testSeachIterative(TEST_NAME, OrFilter.createOr(filter1, filter2), rootOptions, fullShadow, false, true, expectedAccountNames); + ObjectFilter filter = QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(attr1Def, ShadowType.F_ATTRIBUTES, attr1Def.getName()).eq(attr1Val) + .or().itemWithDef(attr2Def, ShadowType.F_ATTRIBUTES, attr2Def.getName()).eq(attr2Val) + .buildFilter(); + testSeachIterative(TEST_NAME, filter, rootOptions, fullShadow, false, true, expectedAccountNames); } @@ -4607,7 +4599,7 @@ public void test502ModifyProtectedAccountShadowAttributes() throws Exception { syncServiceMock.reset(); Collection modifications = new ArrayList(1); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition defaultAccountDefinition = resourceSchema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT); ResourceAttributeDefinition fullnameAttrDef = defaultAccountDefinition.findAttributeDefinition("fullname"); ResourceAttribute fullnameAttr = fullnameAttrDef.instantiate(); @@ -4721,7 +4713,7 @@ public void test511AddProtectedAccountCaseIgnore() throws Exception { } private PrismObject createAccountShadow(String username) throws SchemaException { - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition defaultAccountDefinition = resourceSchema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT); ShadowType shadowType = new ShadowType(); PrismTestUtil.getPrismContext().adopt(shadowType); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyHacks.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyHacks.java index cd2032ef5c6..56a34e8f873 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyHacks.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyHacks.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.schema.processor.ResourceSchemaImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -175,7 +176,7 @@ public void test003Connection() throws Exception { assertNotNull("No serialNumber", cachingMetadata.getSerialNumber()); Element xsdElement = ObjectTypeUtil.findXsdElement(xmlSchemaTypeAfter); - ResourceSchema parsedSchema = ResourceSchema.parse(xsdElement, resourceBefore.toString(), prismContext); + ResourceSchema parsedSchema = ResourceSchemaImpl.parse(xsdElement, resourceBefore.toString(), prismContext); assertNotNull("No schema after parsing", parsedSchema); display("Parsed schema", parsedSchema); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLegacy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLegacy.java index 6b68f31bf45..ba8002d017e 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLegacy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLegacy.java @@ -24,6 +24,7 @@ import java.io.File; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -179,7 +180,7 @@ public void test105NativeParsedSchema() throws Exception { assertSuccess(result); resourceTypeNative = resourceNative.asObjectable(); - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resourceTypeNative, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceTypeNative, prismContext); display("Parsed resource schema", returnedSchema); assertNotNull("No parsed schema", returnedSchema); @@ -262,7 +263,7 @@ public void test205LegacyParsedSchema() throws Exception { assertSuccess(result); resourceTypeLegacy = resourceLegacy.asObjectable(); - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resourceTypeLegacy, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceTypeLegacy, prismContext); display("Parsed resource schema", returnedSchema); assertNotNull("No parsed schema", returnedSchema); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyNoActivation.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyNoActivation.java index d10861af230..bf1f934d117 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyNoActivation.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyNoActivation.java @@ -325,7 +325,9 @@ public void test158DeleteValidToValidFrom() throws Exception { ACCOUNT_WILL_OID, SchemaConstants.PATH_ACTIVATION_VALID_TO, prismContext, XmlTypeConverter.createXMLGregorianCalendar(VALID_TO_MILLIS)); PrismObjectDefinition def = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); - PropertyDelta validFromDelta = PropertyDelta.createModificationDeleteProperty(SchemaConstants.PATH_ACTIVATION_VALID_FROM, def.findPropertyDefinition(SchemaConstants.PATH_ACTIVATION_VALID_FROM), VALID_FROM_MILLIS); + PropertyDelta validFromDelta = PropertyDelta.createModificationDeleteProperty(SchemaConstants.PATH_ACTIVATION_VALID_FROM, + def.findPropertyDefinition(SchemaConstants.PATH_ACTIVATION_VALID_FROM), + XmlTypeConverter.createXMLGregorianCalendar(VALID_FROM_MILLIS)); delta.addModification(validFromDelta); delta.checkConsistence(); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java index df9921554d4..8ba5437ea9e 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java @@ -26,6 +26,11 @@ import java.util.ArrayList; import java.util.Collection; +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.*; +import org.apache.commons.lang.StringUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; @@ -33,8 +38,7 @@ import org.w3c.dom.Element; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.delta.DiffUtil; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; @@ -130,8 +134,8 @@ public void test010GetResource() throws Exception { assertResourceCacheHitsIncrement(0); assertResourceCacheMissesIncrement(1); - rememberResourceSchema(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - rememberRefinedResourceSchema(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + rememberResourceSchema(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + rememberRefinedResourceSchema(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); // Just refresh the resource used by other tests. This one has a complete schema. @@ -170,8 +174,8 @@ public void test011GetResourceAgain() throws Exception { assertResourceCacheHitsIncrement(1); assertResourceCacheMissesIncrement(0); - assertResourceSchemaUnchanged(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - assertRefinedResourceSchemaUnchanged(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + assertResourceSchemaUnchanged(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + assertRefinedResourceSchemaUnchanged(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); assertConnectorInstanceUnchanged(resourceProvisioning); @@ -198,8 +202,8 @@ public void test011GetResourceAgain() throws Exception { assertResourceCacheHitsIncrement(1); assertResourceCacheMissesIncrement(0); - assertResourceSchemaUnchanged(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - assertRefinedResourceSchemaUnchanged(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + assertResourceSchemaUnchanged(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + assertRefinedResourceSchemaUnchanged(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); assertConnectorInstanceUnchanged(resourceProvisioning); @@ -245,8 +249,8 @@ public void test012AddAccountGetResource() throws Exception { assertResourceCacheHitsIncrement(1); assertResourceCacheMissesIncrement(0); - assertResourceSchemaUnchanged(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - assertRefinedResourceSchemaUnchanged(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + assertResourceSchemaUnchanged(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + assertRefinedResourceSchemaUnchanged(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); assertConnectorInstanceUnchanged(resourceProvisioning); @@ -307,8 +311,8 @@ public void test020ModifyAndGetResource() throws Exception { assertResourceCacheMissesIncrement(1); // There are expected to be re-parsed - rememberResourceSchema(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - rememberRefinedResourceSchema(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + rememberResourceSchema(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + rememberRefinedResourceSchema(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); assertConnectorInstanceUnchanged(resourceProvisioning); @@ -354,8 +358,8 @@ public void test022GetAccountGetResource() throws Exception { assertResourceCacheHitsIncrement(1); assertResourceCacheMissesIncrement(0); - assertResourceSchemaUnchanged(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - assertRefinedResourceSchemaUnchanged(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + assertResourceSchemaUnchanged(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + assertRefinedResourceSchemaUnchanged(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); assertConnectorInstanceUnchanged(resourceProvisioning); @@ -418,8 +422,8 @@ public void test023ModifyRepoAndGetResource() throws Exception { assertResourceCacheMissesIncrement(1); // There are expected to be re-parsed - rememberResourceSchema(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - rememberRefinedResourceSchema(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + rememberResourceSchema(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + rememberRefinedResourceSchema(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); assertConnectorInstanceUnchanged(resourceProvisioning); @@ -523,7 +527,7 @@ private PropertyDelta createUselessStringDelta(String newVal) { new ItemPath(ResourceType.F_CONNECTOR_CONFIGURATION, ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_ELEMENT_QNAME, DummyResourceContoller.CONNECTOR_DUMMY_USELESS_STRING_QNAME), - new PrismPropertyDefinition(DummyResourceContoller.CONNECTOR_DUMMY_USELESS_STRING_QNAME, DOMUtil.XSD_STRING, prismContext), + new PrismPropertyDefinitionImpl(DummyResourceContoller.CONNECTOR_DUMMY_USELESS_STRING_QNAME, DOMUtil.XSD_STRING, prismContext), newVal); return uselessStringDelta; } @@ -560,8 +564,8 @@ private void assertConnectorConfigChanged() throws ObjectNotFoundException, Sche assertResourceCacheMissesIncrement(1); // There are expected to be re-parsed - rememberResourceSchema(RefinedResourceSchema.getResourceSchema(resourceProvisioning, prismContext)); - rememberRefinedResourceSchema(RefinedResourceSchema.getRefinedSchema(resourceProvisioning)); + rememberResourceSchema(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + rememberRefinedResourceSchema(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); assertResourceSchemaParseCountIncrement(0); // WHEN diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySchemaless.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySchemaless.java index e0b2af8acc8..94b9410183d 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySchemaless.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySchemaless.java @@ -33,6 +33,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -223,10 +224,10 @@ public void test005ParsedSchemaSchemaless() throws Exception { // THEN // The returned type should have the schema pre-parsed - assertNotNull(RefinedResourceSchema.hasParsedSchema(resourceTypeSchemaless)); + assertNotNull(RefinedResourceSchemaImpl.hasParsedSchema(resourceTypeSchemaless)); // Also test if the utility method returns the same thing - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resourceTypeSchemaless, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceTypeSchemaless, prismContext); display("Parsed resource schema", returnedSchema); @@ -299,10 +300,10 @@ public void test105ParsedSchemaStaticSchema() throws Exception { // THEN // The returned type should have the schema pre-parsed - assertNotNull(RefinedResourceSchema.hasParsedSchema(resourceTypeStaticSchema)); + assertNotNull(RefinedResourceSchemaImpl.hasParsedSchema(resourceTypeStaticSchema)); // Also test if the utility method returns the same thing - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resourceTypeStaticSchema, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceTypeStaticSchema, prismContext); display("Parsed resource schema", returnedSchema); assertNotNull("Null resource schema", returnedSchema); @@ -323,7 +324,7 @@ public void test106GetObjectStaticSchema() throws Exception { assertNotNull("No connector ref", resourceType.getConnectorRef()); assertNotNull("No connector ref OID", resourceType.getConnectorRef().getOid()); - ResourceSchema returnedSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema returnedSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); display("Parsed resource schema", returnedSchema); assertNotNull("Null resource schema", returnedSchema); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java index 1333a93345b..f4be0a4a952 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java @@ -25,6 +25,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -188,22 +191,19 @@ private String addFettucini(final String TEST_NAME, File file, String oid, Strin private void searchFettucini(int expectedNumberOfFettucinis) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { OperationResult result = new OperationResult(TestDummy.class.getName() + ".searchFettucini"); - - ObjectFilter filter = AndFilter.createAnd( - RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resource), - EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, - new QName(dummyResourceCtl.getNamespace(), "AccountObjectClass")), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, getIcfNameDefinition().getName()), - getIcfNameDefinition(), new PrismPropertyValue(ACCOUNT_FETTUCINI_NAME))); - ObjectQuery query = new ObjectQuery(); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) + .and().item(ShadowType.F_OBJECT_CLASS).eq(new QName(dummyResourceCtl.getNamespace(), "AccountObjectClass")) + .and().itemWithDef(getIcfNameDefinition(), ShadowType.F_ATTRIBUTES, getIcfNameDefinition().getName()).eq(ACCOUNT_FETTUCINI_NAME) + .build(); + // WHEN List> shadows = provisioningService.searchObjects(ShadowType.class, query, null, null, result); assertEquals("Wrong number of Fettucinis found", expectedNumberOfFettucinis, shadows.size()); } private PrismPropertyDefinition getIcfNameDefinition() { - return new PrismPropertyDefinition(ConnectorFactoryIcfImpl.ICFS_NAME, + return new PrismPropertyDefinitionImpl<>(ConnectorFactoryIcfImpl.ICFS_NAME, DOMUtil.XSD_STRING, prismContext); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java index 740ab12830d..864f0d66406 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java @@ -37,8 +37,10 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.schema.processor.*; import org.apache.commons.lang.StringUtils; import org.identityconnectors.framework.common.objects.Name; import org.identityconnectors.framework.common.objects.Uid; @@ -89,10 +91,6 @@ import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.constants.ConnectorTestOperation; import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceSchema; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; @@ -248,7 +246,7 @@ public void test003Connection() throws Exception { assertNotNull("No serialNumber",cachingMetadata.getSerialNumber()); Element xsdElement = ResourceTypeUtil.getResourceXsdSchema(resourceTypeRepoAfter); - ResourceSchema parsedSchema = ResourceSchema.parse(xsdElement, resourceTypeRepoAfter.toString(), prismContext); + ResourceSchema parsedSchema = ResourceSchemaImpl.parse(xsdElement, resourceTypeRepoAfter.toString(), prismContext); assertNotNull("No schema after parsing",parsedSchema); ObjectClassComplexTypeDefinition inetOrgPersonDefinition = parsedSchema.findObjectClassDefinition(RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS); @@ -270,7 +268,7 @@ public void test004ResourceAndConnectorCaching() throws Exception { ConnectorInstance configuredConnectorInstance = connectorManager.getConfiguredConnectorInstance( resource, false, result); assertNotNull("No configuredConnectorInstance", configuredConnectorInstance); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); assertNotNull("No resource schema", resourceSchema); // WHEN @@ -286,7 +284,7 @@ public void test004ResourceAndConnectorCaching() throws Exception { assertTrue("Configurations not equivalent", configurationContainer.equivalent(configurationContainerAgain)); assertTrue("Configurations not equals", configurationContainer.equals(configurationContainerAgain)); - ResourceSchema resourceSchemaAgain = RefinedResourceSchema.getResourceSchema(resourceAgain, prismContext); + ResourceSchema resourceSchemaAgain = RefinedResourceSchemaImpl.getResourceSchema(resourceAgain, prismContext); assertNotNull("No resource schema (again)", resourceSchemaAgain); assertEquals("Schema serial number mismatch", resourceType.getSchema().getCachingMetadata().getSerialNumber(), resourceTypeAgain.getSchema().getCachingMetadata().getSerialNumber()); @@ -373,7 +371,7 @@ public void test006Schema() throws Exception { // GIVEN // WHEN - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resourceType, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext); display("Resource schema", resourceSchema); ObjectClassComplexTypeDefinition accountDef = resourceSchema.findObjectClassDefinition(RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS); @@ -540,7 +538,7 @@ public void test007RefinedSchema() throws Exception { // GIVEN // WHEN - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceType, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType, prismContext); display("Refined schema", refinedSchema); // Check whether it is reusing the existing schema and not parsing it @@ -548,7 +546,7 @@ public void test007RefinedSchema() throws Exception { // Not equals() but == ... we want to really know if exactly the same // object instance is returned assertTrue("Broken caching", - refinedSchema == RefinedResourceSchema.getRefinedSchema(resourceType, prismContext)); + refinedSchema == RefinedResourceSchemaImpl.getRefinedSchema(resourceType, prismContext)); RefinedObjectClassDefinition accountDef = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); assertNotNull("Account definition is missing", accountDef); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDjNegative.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDjNegative.java index 78f1a91d5cc..be5715e6ace 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDjNegative.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDjNegative.java @@ -25,6 +25,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.PrismContext; import org.springframework.beans.factory.annotation.Autowired; @@ -163,7 +164,7 @@ public void test004ResourceAndConnectorCaching() throws Exception { TestUtil.assertFailure(result); TestUtil.assertFailure(resource.asObjectable().getFetchResult()); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); assertNull("Resource schema found", resourceSchema); // WHEN @@ -184,7 +185,7 @@ public void test004ResourceAndConnectorCaching() throws Exception { assertTrue("Configurations not equivalent", configurationContainer.equivalent(configurationContainerAgain)); assertTrue("Configurations not equals", configurationContainer.equals(configurationContainerAgain)); - ResourceSchema resourceSchemaAgain = RefinedResourceSchema.getResourceSchema(resourceAgain, prismContext); + ResourceSchema resourceSchemaAgain = RefinedResourceSchemaImpl.getResourceSchema(resourceAgain, prismContext); assertNull("Resource schema (again)", resourceSchemaAgain); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java index 03e325b185e..b9267e0aeea 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java @@ -28,6 +28,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.schema.PrismSchemaImpl; +import com.evolveum.midpoint.schema.processor.*; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; import org.testng.annotations.Test; @@ -55,10 +58,7 @@ import com.evolveum.midpoint.provisioning.ucf.api.ResultHandler; import com.evolveum.midpoint.provisioning.ucf.impl.ConnectorFactoryIcfImpl; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; -import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; -import com.evolveum.midpoint.schema.processor.ResourceAttribute; -import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; -import com.evolveum.midpoint.schema.processor.ResourceSchema; +import com.evolveum.midpoint.schema.constants.MidPointConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.statistics.ConnectorOperationalStatus; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -159,7 +159,7 @@ public void test002ConnectorSchema() throws Exception { display("Serialized XSD connector schema", DOMUtil.serializeDOMToString(xsdSchemaDom)); // Try to re-parse - PrismSchema reparsedConnectorSchema = PrismSchema.parse(DOMUtil.getFirstChildElement(xsdSchemaDom), true, "schema fetched from "+cc, PrismTestUtil.getPrismContext()); + PrismSchema reparsedConnectorSchema = PrismSchemaImpl.parse(DOMUtil.getFirstChildElement(xsdSchemaDom), true, "schema fetched from "+cc, PrismTestUtil.getPrismContext()); ProvisioningTestUtil.assertConnectorSchemaSanity(reparsedConnectorSchema, "re-parsed"); // TODO: 3 definitions would be cleaner. But we can live with this assertEquals("Unexpected number of definitions in re-parsed schema", 6, reparsedConnectorSchema.getDefinitions().size()); @@ -268,7 +268,7 @@ public void test030ResourceSchema() throws Exception { display("Serialized XSD resource schema", DOMUtil.serializeDOMToString(xsdSchemaDom)); // Try to re-parse - ResourceSchema reparsedResourceSchema = ResourceSchema.parse(DOMUtil.getFirstChildElement(xsdSchemaDom), + ResourceSchema reparsedResourceSchema = ResourceSchemaImpl.parse(DOMUtil.getFirstChildElement(xsdSchemaDom), "serialized schema", PrismTestUtil.getPrismContext()); display("Re-parsed resource schema", reparsedResourceSchema); assertEquals("Unexpected number of definitions in re-parsed schema", 4, reparsedResourceSchema.getDefinitions().size()); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java index 21e3a94e8af..d9f0f2bc331 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java @@ -15,14 +15,7 @@ */ package com.evolveum.midpoint.provisioning.impl.ucf; -import com.evolveum.midpoint.prism.Definition; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; @@ -750,7 +743,7 @@ public void test610ChangePassword() throws Exception { propMod.setPath(path); //set the replace value - MapXNode passPsXnode = prismContext.getBeanConverter().marshalProtectedDataType(passPs); + MapXNode passPsXnode = ((PrismContextImpl) prismContext).getBeanMarshaller().marshalProtectedDataType(passPs, null); RawType value = new RawType(passPsXnode, prismContext); propMod.getValue().add(value); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java index 31d9516ae28..cfa518a605a 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddGetObjectTest.java @@ -27,6 +27,7 @@ import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.stat.Statistics; @@ -49,7 +50,6 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.util.PrismTestUtil; -import com.evolveum.midpoint.prism.util.ValueSerializationUtil; import com.evolveum.midpoint.repo.sql.type.XMLGregorianCalendarType; import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.schema.DeltaConvertor; @@ -98,8 +98,7 @@ public void perfTest() throws Exception { stats.setStatisticsEnabled(true); final File OBJECTS_FILE = new File("./src/test/resources/10k-users.xml"); - List> elements = prismContext.parseObjects( - OBJECTS_FILE); + List> elements = prismContext.parserFor(OBJECTS_FILE).parseObjects(); long previousCycle = 0; long time = System.currentTimeMillis(); @@ -160,7 +159,7 @@ public void simpleAddGetTest() throws Exception { } private void addGetCompare(File file) throws Exception { - List> elements = prismContext.parseObjects(file); + List> elements = prismContext.parserFor(file).parseObjects(); List oids = new ArrayList(); OperationResult result = new OperationResult("Simple Add Get Test"); @@ -175,7 +174,7 @@ private void addGetCompare(File file) throws Exception { (System.currentTimeMillis() - time),}); int count = 0; - elements = prismContext.parseObjects(file); + elements = prismContext.parserFor(file).parseObjects(); for (int i = 0; i < elements.size(); i++) { try { PrismObject object = elements.get(i); @@ -311,13 +310,12 @@ private void checkContainersSize(PrismContainer newContainer, PrismContainer old public void addUserWithAssignmentExtension() throws Exception { LOGGER.info("===[ addUserWithAssignmentExtension ]==="); File file = new File(FOLDER_BASIC, "user-assignment-extension.xml"); - List> elements = prismContext.parseObjects(file); + List> elements = prismContext.parserFor(file).parseObjects(); OperationResult result = new OperationResult("ADD"); String oid = repositoryService.addObject((PrismObject) elements.get(0), null, result); - PrismObject fileUser = (PrismObject) prismContext.parseObjects(file) - .get(0); + PrismObject fileUser = (PrismObject) prismContext.parserFor(file).parseObjects().get(0); long id = 1; for (AssignmentType assignment : fileUser.asObjectable().getAssignment()) { assignment.setId(id); @@ -345,7 +343,7 @@ public void addGetFullAccount() throws Exception { // apply appropriate schema PrismObject resource = prismContext.parseObject(new File(FOLDER_BASIC, "resource-opendj.xml")); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ShadowUtil.applyResourceSchema(fileAccount, resourceSchema); OperationResult result = new OperationResult("ADD"); @@ -498,60 +496,36 @@ private String testIterationToken(String token) throws Exception { return token; } - @Test(enabled = false) - public void deltaOperationSerializationPerformanceTest() throws Exception { - List> elements = - prismContext.parseObjects(new File(FOLDER_BASIC, "objects.xml")); - - //get user from objects.xml - ObjectDelta delta = ObjectDelta.createAddDelta(elements.get(0)); - - final int COUNT = 10000; - //first conversion option - System.out.println(DeltaConvertor.toObjectDeltaTypeXml(delta)); - //second conversion option - System.out.println("\n" + toRepo(DeltaConvertor.toObjectDeltaType(delta), prismContext)); - - long time = System.currentTimeMillis(); - for (int i = 0; i < COUNT; i++) { - String xml = DeltaConvertor.toObjectDeltaTypeXml(delta); - } - time = System.currentTimeMillis() - time; - System.out.println(">>> " + time); - - time = System.currentTimeMillis(); - for (int i = 0; i < COUNT; i++) { - ObjectDeltaType type = DeltaConvertor.toObjectDeltaType(delta); - String xml = toRepo(type, prismContext); - } - time = System.currentTimeMillis() - time; - System.out.println(">>> " + time); - } - - private String toRepo(T value, PrismContext prismContext) - throws SchemaException, JAXBException { - if (value == null) { - return null; - } - - // PrismDomProcessor domProcessor = prismContext.getPrismDomProcessor(); - if (value instanceof Objectable) { - return prismContext.serializeObjectToString(((Objectable) value).asPrismObject(), - PrismContext.LANG_XML); - } +// @Test(enabled = false) +// public void deltaOperationSerializationPerformanceTest() throws Exception { +// List> elements = +// prismContext.processorFor(new File(FOLDER_BASIC, "objects.xml")).parseObjects(); +// +// //get user from objects.xml +// ObjectDelta delta = ObjectDelta.createAddDelta(elements.get(0)); +// +// final int COUNT = 10000; +// //first conversion option +// System.out.println(DeltaConvertor.toObjectDeltaTypeXml(delta)); +// //second conversion option +// //System.out.println("\n" + toRepo(DeltaConvertor.toObjectDeltaType(delta), prismContext)); +// +// long time = System.currentTimeMillis(); +// for (int i = 0; i < COUNT; i++) { +// String xml = DeltaConvertor.toObjectDeltaTypeXml(delta); +// } +// time = System.currentTimeMillis() - time; +// System.out.println(">>> " + time); +// +// time = System.currentTimeMillis(); +// for (int i = 0; i < COUNT; i++) { +// ObjectDeltaType type = DeltaConvertor.toObjectDeltaType(delta); +// String xml = toRepo(type, prismContext); +// } +// time = System.currentTimeMillis() - time; +// System.out.println(">>> " + time); +// } - if (value instanceof Containerable) { - // TODO: createFakeParentElement??? why we don't use the real - // name??? - return prismContext.serializeContainerValueToString( - ((Containerable) value).asPrismContainerValue(), - QNameUtil.getNodeQName(RUtil.createFakeParentElement()), prismContext.LANG_XML); - } - - - return ValueSerializationUtil.serializeValue(value, new QName("fake"), prismContext, PrismContext.LANG_XML); - - } @Test public void test() throws Exception { @@ -580,7 +554,7 @@ private void addGetFullAccountShadow() throws Exception { // apply appropriate schema PrismObject resource = prismContext.parseObject(new File(FOLDER_BASIC, "resource-opendj.xml")); - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ShadowUtil.applyResourceSchema(account, resourceSchema); repositoryService.addObject(account, null, result); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddOverwriteTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddOverwriteTest.java index dacfbcc0daf..9bb4c245a01 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddOverwriteTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AddOverwriteTest.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; @@ -81,7 +82,7 @@ public void setup() throws SchemaException, SAXException, IOException { @Test public void addWithOverwrite() throws Exception { - List> objects = prismContext.parseObjects(new File(ORG_STRUCT_OBJECTS)); + List> objects = prismContext.parserFor(new File(ORG_STRUCT_OBJECTS)).parseObjects(); OperationResult opResult = new OperationResult("Import file"); @@ -102,7 +103,7 @@ public void addWithOverwrite() throws Exception { AssertJUnit.assertNotNull(oid); //reimport carla, oid should stay the same, version must be incremented - objects = prismContext.parseObjects(new File(IMPORT_OVERWRITE)); + objects = prismContext.parserFor(new File(IMPORT_OVERWRITE)).parseObjects(); PrismObject newCarla = objects.get(0); newCarla.setOid(oid); @@ -119,9 +120,10 @@ public void addWithOverwrite() throws Exception { private PrismObject getCarla(OperationResult opResult) throws Exception { final String CARLA_NAME = "carla"; - final ObjectQuery query = new ObjectQuery(); PrismObjectDefinition userObjectDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); - query.setFilter(EqualFilter.createEqual(ObjectType.F_NAME, userObjectDef.findPropertyDefinition(ObjectType.F_NAME), null, CARLA_NAME)); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_NAME).eq(CARLA_NAME) + .build(); List> users = repositoryService.searchObjects(UserType.class, query, null, opResult); AssertJUnit.assertEquals(1, users.size()); return users.get(0); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ConcurrencyTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ConcurrencyTest.java index 59b5d0de460..e9ba1fed04f 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ConcurrencyTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ConcurrencyTest.java @@ -34,6 +34,7 @@ import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.sql.testing.SqlRepoTestUtil; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.result.OperationResult; @@ -453,8 +454,8 @@ public void concurrency010_SearchIterative() throws Exception { String oid = repositoryService.addObject(user, null, result); repositoryService.searchObjectsIterative(UserType.class, - ObjectQuery.createObjectQuery( - EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, PolyStringOrigMatchingRule.NAME, new PolyString(name))), + QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_NAME).eqPoly(name).matchingOrig().build(), new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/DeleteTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/DeleteTest.java index 9b57b0ea00c..b2ee05b3aaf 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/DeleteTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/DeleteTest.java @@ -53,7 +53,7 @@ public void delete001() throws Exception { return; } - List> elements = prismContext.parseObjects(file); + List> elements = prismContext.parserFor(file).parseObjects(); List oids = new ArrayList(); OperationResult result = new OperationResult("Delete Test"); @@ -114,8 +114,7 @@ public void delete0003() throws Exception { @Test public void test100DeleteObjects() throws Exception { // PrismDomProcessor domProcessor = prismContext.getPrismDomProcessor(); - List> objects = prismContext.parseObjects( - new File(FOLDER_BASIC, "objects.xml")); + List> objects = prismContext.parserFor(new File(FOLDER_BASIC, "objects.xml")).parseObjects(); OperationResult result = new OperationResult("add objects"); List oids = new ArrayList<>(); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java index 34da3a81785..258e835e472 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/EncodingTest.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.util.DebugUtil; @@ -559,10 +560,9 @@ private void repositorySelfTestUser(OperationResult testResult) throws SchemaExc OperationResult subresult1 = result.createSubresult(result.getOperation() + ".searchObjects.fullName"); try { - ObjectQuery query = new ObjectQuery(); - ObjectFilter filter = EqualFilter.createEqual(UserType.F_FULL_NAME, UserType.class, prismContext, - PolyStringNormMatchingRule.NAME, toPolyString(USER_FULL_NAME)); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME).eq(toPolyString(USER_FULL_NAME)).matchingNorm() + .build(); subresult1.addParam("query", query); List> foundObjects = repositoryService.searchObjects(UserType.class, query, null, subresult1); if (LOGGER.isTraceEnabled()) { diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java index 03074ce74ec..67df219d6bf 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ListAccountShadowOwnerTest.java @@ -70,7 +70,7 @@ public void listExistingOwner() throws Exception { //insert sample data final File OBJECTS_FILE = new File(FOLDER_BASIC, "objects.xml"); - List> elements = prismContext.parseObjects(OBJECTS_FILE); + List> elements = prismContext.parserFor(OBJECTS_FILE).parseObjects(); for (int i = 0; i < elements.size(); i++) { PrismObject object = elements.get(i); repositoryService.addObject(object, null, result); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java index b0ef0206762..f7d0a0c9794 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java @@ -25,9 +25,9 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.LessFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.api.RepoModifyOptions; @@ -78,7 +78,7 @@ public class ModifyTest extends BaseSQLRepoTest { private static final File TEST_DIR = new File("src/test/resources/modify"); private static final File ACCOUNT_FILE = new File(TEST_DIR, "account.xml"); private static final File MODIFY_USER_ADD_LINK = new File(TEST_DIR, "change-add.xml"); - + private static final Trace LOGGER = TraceManager.getTrace(ModifyTest.class); @BeforeSuite @@ -86,7 +86,7 @@ public void setup() throws SchemaException, SAXException, IOException { PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); } - + @BeforeClass public void setupClass() { InternalsConfig.encryptionChecks = false; @@ -95,12 +95,12 @@ public void setupClass() { protected RepoModifyOptions getModifyOptions() { return null; } - + @Test(expectedExceptions = SystemException.class, enabled = false) public void test010ModifyWithExistingName() throws Exception { final String TEST_NAME = "test010ModifyWithExistingName"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult result = new OperationResult("MODIFY"); File userFile = new File(TEST_DIR, "modify-user.xml"); @@ -131,7 +131,7 @@ public void test010ModifyWithExistingName() throws Exception { public void test020ModifyNotExistingUser() throws Exception { final String TEST_NAME = "test020ModifyNotExistingUser"; TestUtil.displayTestTile(TEST_NAME); - + ObjectModificationType modification = PrismTestUtil.parseAtomicValue( new File(TEST_DIR, "change-add.xml"), ObjectModificationType.COMPLEX_TYPE); @@ -147,7 +147,7 @@ public void test020ModifyNotExistingUser() throws Exception { public void test030ModifyUserOnNonExistingAccountTest() throws Exception { final String TEST_NAME = "test030ModifyUserOnNonExistingAccountTest"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult result = new OperationResult("MODIFY"); //add user @@ -183,7 +183,7 @@ public void test030ModifyUserOnNonExistingAccountTest() throws Exception { public void test031ModifyUserOnExistingAccountTest() throws Exception { final String TEST_NAME = "test031ModifyUserOnExistingAccountTest"; TestUtil.displayTestTile(TEST_NAME); - + // GIVEN OperationResult result = new OperationResult(TEST_NAME); @@ -203,7 +203,7 @@ public void test031ModifyUserOnExistingAccountTest() throws Exception { ObjectDeltaType objectDeltaType = PrismTestUtil.parseAnyValue(MODIFY_USER_ADD_LINK); ObjectDelta objectDelta = DeltaConvertor.createObjectDelta(objectDeltaType, prismContext); - Collection> deltas = objectDelta.getModifications(); + Collection> deltas = objectDelta.getModifications(); // WHEN repositoryService.modifyObject(UserType.class, oid, deltas, getModifyOptions(), result); @@ -222,7 +222,7 @@ public void test031ModifyUserOnExistingAccountTest() throws Exception { public void test032ModifyTaskObjectRef() throws Exception { final String TEST_NAME = "test032ModifyTaskObjectRef"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult result = new OperationResult(TEST_NAME); File taskFile = new File(TEST_DIR, "task.xml"); System.out.println("ADD"); @@ -315,7 +315,7 @@ private void checkReference(String taskOid) { public void test100ModifyUserAddRole() throws Exception { final String TEST_NAME = "test100ModifyUserAddRole"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult parentResult = new OperationResult("Modify user -> add roles"); String userToModifyOid = "f65963e3-9d47-4b18-aaf3-bfc98bdfa000"; @@ -357,7 +357,7 @@ public void test100ModifyUserAddRole() throws Exception { public void test110ModifyDeleteObjectChangeFromAccount() throws Exception { final String TEST_NAME = "test110ModifyDeleteObjectChangeFromAccount"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult parentResult = new OperationResult("testModifyDeleteObjectChnageFromAccount"); PrismObject accShadow = prismContext.parseObject(new File(TEST_DIR + "/account-delete-object-change.xml")); String oid = repositoryService.addObject(accShadow, null, parentResult); @@ -390,7 +390,7 @@ public void test110ModifyDeleteObjectChangeFromAccount() throws Exception { public void test120ModifyAccountMetadata() throws Exception { final String TEST_NAME = "test120ModifyAccountMetadata"; TestUtil.displayTestTile(TEST_NAME); - + // GIVEN OperationResult parentResult = new OperationResult(TEST_NAME); @@ -403,18 +403,18 @@ public void test120ModifyAccountMetadata() throws Exception { // The parsed shadow has attributes that have xsi:type specification. Add another one that has // fully dynamic definition - + QName attrBazQName = new QName(MidPointConstants.NS_RI, "baz"); PrismContainer attributesContainerBefore = shadowBefore.findContainer(ShadowType.F_ATTRIBUTES); PrismProperty attrBazBefore = new PrismProperty<>(new QName(MidPointConstants.NS_RI, "baz"), prismContext); - PrismPropertyDefinition attrBazDefBefore = new PrismPropertyDefinition<>(attrBazQName, DOMUtil.XSD_STRING, prismContext); + PrismPropertyDefinitionImpl attrBazDefBefore = new PrismPropertyDefinitionImpl<>(attrBazQName, DOMUtil.XSD_STRING, prismContext); attrBazDefBefore.setMaxOccurs(-1); attrBazBefore.setDefinition(attrBazDefBefore); attrBazBefore.addRealValue("BaZ1"); attrBazBefore.addRealValue("BaZ2"); attrBazBefore.addRealValue("BaZ3"); attributesContainerBefore.add(attrBazBefore); - + System.out.println("\nAcc shadow"); System.out.println(shadowBefore.debugDump()); @@ -423,7 +423,7 @@ public void test120ModifyAccountMetadata() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - + PrismObject repoShadow = repositoryService.getObject(ShadowType.class, oid, null, parentResult); // THEN @@ -459,10 +459,10 @@ public void test120ModifyAccountMetadata() throws Exception { oid, null, parentResult); System.out.println("\nAfter modify 1"); System.out.println(afterModify.debugDump()); - + MetadataType metadataAfter = afterModify.asObjectable().getMetadata(); assertEquals("Wrong modifyTimestamp", modifyTimestampBefore, metadataAfter.getModifyTimestamp()); - + PrismAsserts.assertEqualsPolyString("Wrong shadow name", "1234", afterModify.asObjectable().getName()); assertAttribute(afterModify, new QName(SchemaConstants.NS_ICF_SCHEMA, "uid"), "8daaeeae-f0c7-41c9-b258-2a3351aa8876"); assertAttribute(afterModify, "foo", "FOO"); @@ -481,7 +481,7 @@ public void test120ModifyAccountMetadata() throws Exception { TestUtil.displayWhen(TEST_NAME); repositoryService.modifyObject(ShadowType.class, oid, syncSituationDeltas, getModifyOptions(), parentResult); // AssertJUnit.assertNull(afterModify.asObjectable().getObjectChange()); - + // THEN TestUtil.displayThen(TEST_NAME); afterModify = repositoryService.getObject(ShadowType.class, @@ -494,7 +494,7 @@ public void test120ModifyAccountMetadata() throws Exception { public void test130ExtensionModify() throws Exception { final String TEST_NAME = "test130ExtensionModify"; TestUtil.displayTestTile(TEST_NAME); - + final QName QNAME_LOOT = new QName("http://example.com/p", "loot"); File userFile = new File(TEST_DIR, "user-with-extension.xml"); @@ -533,7 +533,7 @@ public void test130ExtensionModify() throws Exception { public void test140ModifyAccountSynchronizationSituation() throws Exception { final String TEST_NAME = "test140ModifyAccountSynchronizationSituation"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult result = new OperationResult("testModifyAccountSynchronizationSituation"); //add account @@ -581,10 +581,9 @@ public void test140ModifyAccountSynchronizationSituation() throws Exception { AssertJUnit.assertNotNull(afterModifytimestamp); assertEquals(afterSecondModifyType.getSynchronizationTimestamp(), description.getTimestamp()); - LessFilter filter = LessFilter.createLess(ShadowType.F_SYNCHRONIZATION_TIMESTAMP, afterSecondModify.findProperty( - ShadowType.F_SYNCHRONIZATION_TIMESTAMP).getDefinition(), afterModifytimestamp, true); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_SYNCHRONIZATION_TIMESTAMP).le(afterModifytimestamp) + .build(); List> shadows = repositoryService.searchObjects(ShadowType.class, query, null, result); AssertJUnit.assertNotNull(shadows); assertEquals(1, shadows.size()); @@ -596,7 +595,7 @@ public void test140ModifyAccountSynchronizationSituation() throws Exception { public void test150ModifyRoleAddInducements() throws Exception { final String TEST_NAME = "test150ModifyRoleAddInducements"; TestUtil.displayTestTile(TEST_NAME); - + OperationResult result = new OperationResult(TEST_NAME); File roleFile = new File(TEST_DIR, "role-modify.xml"); @@ -641,11 +640,11 @@ public void test150ModifyRoleAddInducements() throws Exception { assertEquals("Version has changed", version, role.getVersion()); } } - + private void assertAttribute(PrismObject shadow, String attrName, T... expectedValues) { assertAttribute(shadow, new QName(MidPointConstants.NS_RI, attrName), expectedValues); } - + private void assertAttribute(PrismObject shadow, QName attrQName, T... expectedValues) { PrismProperty attr = shadow.findProperty(new ItemPath(ShadowType.F_ATTRIBUTES, attrQName)); if (expectedValues.length == 0) { diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/OrgStructTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/OrgStructTest.java index b172bfbf620..d4e4391cf6c 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/OrgStructTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/OrgStructTest.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.repo.sql.data.common.ROrgClosure; @@ -113,7 +114,7 @@ public class OrgStructTest extends BaseSQLRepoTest { @Test public void test001addOrgStructObjects() throws Exception { OperationResult opResult = new OperationResult("test001addOrgStructObjects"); - List> orgStruct = prismContext.parseObjects(new File(ORG_STRUCT_OBJECTS)); + List> orgStruct = prismContext.parserFor(new File(ORG_STRUCT_OBJECTS)).parseObjects(); for (PrismObject o : orgStruct) { repositoryService.addObject((PrismObject) o, null, opResult); @@ -131,9 +132,10 @@ public void test001addOrgStructObjects() throws Exception { PrismObjectDefinition userObjectDef = prismContext.getSchemaRegistry() .findObjectDefinitionByCompileTimeClass(UserType.class); - EqualFilter equals = EqualFilter.createEqual(UserType.F_NAME, userObjectDef.findPropertyDefinition(UserType.F_NAME), null, ELAINE_NAME); - List> users = repositoryService.searchObjects(UserType.class, - ObjectQuery.createObjectQuery(equals), null, opResult); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_NAME).eq(ELAINE_NAME) + .build(); + List> users = repositoryService.searchObjects(UserType.class, query, null, opResult); AssertJUnit.assertEquals(1, users.size()); ELAINE_OID = users.get(0).getOid(); @@ -238,8 +240,8 @@ private void assertSubordinate(boolean expected, String upperOrgOid, String... l public void test001addOrgStructObjectsIncorrect() throws Exception { OperationResult opResult = new OperationResult("test001addOrgStructObjectsIncorrect"); - List> orgStructIncorrect = prismContext.parseObjects( - new File(ORG_STRUCT_OBJECTS_INCORRECT)); + List> orgStructIncorrect = prismContext.parserFor( + new File(ORG_STRUCT_OBJECTS_INCORRECT)).parseObjects(); for (PrismObject o : orgStructIncorrect) { repositoryService.addObject((PrismObject) o, null, opResult); @@ -270,11 +272,9 @@ public void test001addOrgStructObjectsIncorrect() throws Exception { orgClosure = criteria.list(); AssertJUnit.assertEquals(3, orgClosure.size()); - - ObjectQuery query = new ObjectQuery(); - PrismObjectDefinition userObjectDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); - query.setFilter(EqualFilter.createEqual(UserType.F_NAME, userObjectDef.findPropertyDefinition(UserType.F_NAME), null, ELAINE_NAME1)); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_NAME).eq(ELAINE_NAME1) + .build(); List> users = repositoryService.searchObjects(UserType.class, query, null, opResult); AssertJUnit.assertNotNull(users); @@ -514,8 +514,10 @@ public void test005deleteOrg() throws Exception { public void test006searchOrgStructUserUnbounded() throws Exception { OperationResult parentResult = new OperationResult("test006searchOrgStructUserUnbounded"); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(OrgFilter.createOrg(SEARCH_ORG_OID_UNBOUNDED_DEPTH)); - objectQuery.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); + ObjectQuery objectQuery = QueryBuilder.queryFor(ObjectType.class, prismContext) + .isChildOf(SEARCH_ORG_OID_UNBOUNDED_DEPTH) + .asc(ObjectType.F_NAME) + .build(); List> orgClosure = repositoryService.searchObjects(ObjectType.class, objectQuery, null, parentResult); @@ -543,9 +545,10 @@ public void test007searchOrgStructOrgDepth() throws Exception { session.getTransaction().commit(); session.close(); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(OrgFilter.createOrg(SEARCH_ORG_OID_DEPTH1, OrgFilter.Scope.ONE_LEVEL)); - objectQuery.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - + ObjectQuery objectQuery = QueryBuilder.queryFor(ObjectType.class, prismContext) + .isDirectChildOf(SEARCH_ORG_OID_DEPTH1) + .asc(ObjectType.F_NAME) + .build(); List> sOrgClosure = repositoryService.searchObjects(ObjectType.class, objectQuery, null, parentResult); for (PrismObject u : sOrgClosure) { @@ -563,9 +566,10 @@ public void test007searchOrgStructOrgDepth() throws Exception { public void test008searchRootOrg() throws Exception { OperationResult parentResult = new OperationResult("test008searchRootOrg"); - ObjectQuery qSearch = ObjectQuery.createObjectQuery(OrgFilter.createRootOrg()); - qSearch.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - + ObjectQuery qSearch = QueryBuilder.queryFor(ObjectType.class, prismContext) + .isRoot() + .asc(ObjectType.F_NAME) + .build(); List> rootOrgs = repositoryService.searchObjects(OrgType.class, qSearch, null, parentResult); for (PrismObject ro : rootOrgs) { @@ -600,12 +604,10 @@ public void test011OrgFilter() throws Exception { TestUtil.displayTestTile(TEST_NAME); OperationResult opResult = new OperationResult(TEST_NAME); - ObjectQuery query = new ObjectQuery(); - PrismReferenceValue baseOrgRef = new PrismReferenceValue(ORG_F001_OID); - ObjectFilter filter = OrgFilter.createOrg(baseOrgRef, OrgFilter.Scope.ONE_LEVEL); - ObjectPaging paging = ObjectPaging.createPaging(null, null, ObjectType.F_NAME, null); - query.setFilter(filter); - query.setPaging(paging); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .isDirectChildOf(ORG_F001_OID) + .asc(ObjectType.F_NAME) + .build(); // WHEN List> orgClosure = repositoryService.searchObjects(ObjectType.class, query, null, opResult); @@ -620,11 +622,9 @@ public void test100ParentOrgRefFilterNullRelation() throws Exception { TestUtil.displayTestTile(TEST_NAME); OperationResult opResult = new OperationResult(TEST_NAME); - ObjectQuery query = new ObjectQuery(); - PrismReferenceValue refVal = new PrismReferenceValue(ORG_F001_OID); - ObjectFilter filter = RefFilter.createReferenceEqual(new ItemPath(ObjectType.F_PARENT_ORG_REF), - UserType.class, prismContext, refVal); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(ObjectType.F_PARENT_ORG_REF).ref(new PrismReferenceValue(ORG_F001_OID)) + .build(); // WHEN List> orgs = repositoryService.searchObjects(ObjectType.class, query, null, opResult); @@ -639,12 +639,11 @@ public void test101ParentOrgRefFilterManagerRelation() throws Exception { TestUtil.displayTestTile(TEST_NAME); OperationResult opResult = new OperationResult(TEST_NAME); - ObjectQuery query = new ObjectQuery(); PrismReferenceValue refVal = new PrismReferenceValue(ORG_F001_OID); refVal.setRelation(SchemaConstants.ORG_MANAGER); - ObjectFilter filter = RefFilter.createReferenceEqual(new ItemPath(ObjectType.F_PARENT_ORG_REF), - UserType.class, prismContext, refVal); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(ObjectType.F_PARENT_ORG_REF).ref(refVal) + .build(); // WHEN List> orgs = repositoryService.searchObjects(ObjectType.class, query, null, opResult); @@ -659,12 +658,11 @@ public void test102ParentOrgRefFilterAnyRelation() throws Exception { TestUtil.displayTestTile(TEST_NAME); OperationResult opResult = new OperationResult(TEST_NAME); - ObjectQuery query = new ObjectQuery(); PrismReferenceValue refVal = new PrismReferenceValue(ORG_F001_OID); refVal.setRelation(PrismConstants.Q_ANY); - ObjectFilter filter = RefFilter.createReferenceEqual(new ItemPath(ObjectType.F_PARENT_ORG_REF), - UserType.class, prismContext, refVal); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(ObjectType.F_PARENT_ORG_REF).ref(refVal) + .build(); // WHEN List> orgs = repositoryService.searchObjects(ObjectType.class, query, null, opResult); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/PerformanceTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/PerformanceTest.java index 372f8220f57..7659e2ed491 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/PerformanceTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/PerformanceTest.java @@ -51,7 +51,7 @@ public void test100Parsing() throws Exception { int COUNT = 1000; for (int i = 0; i < COUNT; i++) { - List> elements = prismContext.parseObjects(new File(FOLDER_BASIC, "objects.xml")); + List> elements = prismContext.parserFor(new File(FOLDER_BASIC, "objects.xml")).parseObjects(); for (PrismObject obj : elements) { prismContext.serializeObjectToString(obj, PrismContext.LANG_XML); } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index 412565029e6..729e745e858 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -16,34 +16,9 @@ package com.evolveum.midpoint.repo.sql; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismConstants; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; -import com.evolveum.midpoint.prism.match.PolyStringOrigMatchingRule; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.ExistsFilter; -import com.evolveum.midpoint.prism.query.GreaterFilter; -import com.evolveum.midpoint.prism.query.InOidFilter; -import com.evolveum.midpoint.prism.query.LessFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectPaging; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.OrFilter; -import com.evolveum.midpoint.prism.query.OrgFilter; -import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; -import com.evolveum.midpoint.prism.query.RefFilter; -import com.evolveum.midpoint.prism.query.SubstringFilter; -import com.evolveum.midpoint.prism.query.TypeFilter; +import com.evolveum.midpoint.prism.query.*; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.prism.util.PrismTestUtil; @@ -94,11 +69,7 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignStateType.IN_REVIEW_STAGE; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_OWNER_REF; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_STATE; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_CURRENT_STAGE_NUMBER; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_DECISION; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_CURRENT_REVIEWER_REF; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_CURRENT_REVIEW_DEADLINE; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_CURRENT_REVIEW_REQUESTED_TIMESTAMP; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.*; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDecisionType.F_RESPONSE; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDecisionType.F_STAGE_NUMBER; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationResponseType.NO_RESPONSE; @@ -107,14 +78,10 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType.F_ASSIGNMENT; import static com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType.F_CREATE_APPROVER_REF; import static com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType.F_CREATOR_REF; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType.F_EXTENSION; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType.F_METADATA; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType.F_NAME; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType.*; import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType.F_WORKFLOW_CONTEXT; import static com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType.F_TIMESTAMP; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.WfContextType.F_PROCESS_INSTANCE_ID; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.WfContextType.F_REQUESTER_REF; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.WfContextType.F_START_TIMESTAMP; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.WfContextType.*; import static org.testng.AssertJUnit.assertEquals; /** @@ -142,8 +109,8 @@ public void beforeClass() throws Exception { PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); - List> objects = prismContext.parseObjects( - new File(FOLDER_BASIC, "objects.xml")); + List> objects = prismContext.parserFor( + new File(FOLDER_BASIC, "objects.xml")).parseObjects(); OperationResult result = new OperationResult("add objects"); for (PrismObject object : objects) { repositoryService.addObject(object, null, result); @@ -186,10 +153,6 @@ public void test002QueryNameOrig() throws Exception { /* * ### user: Equal (name, "asdf", PolyStringOrig) */ - ObjectFilter filter = EqualFilter.createEqual(F_NAME, UserType.class, prismContext, - PolyStringOrigMatchingRule.NAME, new PolyString("asdf", "asdf")); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(F_NAME).eqPoly("asdf", "asdf").matchingOrig().build(); @@ -215,10 +178,6 @@ public void test003QueryNameStrict() throws Exception { /* * ### user: Equal (name, "asdf", PolyStringOrig) */ - ObjectFilter filter = EqualFilter.createEqual(F_NAME, UserType.class, prismContext, - null, new PolyString("asdf", "asdf")); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(F_NAME).eqPoly("asdf", "asdf").build(); @@ -272,10 +231,6 @@ public void test011QueryOrganizationOrig() throws Exception { /* * ### user: Equal (organization, "asdf", PolyStringOrig) */ - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, - PolyStringOrigMatchingRule.NAME, new PolyString("asdf", "asdf")); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(UserType.F_ORGANIZATION).eqPoly("asdf", "asdf").matchingOrig().build(); @@ -301,11 +256,6 @@ public void test012QueryOrganizationStrict() throws Exception { /* * ### user: Equal (organization, "asdf") */ - - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, - null, new PolyString("asdf", "asdf")); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(UserType.F_ORGANIZATION).eqPoly("asdf", "asdf").matchingStrict().build(); @@ -332,12 +282,6 @@ public void test020QueryTwoOrganizationsNormAnd() throws Exception { * UserType: And (Equal (organization, 'asdf', PolyStringNorm), * Equal (organization, 'ghjk', PolyStringNorm)) */ - ObjectFilter filter = AndFilter.createAnd( - EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, PolyStringNormMatchingRule.NAME, new PolyString("asdf", "asdf")), - EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, PolyStringNormMatchingRule.NAME, new PolyString("ghjk", "ghjk"))); - - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(UserType.F_ORGANIZATION).eqPoly("asdf", "asdf").matchingNorm() .and().item(UserType.F_ORGANIZATION).eqPoly("ghjk", "ghjk").matchingNorm() @@ -367,12 +311,6 @@ public void test021QueryTwoOrganizationsStrictOr() throws Exception { * UserType: Or (Equal (organization, 'asdf'), * Equal (organization, 'ghjk')) */ - ObjectFilter filter = OrFilter.createOr( - EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, null, new PolyString("asdf", "asdf")), - EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, null, new PolyString("ghjk", "ghjk"))); - - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(UserType.F_ORGANIZATION).eqPoly("asdf", "asdf") .or().item(UserType.F_ORGANIZATION).eqPoly("ghjk", "ghjk") @@ -405,10 +343,9 @@ public void test025QueryOrganizationOrigPolymorphic() throws Exception { /* * ### object: Equal (organization, "asdf", PolyStringOrig) */ - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, - PolyStringOrigMatchingRule.NAME, new PolyString("asdf", "asdf")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ORGANIZATION).eqPoly("asdf", "asdf").matchingOrig() + .build(); String expected = "select\n" + " o.fullObject, o.stringsCount, o.longsCount, o.datesCount, o.referencesCount, o.polysCount, o.booleansCount\n" + "from\n" + @@ -432,8 +369,9 @@ public void test030QueryTaskDependent() throws Exception { /* * ### task: Equal (dependent, "123456") */ - ObjectFilter filter = EqualFilter.createEqual(TaskType.F_DEPENDENT, TaskType.class, prismContext, null, "123456"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_DEPENDENT).eq("123456") + .build(); String expected = "select\n" + " t.fullObject, t.stringsCount, t.longsCount, t.datesCount, t.referencesCount, t.polysCount, t.booleansCount\n" + @@ -455,9 +393,6 @@ public void test040QueryClob() throws Exception { Session session = open(); try { - ObjectFilter filter = EqualFilter.createEqual(UserType.F_DESCRIPTION, UserType.class, prismContext, null, "aaa"); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(UserType.F_DESCRIPTION).eq("aaa") .build(); @@ -476,9 +411,9 @@ public void test050QueryEnum() throws Exception { /* * ### task: Equal (executionStatus, WAITING) */ - ObjectFilter filter = EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, TaskType.class, prismContext, - null, TaskExecutionStatusType.WAITING); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.WAITING) + .build(); String real = getInterpretedQuery2(session, TaskType.class, query); String expected = "select\n" + @@ -718,12 +653,6 @@ public void test080QueryExistsAssignment() throws Exception { /* * ### UserType: Exists (assignment, Equal (activation/administrativeStatus = Enabled)) */ - ExistsFilter filter = ExistsFilter.createExists(new ItemPath(F_ASSIGNMENT), UserType.class, prismContext, - EqualFilter.createEqual(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS), - AssignmentType.class, prismContext, null, ActivationStatusType.ENABLED)); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - query0.setPaging(ObjectPaging.createPaging(F_NAME, ASCENDING)); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .exists(F_ASSIGNMENT) .item(AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS) @@ -876,10 +805,10 @@ public void test100QueryObjectByName() throws Exception { * ==> from RObject o where name.orig = 'cpt. Jack Sparrow' and name.norm = 'cpt jack sparrow' * order by name.orig asc */ - EqualFilter filter = EqualFilter.createEqual(F_NAME, ObjectType.class, prismContext, - null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - query.setPaging(ObjectPaging.createPaging(null, null, F_NAME, ASCENDING)); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(F_NAME).eqPoly("cpt. Jack Sparrow", "cpt jack sparrow") + .asc(F_NAME) + .build(); String real = getInterpretedQuery2(session, ObjectType.class, query); String expected = "select\n" + @@ -1074,12 +1003,9 @@ public void test140QueryUserAccountRef() throws Exception { * ==> select from RUser u left join u.linkRef l where * l.targetOid = '123' and l.relation = '#' */ - RefFilter filter = RefFilter.createReferenceEqual(UserType.F_LINK_REF, UserType.class, prismContext, "123"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - -// ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) -// .item(UserType.F_LINK_REF).ref("123") -// .build(); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_LINK_REF).ref("123") + .build(); String real = getInterpretedQuery2(session, UserType.class, query); @@ -1121,10 +1047,10 @@ public void test150QueryUserAssignmentTargetRef() throws Exception { ObjectReferenceType ort = new ObjectReferenceType(); ort.setOid("123"); ort.setType(RoleType.COMPLEX_TYPE); - RefFilter filter = RefFilter.createReferenceEqual( - new ItemPath(F_ASSIGNMENT, AssignmentType.F_TARGET_REF), - UserType.class, prismContext, ort.asReferenceValue()); - String real = getInterpretedQuery2(session, UserType.class, ObjectQuery.createObjectQuery(filter)); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(ort.asReferenceValue()) + .build(); + String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + " u.fullObject,\n" + " u.stringsCount,\n" + @@ -1156,12 +1082,9 @@ public void test160QueryTrigger() throws Exception { Session session = open(); try { XMLGregorianCalendar thisScanTimestamp = XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime()); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(ObjectType.class); - ItemPath triggerPath = new ItemPath(ObjectType.F_TRIGGER, F_TIMESTAMP); - ObjectFilter filter = LessFilter.createLess(triggerPath, objectDef, thisScanTimestamp, true); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(ObjectType.F_TRIGGER, F_TIMESTAMP).le(thisScanTimestamp) + .build(); String real = getInterpretedQuery2(session, ObjectType.class, query); String expected = "select\n" + @@ -1214,11 +1137,9 @@ public void test162QueryTriggerBeforeAfter() throws Exception { public void test170QueryAssignmentActivationAdministrativeStatus() throws Exception { Session session = open(); try { - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(UserType.class); - ItemPath activationPath = new ItemPath(F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - ObjectFilter filter = EqualFilter.createEqual(activationPath, objectDef, ActivationStatusType.ENABLED); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.ENABLED) + .build(); String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + @@ -1252,11 +1173,10 @@ public void test180QueryInducementActivationAdministrativeStatus() throws Except * a.assignmentOwner = RAssignmentOwner.ABSTRACT_ROLE and <--- this differentiates inducements from assignments * a.activation.administrativeStatus = RActivationStatus.ENABLED */ - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(RoleType.class); - ItemPath activationPath = new ItemPath(RoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - ObjectFilter filter = EqualFilter.createEqual(activationPath, objectDef, ActivationStatusType.ENABLED); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(RoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.ENABLED) + .build(); + String real = getInterpretedQuery2(session, RoleType.class, query); String expected = "select\n" + @@ -1288,18 +1208,10 @@ public void test182QueryInducementAndAssignmentActivationAdministrativeStatus() * ### Role: Or (Equal (assignment/activation/administrativeStatus, RActivationStatus.ENABLED), * Equal (inducement/activation/administrativeStatus, RActivationStatus.ENABLED)) */ - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(RoleType.class); - - //filter1 - ItemPath activationPath1 = new ItemPath(F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - ObjectFilter filter1 = EqualFilter.createEqual(activationPath1, objectDef, ActivationStatusType.ENABLED); - - //filter2 - ItemPath activationPath2 = new ItemPath(RoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - ObjectFilter filter2 = EqualFilter.createEqual(activationPath2, objectDef, ActivationStatusType.ENABLED); - - ObjectQuery query = ObjectQuery.createObjectQuery(OrFilter.createOr(filter1, filter2)); + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.ENABLED) + .or().item(RoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.ENABLED) + .build(); String real = getInterpretedQuery2(session, RoleType.class, query); String expected = "select\n" + @@ -1339,14 +1251,10 @@ public void test190QueryUserByActivationDouble() throws Exception { * ==> select u from RUser u where u.activation.administrativeStatus = RActivationStatus.ENABLED and * u.activation.validFrom = ... */ - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(UserType.class); - ObjectFilter filter1 = EqualFilter.createEqual(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS), objectDef, - ActivationStatusType.ENABLED); - ObjectFilter filter2 = EqualFilter.createEqual(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_VALID_FROM), objectDef, - XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime())); - - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(filter1, filter2)); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).eq(ActivationStatusType.ENABLED) + .and().item(AssignmentType.F_ACTIVATION, ActivationType.F_VALID_FROM).eq(XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime())) + .build(); String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + @@ -1373,15 +1281,11 @@ public void test200QueryTriggerTimestampDoubleWrong() throws Exception { try { XMLGregorianCalendar thisScanTimestamp = XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime()); - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(ObjectType.class); - ItemPath triggerPath = new ItemPath(ObjectType.F_TRIGGER, F_TIMESTAMP); - ObjectFilter greater = GreaterFilter.createGreater(triggerPath, objectDef, thisScanTimestamp, false); - ObjectFilter lesser = LessFilter.createLess(triggerPath, objectDef, thisScanTimestamp, false); - AndFilter and = AndFilter.createAnd(greater, lesser); - LOGGER.info(and.debugDump()); - - ObjectQuery query = ObjectQuery.createObjectQuery(and); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(ObjectType.F_TRIGGER, F_TIMESTAMP).gt(thisScanTimestamp) + .and().item(ObjectType.F_TRIGGER, F_TIMESTAMP).lt(thisScanTimestamp) + .build(); + LOGGER.info(query.debugDump()); String real = getInterpretedQuery2(session, ObjectType.class, query); // correct translation but the filter is wrong: we need to point to THE SAME timestamp -> i.e. ForValue should be used here @@ -1408,12 +1312,6 @@ public void test300CountObjectOrderByName() throws Exception { Session session = open(); try { - EqualFilter filter = EqualFilter.createEqual(F_NAME, UserType.class, prismContext, - null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); - - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter, - ObjectPaging.createPaging(F_NAME, ASCENDING)); - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) .item(F_NAME).eqPoly("cpt. Jack Sparrow", "cpt jack sparrow") .asc(F_NAME).build(); @@ -1463,11 +1361,10 @@ public void test320CountTaskOrderByName() throws Exception { Session session = open(); try { - EqualFilter filter = EqualFilter.createEqual(TaskType.F_PARENT, TaskType.class, prismContext, null); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - query.setPaging(ObjectPaging.createPaging(null, null, F_NAME, ASCENDING)); - + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_PARENT).isNull() + .asc(F_NAME) + .build(); String real = getInterpretedQuery2(session, TaskType.class, query, true); String expected = "select\n" + " count(*)\n" + @@ -1532,11 +1429,6 @@ public void test340QueryOrgTreeFindOrgs() throws Exception { Session session = open(); try { - OrgFilter orgFilter = OrgFilter.createOrg("some oid", OrgFilter.Scope.ONE_LEVEL); - ObjectQuery query0 = ObjectQuery.createObjectQuery(orgFilter); - query0.setPaging(ObjectPaging.createPaging(null, null, F_NAME, ASCENDING)); - query0.setUseNewQueryInterpreter(true); - ObjectQuery query = QueryBuilder.queryFor(OrgType.class, prismContext) .isDirectChildOf("some oid") .asc(ObjectType.F_NAME) @@ -1675,18 +1567,6 @@ public void test400ActivationQueryWrong() throws Exception { XMLGregorianCalendar thisScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - OrFilter filter = OrFilter.createOr( - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_VALID_FROM), - focusObjectDef, thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_VALID_TO), - focusObjectDef, thisScanTimestamp, true) - ); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) .item(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM).le(thisScanTimestamp) .or().item(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO).le(thisScanTimestamp) @@ -1736,19 +1616,6 @@ public void test405ActivationQueryCorrect() throws Exception { XMLGregorianCalendar thisScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - OrFilter filter = OrFilter.createOr( - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - thisScanTimestamp, true), - ExistsFilter.createExists(new ItemPath(F_ASSIGNMENT), focusObjectDef, - OrFilter.createOr( - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - assignmentDef, thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - assignmentDef, thisScanTimestamp, true)))); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) .item(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM).le(thisScanTimestamp) .or().item(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO).le(thisScanTimestamp) @@ -1798,34 +1665,6 @@ public void test410ActivationQueryWrong() throws Exception { XMLGregorianCalendar lastScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); XMLGregorianCalendar thisScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - OrFilter filter = OrFilter.createOr( - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - focusObjectDef, lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - focusObjectDef, thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - focusObjectDef, lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - focusObjectDef, thisScanTimestamp, true) - ) - ); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) .block() .item(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM).gt(lastScanTimestamp) @@ -1845,8 +1684,6 @@ public void test410ActivationQueryWrong() throws Exception { .endBlock() .build(); - //QueryBuilder.queryFor(UserType.class, prismContext); - Session session = open(); try { String real = getInterpretedQuery2(session, UserType.class, query, false); @@ -1902,37 +1739,6 @@ public void test415ActivationQueryCorrect() throws Exception { XMLGregorianCalendar lastScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); XMLGregorianCalendar thisScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - OrFilter filter = OrFilter.createOr( - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - thisScanTimestamp, true) - ), - AndFilter.createAnd( - ExistsFilter.createExists(new ItemPath(F_ASSIGNMENT), focusObjectDef, - OrFilter.createOr( - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - assignmentDef, lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - assignmentDef, thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - assignmentDef, lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - assignmentDef, thisScanTimestamp, true)))) - ) - ); - ObjectQuery query0 = ObjectQuery.createObjectQuery(filter); - ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) .block() .item(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM).gt(lastScanTimestamp) @@ -2000,7 +1806,7 @@ public void test415ActivationQueryCorrect() throws Exception { public void test500OrgQuery() throws Exception { File objects = new File("src/test/resources/orgstruct/org-monkey-island.xml"); OperationResult opResult = new OperationResult("test500OrgQuery"); - List> orgStruct = prismContext.parseObjects(objects); + List> orgStruct = prismContext.parserFor(objects).parseObjects(); for (PrismObject o : orgStruct) { repositoryService.addObject((PrismObject) o, null, opResult); @@ -2038,9 +1844,10 @@ private void checkQueryResult(Class type, String oid, throws Exception { LOGGER.info("checkQueryResult"); - OrgFilter orgFilter = OrgFilter.createOrg(oid, scope); - ObjectQuery query = ObjectQuery.createObjectQuery(orgFilter); - query.setPaging(ObjectPaging.createPaging(null, null, F_NAME, ASCENDING)); + ObjectQuery query = QueryBuilder.queryFor(type, prismContext) + .isInScopeOf(oid, scope) + .asc(F_NAME) + .build(); query.setUseNewQueryInterpreter(true); OperationResult result = new OperationResult("checkQueryResult"); @@ -2049,13 +1856,13 @@ private void checkQueryResult(Class type, String oid, LOGGER.info("{}", object.getOid()); } int realCount = objects.size(); - assertEquals("Expected count doesn't match for searchObjects " + orgFilter, count, realCount); + assertEquals("Expected count doesn't match for searchObjects " + query, count, realCount); result.computeStatusIfUnknown(); AssertJUnit.assertTrue(result.isSuccess()); realCount = repositoryService.countObjects(type, query, result); - assertEquals("Expected count doesn't match for countObjects " + orgFilter, count, realCount); + assertEquals("Expected count doesn't match for countObjects " + query, count, realCount); result.computeStatusIfUnknown(); AssertJUnit.assertTrue(result.isSuccess()); @@ -2066,14 +1873,11 @@ public void test510QueryNameAndOrg() throws Exception { Session session = open(); try { - EqualFilter eqFilter = EqualFilter.createEqual(F_NAME, ObjectType.class, prismContext, - null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); - - OrgFilter orgFilter = OrgFilter.createOrg("12341234-1234-1234-1234-123412341234"); - - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(eqFilter, orgFilter)); - query.setPaging(ObjectPaging.createPaging(null, null, F_NAME, ASCENDING)); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(F_NAME).eqPoly("cpt. Jack Sparrow", "cpt jack sparrow") + .and().isChildOf("12341234-1234-1234-1234-123412341234") + .asc(F_NAME) + .build(); String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + @@ -2137,10 +1941,9 @@ public void test530queryUserSubstringName() throws Exception { Session session = open(); try { - SubstringFilter substring = SubstringFilter.createSubstring(F_NAME, ObjectType.class, - prismContext, PolyStringOrigMatchingRule.NAME, "a"); - substring.setAnchorStart(true); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(substring); + ObjectQuery objectQuery = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(F_NAME).startsWith("a").matchingOrig() + .build(); objectQuery.setUseNewQueryInterpreter(true); String real = getInterpretedQuery2(session, ObjectType.class, objectQuery); @@ -2162,9 +1965,9 @@ public void test530queryUserSubstringName() throws Exception { int count = repositoryService.countObjects(ObjectType.class, objectQuery, result); assertEquals(2, count); - substring = SubstringFilter.createSubstring(F_NAME, ObjectType.class, - prismContext, PolyStringOrigMatchingRule.NAME, "a"); - objectQuery = ObjectQuery.createObjectQuery(substring); + objectQuery = QueryBuilder.queryFor(ObjectType.class, prismContext) + .item(F_NAME).containsPoly("a").matchingOrig() + .build(); objectQuery.setUseNewQueryInterpreter(true); count = repositoryService.countObjects(ObjectType.class, objectQuery, result); assertEquals(20, count); @@ -2232,12 +2035,10 @@ public void test560queryMetadataTimestamp() throws Exception { try { XMLGregorianCalendar timeXml = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - - LessFilter less = LessFilter.createLess( - new ItemPath(ReportOutputType.F_METADATA, MetadataType.F_CREATE_TIMESTAMP), - ReportOutputType.class, prismContext, timeXml, true); - - String real = getInterpretedQuery2(session, ReportOutputType.class, ObjectQuery.createObjectQuery(less)); + ObjectQuery query = QueryBuilder.queryFor(ReportOutputType.class, prismContext) + .item(ReportOutputType.F_METADATA, MetadataType.F_CREATE_TIMESTAMP).le(timeXml) + .build(); + String real = getInterpretedQuery2(session, ReportOutputType.class, query); String expected = "select\n" + " r.fullObject,\n" + " r.stringsCount,\n" + @@ -2261,11 +2062,15 @@ public void test560queryMetadataTimestamp() throws Exception { public void test570queryObjectypeByTypeUserAndLocality() throws Exception { Session session = open(); try { - EqualFilter eq = EqualFilter.createEqual(new ItemPath(UserType.F_LOCALITY), UserType.class, prismContext, - new PolyString("Caribbean", "caribbean")); - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, eq); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .type(UserType.class) + .item(UserType.F_LOCALITY).eqPoly("Caribbean", "caribbean") + .build(); +// EqualFilter eq = EqualFilter.createEqual(new ItemPath(UserType.F_LOCALITY), UserType.class, prismContext, +// new PolyString("Caribbean", "caribbean")); +// TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, eq); - String real = getInterpretedQuery2(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); + String real = getInterpretedQuery2(session, ObjectType.class, query); String expected = "select\n" + " o.fullObject,\n" + " o.stringsCount,\n" + @@ -2326,11 +2131,12 @@ private void checkQueryTypeAlias(String query, String table, String... propertie public void test575QueryObjectypeByTypeOrgAndLocality() throws Exception { Session session = open(); try { - EqualFilter eq = EqualFilter.createEqual(new ItemPath(OrgType.F_LOCALITY), OrgType.class, prismContext, - new PolyString("Caribbean", "caribbean")); - TypeFilter type = TypeFilter.createType(OrgType.COMPLEX_TYPE, eq); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .type(OrgType.class) + .item(OrgType.F_LOCALITY).eqPoly("Caribbean", "caribbean") + .build(); - String real = getInterpretedQuery2(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); + String real = getInterpretedQuery2(session, ObjectType.class, query); String expected = "select\n" + " o.fullObject,\n" + " o.stringsCount,\n" + @@ -2360,12 +2166,17 @@ public void test575QueryObjectypeByTypeOrgAndLocality() throws Exception { public void test580QueryObjectypeByTypeAndExtensionAttribute() throws Exception { Session session = open(); try { - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "weapon")), - UserType.class, prismContext, "some weapon name"); - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, eq); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .type(UserType.class) + .item(UserType.F_EXTENSION, new QName("http://example.com/p", "weapon")).eq("some weapon name") + .build(); - RQueryImpl realQuery = (RQueryImpl) getInterpretedQuery2Whole(session, ObjectType.class, ObjectQuery.createObjectQuery(type), false); +// EqualFilter eq = EqualFilter.createEqual( +// new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "weapon")), +// UserType.class, prismContext, "some weapon name"); +// TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, eq); + + RQueryImpl realQuery = (RQueryImpl) getInterpretedQuery2Whole(session, ObjectType.class, query, false); String expected = "select\n" + " o.fullObject,\n" + " o.stringsCount,\n" + @@ -2394,10 +2205,12 @@ public void test580QueryObjectypeByTypeAndExtensionAttribute() throws Exception public void test590QueryObjectypeByTypeAndReference() throws Exception { Session session = open(); try { - RefFilter ref = RefFilter.createReferenceEqual(UserType.F_LINK_REF, UserType.class, prismContext, "123"); - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, ref); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .type(UserType.class) + .item(UserType.F_LINK_REF).ref("123") + .build(); - String real = getInterpretedQuery2(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); + String real = getInterpretedQuery2(session, ObjectType.class, query); String expected = "select\n" + " o.fullObject,\n" + " o.stringsCount,\n" + @@ -2428,20 +2241,19 @@ public void test590QueryObjectypeByTypeAndReference() throws Exception { public void test600QueryObjectypeByTypeComplex() throws Exception { Session session = open(); try { - EqualFilter eq1 = EqualFilter.createEqual(UserType.F_LOCALITY, UserType.class, prismContext, - new PolyString("Caribbean", "caribbean")); - EqualFilter eq2 = EqualFilter.createEqual(UserType.F_LOCALITY, UserType.class, prismContext, - new PolyString("Adriatic", "adriatic")); - TypeFilter type1 = TypeFilter.createType(UserType.COMPLEX_TYPE, OrFilter.createOr(eq1, eq2)); - - EqualFilter equal = EqualFilter.createEqual(OrgType.F_ORG_TYPE, OrgType.class, prismContext, "functional"); - TypeFilter type2 = TypeFilter.createType(OrgType.COMPLEX_TYPE, equal); - - TypeFilter type3 = TypeFilter.createType(ReportType.COMPLEX_TYPE, null); - - OrFilter or = OrFilter.createOr(type1, type2, type3); - - String real = getInterpretedQuery2(session, ObjectType.class, ObjectQuery.createObjectQuery(or)); + ObjectQuery query = QueryBuilder.queryFor(ObjectType.class, prismContext) + .type(UserType.class) + .block() + .item(UserType.F_LOCALITY).eqPoly("Caribbean", "caribbean") + .or().item(UserType.F_LOCALITY).eqPoly("Adriatic", "adriatic") + .endBlock() + .or().type(OrgType.class) + .block() + .item(OrgType.F_ORG_TYPE).eq("functional") + .endBlock() + .or().type(ReportType.class) + .build(); + String real = getInterpretedQuery2(session, ObjectType.class, query); String expected = "select\n" + " o.fullObject,\n" + " o.stringsCount,\n" + @@ -2586,11 +2398,10 @@ public void test606QueryObjectypeByTypeAndOwnerRefOverloaded() throws Exception public void test610QueryGenericClob() throws Exception { Session session = open(); try { - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "locations")), - GenericObjectType.class, prismContext, null); - - getInterpretedQuery2(session, GenericObjectType.class, ObjectQuery.createObjectQuery(eq)); + ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext) + .item(ObjectType.F_EXTENSION, new QName("http://example.com/p", "locations")).isNull() + .build(); + getInterpretedQuery2(session, GenericObjectType.class, query); } catch (QueryException ex) { LOGGER.info("Exception", ex); throw ex; @@ -2603,11 +2414,10 @@ public void test610QueryGenericClob() throws Exception { public void test620QueryGenericString() throws Exception { Session session = open(); try { - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "stringType")), - GenericObjectType.class, prismContext, "asdf"); - - String real = getInterpretedQuery2(session, GenericObjectType.class, ObjectQuery.createObjectQuery(eq)); + ObjectQuery query = QueryBuilder.queryFor(GenericObjectType.class, prismContext) + .item(ObjectType.F_EXTENSION, new QName("http://example.com/p", "stringType")).eq("asdf") + .build(); + String real = getInterpretedQuery2(session, GenericObjectType.class, query); String expected = "select\n" + " g.fullObject,\n" + " g.stringsCount,\n" + @@ -2636,11 +2446,11 @@ public void test620QueryGenericString() throws Exception { // // List secondaryEquals = new ArrayList<>(); // EqualFilter eq = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstantsGenerated.ICF_S_UID), -// new PrismPropertyDefinition(SchemaConstantsGenerated.ICF_S_UID, DOMUtil.XSD_STRING, prismContext), +// new PrismPropertyDefinitionImpl(SchemaConstantsGenerated.ICF_S_UID, DOMUtil.XSD_STRING, prismContext), // "8daaeeae-f0c7-41c9-b258-2a3351aa8876"); // secondaryEquals.add(eq); // eq = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstantsGenerated.ICF_S_NAME), -// new PrismPropertyDefinition(SchemaConstantsGenerated.ICF_S_NAME, DOMUtil.XSD_STRING, prismContext), +// new PrismPropertyDefinitionImpl(SchemaConstantsGenerated.ICF_S_NAME, DOMUtil.XSD_STRING, prismContext), // "some-name"); // secondaryEquals.add(eq); // @@ -2674,11 +2484,9 @@ public void test620QueryGenericString() throws Exception { public void test630QueryGenericBoolean() throws Exception { Session session = open(); try { - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, SKIP_AUTOGENERATION), - GenericObjectType.class, prismContext, true); - - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(eq); + ObjectQuery objectQuery = QueryBuilder.queryFor(GenericObjectType.class, prismContext) + .item(ObjectType.F_EXTENSION, SKIP_AUTOGENERATION).eq(true) + .build(); objectQuery.setUseNewQueryInterpreter(true); RQueryImpl realQuery = (RQueryImpl) getInterpretedQuery2Whole(session, GenericObjectType.class, objectQuery, false); @@ -2729,13 +2537,11 @@ public void test640queryAssignmentExtensionBoolean() throws Exception { SchemaRegistry registry = prismContext.getSchemaRegistry(); PrismObjectDefinition userDef = registry.findObjectDefinitionByCompileTimeClass(UserType.class); PrismContainerDefinition assignmentDef = userDef.findContainerDefinition(F_ASSIGNMENT); - PrismPropertyDefinition propDef = assignmentDef.createPropertyDefinition(SKIP_AUTOGENERATION, DOMUtil.XSD_BOOLEAN); + PrismPropertyDefinition propDef = ((PrismContainerDefinitionImpl) assignmentDef).createPropertyDefinition(SKIP_AUTOGENERATION, DOMUtil.XSD_BOOLEAN); - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(F_ASSIGNMENT, AssignmentType.F_EXTENSION, SKIP_AUTOGENERATION), - propDef, null, true); - - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(eq); + ObjectQuery objectQuery = QueryBuilder.queryFor(UserType.class, prismContext) + .itemWithDef(propDef, F_ASSIGNMENT, AssignmentType.F_EXTENSION, SKIP_AUTOGENERATION).eq(true) + .build(); objectQuery.setUseNewQueryInterpreter(true); String real = getInterpretedQuery2(session, UserType.class, objectQuery); @@ -2816,12 +2622,10 @@ public void test710QueryCertCaseOwner() throws Exception { public void test720QueryCertCaseOwnerAndTarget() throws Exception { Session session = open(); try { - PrismContainerDefinition caseDef = - prismContext.getSchemaRegistry().findContainerDefinitionByCompileTimeClass(AccessCertificationCaseType.class); - AndFilter filter = AndFilter.createAnd( - InOidFilter.createOwnerHasOidIn("123456"), - RefFilter.createReferenceEqual(new ItemPath(AccessCertificationCaseType.F_TARGET_REF), caseDef, "1234567890")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) + .ownerId("123456") + .and().item(AccessCertificationCaseType.F_TARGET_REF).ref("1234567890") + .build(); String real = getInterpretedQuery2(session, AccessCertificationCaseType.class, query, false); String expected = "select\n" + " a.fullObject, a.ownerOid\n" + @@ -2845,10 +2649,9 @@ public void test720QueryCertCaseOwnerAndTarget() throws Exception { public void test730QueryCertCaseReviewer() throws Exception { Session session = open(); try { - PrismContainerDefinition caseDef = - prismContext.getSchemaRegistry().findContainerDefinitionByCompileTimeClass(AccessCertificationCaseType.class); - ObjectFilter filter = RefFilter.createReferenceEqual(new ItemPath(F_CURRENT_REVIEWER_REF), caseDef, "1234567890"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) + .item(F_CURRENT_REVIEWER_REF).ref("1234567890") + .build(); String real = getInterpretedQuery2(session, AccessCertificationCaseType.class, query, false); String expected = "select\n" + " a.fullObject, a.ownerOid\n" + @@ -3034,10 +2837,9 @@ public void test750DereferenceLink() throws Exception { * ### UserType: linkRef/@/name contains 'test.com' */ - ObjectFilter filter = SubstringFilter.createSubstring( - new ItemPath(UserType.F_LINK_REF, PrismConstants.T_OBJECT_REFERENCE, F_NAME), - UserType.class, prismContext, "test.com"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_LINK_REF, PrismConstants.T_OBJECT_REFERENCE, F_NAME).containsPoly("test.com") + .build(); String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + @@ -3072,12 +2874,11 @@ public void test752DereferenceLinkedResourceName() throws Exception { * ### UserType: linkRef/@/resourceRef/@/name contains 'CSV' (norm) */ - ObjectFilter filter = SubstringFilter.createSubstring( - new ItemPath(UserType.F_LINK_REF, PrismConstants.T_OBJECT_REFERENCE, + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_LINK_REF, PrismConstants.T_OBJECT_REFERENCE, ShadowType.F_RESOURCE_REF, PrismConstants.T_OBJECT_REFERENCE, - F_NAME), - UserType.class, prismContext, PolyStringNormMatchingRule.NAME, "CSV"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + F_NAME).containsPoly("CSV").matchingNorm() + .build(); String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + @@ -3102,7 +2903,7 @@ public void test752DereferenceLinkedResourceName() throws Exception { } } - @Test(expectedExceptions = IllegalStateException.class) // at this time + @Test(expectedExceptions = IllegalArgumentException.class) // at this time public void test760DereferenceAssignedRoleType() throws Exception { Session session = open(); @@ -3115,10 +2916,14 @@ public void test760DereferenceAssignedRoleType() throws Exception { * ### UserType: assignment/targetRef/@/roleType */ - ObjectFilter filter = EqualFilter.createEqual( - new ItemPath(F_ASSIGNMENT, AssignmentType.F_TARGET_REF, PrismConstants.T_OBJECT_REFERENCE, RoleType.F_ROLE_TYPE), - UserType.class, prismContext, "type1"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(F_ASSIGNMENT, AssignmentType.F_TARGET_REF, PrismConstants.T_OBJECT_REFERENCE, RoleType.F_ROLE_TYPE).eq("type1") + .build(); +// +// ObjectFilter filter = EqualFilter.createEqual( +// new ItemPath(), +// UserType.class, prismContext, "type1"); +// ObjectQuery query = ObjectQuery.createObjectQuery(filter); String real = getInterpretedQuery2(session, UserType.class, query); @@ -3136,11 +2941,9 @@ public void test770CaseParentFilter() throws Exception { * ### AccessCertificationCaseType: Equal(../name, 'Campaign 1') */ - ObjectFilter filter = EqualFilter.createEqual( - new ItemPath(T_PARENT, F_NAME), - AccessCertificationCaseType.class, prismContext, "Campaign 1"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) + .item(T_PARENT, F_NAME).eq("Campaign 1") + .build(); String real = getInterpretedQuery2(session, AccessCertificationCaseType.class, query); String expected = "select\n" + " a.fullObject, a.ownerOid\n" + @@ -3257,15 +3060,16 @@ public void test900EqualsMultivalue() throws Exception { PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); PrismPropertyDefinition prefLangDef = userDef.findPropertyDefinition(UserType.F_PREFERRED_LANGUAGE); - PrismPropertyDefinition multivalDef = new PrismPropertyDefinition(UserType.F_PREFERRED_LANGUAGE, + PrismPropertyDefinitionImpl multivalDef = new PrismPropertyDefinitionImpl(UserType.F_PREFERRED_LANGUAGE, DOMUtil.XSD_STRING, prismContext); multivalDef.setMaxOccurs(-1); PrismProperty multivalProperty = multivalDef.instantiate(); multivalProperty.addRealValue("SK"); multivalProperty.addRealValue("HU"); - ObjectQuery query = ObjectQuery.createObjectQuery( - EqualFilter.createEqual(new ItemPath(UserType.F_PREFERRED_LANGUAGE), multivalProperty)); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_PREFERRED_LANGUAGE).eq(multivalProperty) + .build(); String real = getInterpretedQuery2(session, UserType.class, query); // assertEqualsIgnoreWhitespace(expected, real); @@ -3282,14 +3086,9 @@ public void test910PreferredLanguageEqualsCostCenter() throws Exception { /* * ### User: preferredLanguage = costCenter */ - ObjectQuery query = ObjectQuery.createObjectQuery( - EqualFilter.createEqual( - new ItemPath(UserType.F_PREFERRED_LANGUAGE), - UserType.class, - prismContext, - null, - new ItemPath(UserType.F_COST_CENTER))); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_PREFERRED_LANGUAGE).eq().item(UserType.F_COST_CENTER) + .build(); String real = getInterpretedQuery2(session, UserType.class, query); String expected = "select\n" + " u.fullObject,\n" + @@ -3323,14 +3122,9 @@ public void test915OrganizationEqualsCostCenter() throws Exception { /* * ### User: organization = costCenter */ - ObjectQuery query = ObjectQuery.createObjectQuery( - EqualFilter.createEqual( - new ItemPath(UserType.F_ORGANIZATION), - UserType.class, - prismContext, - null, - new ItemPath(UserType.F_COST_CENTER))); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ORGANIZATION).eq(UserType.F_COST_CENTER) + .build(); String real = getInterpretedQuery2(session, UserType.class, query); // assertEqualsIgnoreWhitespace(expected, real); } finally { diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreterTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreterTest.java deleted file mode 100644 index 582bbb2b47a..00000000000 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreterTest.java +++ /dev/null @@ -1,1864 +0,0 @@ -/* - * Copyright (c) 2010-2013 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.evolveum.midpoint.repo.sql; - -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; -import com.evolveum.midpoint.prism.match.PolyStringOrigMatchingRule; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.query.*; -import com.evolveum.midpoint.prism.schema.SchemaRegistry; -import com.evolveum.midpoint.prism.util.PrismTestUtil; -import com.evolveum.midpoint.prism.xml.XmlTypeConverter; -import com.evolveum.midpoint.repo.sql.data.common.*; -import com.evolveum.midpoint.repo.sql.data.common.enums.RActivationStatus; -import com.evolveum.midpoint.repo.sql.data.common.enums.RTaskExecutionStatus; -import com.evolveum.midpoint.repo.sql.data.common.other.RAssignmentOwner; -import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sql.data.common.type.RAssignmentExtensionType; -import com.evolveum.midpoint.repo.sql.data.common.type.RObjectExtensionType; -import com.evolveum.midpoint.repo.sql.query.QueryException; -import com.evolveum.midpoint.repo.sql.type.XMLGregorianCalendarType; -import com.evolveum.midpoint.repo.sql.util.HibernateToSqlTranslator; -import com.evolveum.midpoint.schema.MidPointPrismContextFactory; -import com.evolveum.midpoint.schema.constants.MidPointConstants; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.QNameUtil; -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.xml.ns._public.common.common_3.*; - -import org.hibernate.Criteria; -import org.hibernate.Session; -import org.hibernate.criterion.*; -import org.hibernate.sql.JoinType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.testng.AssertJUnit; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.Test; -import org.xml.sax.SAXException; - -import javax.xml.datatype.XMLGregorianCalendar; -import javax.xml.namespace.QName; - -import java.io.File; -import java.io.IOException; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -/** - * @author lazyman - */ -@ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -public class QueryInterpreterTest extends BaseSQLRepoTest { - - private static final Trace LOGGER = TraceManager.getTrace(QueryInterpreterTest.class); - private static final File TEST_DIR = new File("./src/test/resources/query"); - - private static final QName SKIP_AUTOGENERATION = new QName("http://example.com/p", "skipAutogeneration"); - - @BeforeSuite - public void setup() throws SchemaException, SAXException, IOException { - PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); - PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); - } - - @BeforeClass - public void beforeClass() throws Exception { - super.beforeClass(); - - PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); - - List> objects = prismContext.parseObjects( - new File(FOLDER_BASIC, "objects.xml")); - OperationResult result = new OperationResult("add objects"); - for (PrismObject object : objects) { - repositoryService.addObject(object, null, result); - } - - result.recomputeStatus(); - AssertJUnit.assertTrue(result.isSuccess()); - } - - @Test - public void queryOrganizationNorm() throws Exception { - Session session = open(); - - try { - /* - * ### user: Equal (organization, "asdf", PolyStringNorm) - * ==> from RUser u left join u.organization o where o.norm = 'asdf' - */ - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, - PolyStringNormMatchingRule.NAME, new PolyString("asdf", "asdf")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - Criteria o = main.createCriteria("organization", "o", JoinType.LEFT_OUTER_JOIN); - - o.add(Restrictions.eq("o.norm", "asdf")); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, UserType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryOrganizationOrig() throws Exception { - Session session = open(); - try { - /* - * ### user: Equal (organization, "asdf", PolyStringOrig) - * ==> from RUser u left join u.organization o where o.orig = 'asdf' - */ - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, - PolyStringOrigMatchingRule.NAME, new PolyString("asdf", "asdf")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - Criteria o = main.createCriteria("organization", "o", JoinType.LEFT_OUTER_JOIN); - - o.add(Restrictions.eq("o.orig", "asdf")); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, UserType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryOrganizationStrict() throws Exception { - Session session = open(); - try { - /* - * ### user: Equal (organization, "asdf") - * ==> from RUser u left join u.organization o where o.orig = 'asdf' and o.norm = 'asdf' - */ - - ObjectFilter filter = EqualFilter.createEqual(UserType.F_ORGANIZATION, UserType.class, prismContext, - null, new PolyString("asdf", "asdf")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - Criteria o = main.createCriteria("organization", "o", JoinType.LEFT_OUTER_JOIN); - - o.add(Restrictions.conjunction() - .add(Restrictions.eq("o.orig", "asdf")) - .add(Restrictions.eq("o.norm", "asdf"))); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, UserType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryDependent() throws Exception { - Session session = open(); - - try { - /* - * ### task: Equal (dependent, "123456") - * ==> from RTask t left join t.dependent d where d = '123456' (why "d.elements" ????) - */ - Criteria main = session.createCriteria(RTask.class, "t"); - Criteria d = main.createCriteria("dependent", "d", JoinType.LEFT_OUTER_JOIN); - d.add(Restrictions.eq("d.elements", "123456")); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("t", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - ObjectFilter filter = EqualFilter.createEqual(TaskType.F_DEPENDENT, TaskType.class, prismContext, null, "123456"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, TaskType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test(expectedExceptions = QueryException.class) - public void queryClob() throws Exception { - Session session = open(); - - try { - ObjectFilter filter = EqualFilter.createEqual(UserType.F_DESCRIPTION, UserType.class, prismContext, - null, "aaa"); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - //should throw exception, because description is lob and can't be queried - getInterpretedQuery(session, UserType.class, query); - } finally { - close(session); - } - } - - @Test - public void queryEnum() throws Exception { - Session session = open(); - try { - /* - * ### task: Equal (executionStatus, WAITING) - * ==> from RTask t where t.executionStatus = com.evolveum.midpoint.repo.sql.data.common.enums.RTaskExecutionStatus.WAITING - */ - Criteria main = session.createCriteria(RTask.class, "t"); - main.add(Restrictions.eq("executionStatus", RTaskExecutionStatus.WAITING)); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("t", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - ObjectFilter filter = EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, TaskType.class, prismContext, - null, TaskExecutionStatusType.WAITING); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, TaskType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryEnabled() throws Exception { - Session session = open(); - try { - /* - * ### task: Equal (activation/administrativeStatus, ENABLED) - * ==> from RUser u where u.activation.administrativeStatus = com.evolveum.midpoint.repo.sql.data.common.enums.RActivationStatus.ENABLED - */ - - Criteria main = session.createCriteria(RUser.class, "u"); - main.add(Restrictions.eq("activation.administrativeStatus", RActivationStatus.ENABLED)); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, UserType.class, - new File(TEST_DIR, "query-user-by-enabled.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryGenericLong() throws Exception { - Session session = open(); - try { - /* - * ### generic: And (Equal (name, "generic object", PolyStringNorm), - * Equal (c:extension/p:intType, 123)) - * ==> from RGenericObject g left join g.longs l where - * g.name.norm = 'generic object' and - * l.ownerType = com.evolveum.midpoint.repo.sql.data.common.type.RObjectExtensionType.EXTENSION and - * l.name = 'http://example.com/p#intType' and - * l.value = 123 - */ - Criteria main = session.createCriteria(RGenericObject.class, "g"); - - Criteria stringExt = main.createCriteria("longs", "l", JoinType.LEFT_OUTER_JOIN); - - //and - Criterion c1 = Restrictions.eq("name.norm", "generic object"); - //and - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("l.ownerType", RObjectExtensionType.EXTENSION)); - c2.add(Restrictions.eq("l.name", new QName("http://example.com/p", "intType"))); - c2.add(Restrictions.eq("l.value", 123L)); - - Conjunction conjunction = Restrictions.conjunction(); - conjunction.add(c1); - conjunction.add(c2); - main.add(conjunction); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("g", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, GenericObjectType.class, - new File(TEST_DIR, "query-and-generic.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryOrComposite() throws Exception { - Session session = open(); - try { - /* - * ### shadow: - * Or ( - * Equal (intent, "some account type"), - * Equal (attributes/f:foo, "foo value"), - * Equal (extension/p:stringType, "uid=test,dc=example,dc=com"), - * Ref (resourceRef, d0db5be9-cb93-401f-b6c1-86ffffe4cd5e)) - * - * ==> from RShadow r left join r.strings s1 where - * r.intent = 'some account type' or - * (s1.ownerType = RObjectExtensionType.ATTRIBUTES and s1.name = 'http://midpoint.evolveum.com/blabla#foo' and s1.value = 'foo value') or - * (s1.ownerType = RObjectExtensionType.EXTENSION and s1.name = 'http://example.com/p#stringType' and s1.value = 'uid=test,dc=example,dc=com') or - * (r.resourceRef.targetOid = 'd0db5be9-cb93-401f-b6c1-86ffffe4cd5e' and r.resourceRef.relation = '#' and r.resourceRef.type = '...#ResourceType') - * - * [If we used AND instead of OR, this SHOULD BE left join r.strings s1, left join r.strings s2] - */ - Criteria main = session.createCriteria(RShadow.class, "r"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("r", projections, false); - main.setProjection(projections); - - Criteria stringExt = main.createCriteria("strings", "s1", JoinType.LEFT_OUTER_JOIN); - - //or - Criterion c1 = Restrictions.eq("intent", "some account type"); - //or - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("s1.ownerType", RObjectExtensionType.ATTRIBUTES)); - c2.add(Restrictions.eq("s1.name", new QName("http://midpoint.evolveum.com/blabla", "foo"))); - c2.add(Restrictions.eq("s1.value", "foo value")); - //or - Conjunction c3 = Restrictions.conjunction(); - c3.add(Restrictions.eq("s1.ownerType", RObjectExtensionType.EXTENSION)); - c3.add(Restrictions.eq("s1.name", new QName("http://example.com/p", "stringType"))); - c3.add(Restrictions.eq("s1.value", "uid=test,dc=example,dc=com")); - //or - Conjunction c4 = Restrictions.conjunction(); - c4.add(Restrictions.eq("r.resourceRef.targetOid", "d0db5be9-cb93-401f-b6c1-86ffffe4cd5e")); - c4.add(Restrictions.eq("r.resourceRef.relation", "#")); - c4.add(Restrictions.eq("r.resourceRef.type", QNameUtil.qNameToUri(ResourceType.COMPLEX_TYPE))); - - Disjunction disjunction = Restrictions.disjunction(); - disjunction.add(c1); - disjunction.add(c2); - disjunction.add(c3); - disjunction.add(c4); - main.add(disjunction); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, ShadowType.class, - new File(TEST_DIR, "query-or-composite.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryObjectByName() throws Exception { - Session session = open(); - - try { - /* - * ### object: Equal (name, "cpt. Jack Sparrow") - * Order by name, ASC - * - * ==> from RObject o where name.orig = 'cpt. Jack Sparrow' and name.norm = 'cpt jack sparrow' - * order by name.orig asc - */ - Criteria main = session.createCriteria(RObject.class, "o"); - main.add(Restrictions.and( - Restrictions.eq("name.orig", "cpt. Jack Sparrow"), - Restrictions.eq("name.norm", "cpt jack sparrow"))); - main.addOrder(Order.asc("name.orig")); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter filter = EqualFilter.createEqual(ObjectType.F_NAME, ObjectType.class, prismContext, - null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - query.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - - String real = getInterpretedQuery(session, ObjectType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryUserByFullName() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - main.add(Restrictions.eq("fullName.norm", "cpt jack sparrow")); - String expected = HibernateToSqlTranslator.toSql(main); - - String real = getInterpretedQuery(session, UserType.class, - new File(TEST_DIR, "query-user-by-fullName.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryUserSubstringFullName() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - main.add(Restrictions.like("fullName.norm", "%cpt jack sparrow%").ignoreCase()); - String expected = HibernateToSqlTranslator.toSql(main); - - String real = getInterpretedQuery(session, UserType.class, - new File(TEST_DIR, "query-user-substring-fullName.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryUserByName() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - main.setProjection(projections); - addFullObjectProjectionList("u", projections, false); - - main.add(Restrictions.eq("name.norm", "some name identificator")); - String expected = HibernateToSqlTranslator.toSql(main); - - String real = getInterpretedQuery(session, UserType.class, - new File(TEST_DIR, "query-user-by-name.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryConnectorByType() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RConnector.class, "c"); - Criterion connectorType = Restrictions.conjunction().add( - Restrictions.eq("connectorType", "org.identityconnectors.ldap.LdapConnector")); - main.add(connectorType); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("c", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - String real = getInterpretedQuery(session, ConnectorType.class, - new File(TEST_DIR, "query-connector-by-type.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryAccountByAttributesAndResourceRef() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RShadow.class, "r"); - - Criteria stringAttr = main.createCriteria("strings", "s1x", JoinType.LEFT_OUTER_JOIN); - - //and - Conjunction c1 = Restrictions.conjunction(); - c1.add(Restrictions.eq("r.resourceRef.targetOid", "aae7be60-df56-11df-8608-0002a5d5c51b")); - c1.add(Restrictions.eq("r.resourceRef.relation", "#")); - c1.add(Restrictions.eq("r.resourceRef.type", QNameUtil.qNameToUri(ResourceType.COMPLEX_TYPE))); - //and - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("s1x.ownerType", RObjectExtensionType.ATTRIBUTES)); - c2.add(Restrictions.eq("s1x.name", new QName("http://midpoint.evolveum.com/blabla", "foo"))); - c2.add(Restrictions.eq("s1x.value", "uid=jbond,ou=People,dc=example,dc=com")); - - Conjunction conjunction = Restrictions.conjunction(); - conjunction.add(c1); - conjunction.add(c2); - main.add(conjunction); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("r", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - String real = getInterpretedQuery(session, ShadowType.class, - new File(TEST_DIR, "query-account-by-attributes-and-resource-ref.xml")); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryUserAccountRef() throws Exception { - Session session = open(); - try { - /* - * ### user: Ref (linkRef, 123) - * - * ==> select from RUser u left join u.linkRef l where - * l.targetOid = '123' and l.relation = '#' - */ - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - Criteria refs = main.createCriteria("linkRef", "l", JoinType.LEFT_OUTER_JOIN); - Conjunction c = Restrictions.conjunction(); - c.add(Restrictions.eq("l.targetOid", "123")); - c.add(Restrictions.eq("l.relation", "#")); - refs.add(c); - - String expected = HibernateToSqlTranslator.toSql(main); - - RefFilter filter = RefFilter.createReferenceEqual(UserType.F_LINK_REF, UserType.class, prismContext, "123"); - String real = getInterpretedQuery(session, UserType.class, ObjectQuery.createObjectQuery(filter)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryUserAssignmentTargetRef() throws Exception { - Session session = open(); - try { - /* - * ### user: Ref (assignment/targetRef, '123', RoleType) - * - * ==> select from RUser u left join u.assignments a where - * a.assignmentOwner = RAssignmentOwner.FOCUS and - * a.targetRef.targetOid = '123' and - * a.targetRef.relation = '#' and - * a.targetRef.type = RObjectType.ROLE - */ - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - Criteria a = main.createCriteria("assignments", "a", JoinType.LEFT_OUTER_JOIN); - Conjunction c0 = Restrictions.conjunction(); - c0.add(Restrictions.eq("a.assignmentOwner", RAssignmentOwner.FOCUS)); - Conjunction c1 = Restrictions.conjunction(); - c1.add(Restrictions.eq("a.targetRef.targetOid", "123")); - c1.add(Restrictions.eq("a.targetRef.relation", "#")); - c1.add(Restrictions.eq("a.targetRef.type", RObjectType.ROLE)); - c0.add(c1); - a.add(c0); - - String expected = HibernateToSqlTranslator.toSql(main); - - ObjectReferenceType ort = new ObjectReferenceType(); - ort.setOid("123"); - ort.setType(RoleType.COMPLEX_TYPE); - RefFilter filter = RefFilter.createReferenceEqual( - new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), - UserType.class, prismContext, ort.asReferenceValue()); - String real = getInterpretedQuery(session, UserType.class, ObjectQuery.createObjectQuery(filter)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - - @Test - public void queryTrigger() throws Exception { - final Date NOW = new Date(); - - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Criteria d = main.createCriteria("trigger", "t", JoinType.LEFT_OUTER_JOIN); - d.add(Restrictions.le("t.timestamp", new Timestamp(NOW.getTime()))); - - String expected = HibernateToSqlTranslator.toSql(main); - - XMLGregorianCalendar thisScanTimestamp = XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime()); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(ObjectType.class); - ItemPath triggerPath = new ItemPath(ObjectType.F_TRIGGER, TriggerType.F_TIMESTAMP); - // PrismContainerDefinition triggerContainerDef = objectDef.findContainerDefinition(triggerPath); - ObjectFilter filter = LessFilter.createLess(triggerPath, objectDef, thisScanTimestamp, true); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, ObjectType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryAssignmentActivationAdministrativeStatus() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RUser.class, "u"); - Criteria a = main.createCriteria("assignments", "a", JoinType.LEFT_OUTER_JOIN); - a.add(Restrictions.and( - Restrictions.eq("a.assignmentOwner", RAssignmentOwner.FOCUS), - Restrictions.eq("a.activation.administrativeStatus", RActivationStatus.ENABLED) - )); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(UserType.class); - ItemPath activationPath = new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - - // PrismContainerDefinition activationDef = objectDef.findContainerDefinition(activationPath); - - ObjectFilter filter = EqualFilter.createEqual(activationPath, objectDef, ActivationStatusType.ENABLED); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, UserType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryInducementActivationAdministrativeStatus() throws Exception { - Session session = open(); - try { - /* - * ### role: Equal (inducement/activation/administrativeStatus, ENABLED) - * - * ==> select from RRole r left join r.assignments a where - * a.assignmentOwner = RAssignmentOwner.ABSTRACT_ROLE and <--- this differentiates inducements from assignments - * a.activation.administrativeStatus = RActivationStatus.ENABLED - */ - Criteria main = session.createCriteria(RRole.class, "r"); - Criteria a = main.createCriteria("assignments", "a", JoinType.LEFT_OUTER_JOIN); - a.add(Restrictions.and( - Restrictions.eq("a.assignmentOwner", RAssignmentOwner.ABSTRACT_ROLE), - Restrictions.eq("a.activation.administrativeStatus", RActivationStatus.ENABLED) - )); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("r", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(RoleType.class); - ItemPath activationPath = new ItemPath(RoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - - // PrismContainerDefinition activationDef = objectDef.findContainerDefinition(activationPath); - - ObjectFilter filter = EqualFilter.createEqual(activationPath, objectDef, ActivationStatusType.ENABLED); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, RoleType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryInducementAndAssignmentActivationAdministrativeStatus() throws Exception { - Session session = open(); - try { - /* - * ### Role: Or (Equal (assignment/activation/administrativeStatus, RActivationStatus.ENABLED), - * Equal (inducement/activation/administrativeStatus, RActivationStatus.ENABLED)) - * - * ==> select r from RRole r left join r.assignments a where - * (a.assignmentOwner = com.evolveum.midpoint.repo.sql.data.common.other.RAssignmentOwner.FOCUS and - * a.activation.administrativeStatus = com.evolveum.midpoint.repo.sql.data.common.enums.RActivationStatus.ENABLED) or - * (a.assignmentOwner = com.evolveum.midpoint.repo.sql.data.common.other.RAssignmentOwner.ABSTRACT_ROLE and - * a.activation.administrativeStatus = com.evolveum.midpoint.repo.sql.data.common.enums.RActivationStatus.ENABLED) - * - * (may return duplicate results) - */ - Criteria main = session.createCriteria(RRole.class, "r"); - Criteria a = main.createCriteria("assignments", "a", JoinType.LEFT_OUTER_JOIN); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("r", projections, false); - main.setProjection(projections); - - Criterion and1 = Restrictions.and( - Restrictions.eq("a.assignmentOwner", RAssignmentOwner.FOCUS), - Restrictions.eq("a.activation.administrativeStatus", RActivationStatus.ENABLED) - ); - - Criterion and2 = Restrictions.and( - Restrictions.eq("a.assignmentOwner", RAssignmentOwner.ABSTRACT_ROLE), - Restrictions.eq("a.activation.administrativeStatus", RActivationStatus.ENABLED) - ); - - a.add(Restrictions.or(and1, and2)); - - String expected = HibernateToSqlTranslator.toSql(main); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(RoleType.class); - - //filter1 - ItemPath activationPath1 = new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - // PrismContainerDefinition activationDef1 = objectDef.findContainerDefinition(activationPath1); - ObjectFilter filter1 = EqualFilter.createEqual(activationPath1, objectDef, ActivationStatusType.ENABLED); - - //filter2 - ItemPath activationPath2 = new ItemPath(RoleType.F_INDUCEMENT, AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); - // PrismContainerDefinition activationDef2 = objectDef.findContainerDefinition(activationPath2); - ObjectFilter filter2 = EqualFilter.createEqual(activationPath2, objectDef, ActivationStatusType.ENABLED); - - ObjectQuery query = ObjectQuery.createObjectQuery(OrFilter.createOr(filter1, filter2)); - String real = getInterpretedQuery(session, RoleType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryUserByActivationDouble() throws Exception { - Date NOW = new Date(); - - Session session = open(); - try { - /* - * ### user: And (Equal (activation/administrativeStatus, RActivationStatus.ENABLED), - * Equal (activation/validFrom, '...')) - * - * ==> select u from RUser u where u.activation.administrativeStatus = RActivationStatus.ENABLED and - * u.activation.validFrom = ... - */ - Criteria main = session.createCriteria(RUser.class, "u"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("u", projections, false); - main.setProjection(projections); - - main.add(Restrictions.and( - Restrictions.eq("u.activation.administrativeStatus", RActivationStatus.ENABLED), - Restrictions.eq("u.activation.validFrom", XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime())))); - - String expected = HibernateToSqlTranslator.toSql(main); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(UserType.class); - // ItemPath triggerPath = new ItemPath(AssignmentType.F_ACTIVATION); - - // PrismContainerDefinition triggerContainerDef = objectDef.findContainerDefinition(triggerPath); - - ObjectFilter filter1 = EqualFilter.createEqual(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS), objectDef, - ActivationStatusType.ENABLED); - - ObjectFilter filter2 = EqualFilter.createEqual(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_VALID_FROM), objectDef, - XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime())); - - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(filter1, filter2)); - String real = getInterpretedQuery(session, UserType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryTriggerTimestampDouble() throws Exception { - final Date NOW = new Date(); - - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Criteria d = main.createCriteria("trigger", "t", JoinType.LEFT_OUTER_JOIN); - d.add(Restrictions.and( - Restrictions.gt("t.timestamp", new Timestamp(NOW.getTime())), - Restrictions.lt("t.timestamp", new Timestamp(NOW.getTime())) - )); - - String expected = HibernateToSqlTranslator.toSql(main); - - XMLGregorianCalendar thisScanTimestamp = XmlTypeConverter.createXMLGregorianCalendar(NOW.getTime()); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition objectDef = registry.findObjectDefinitionByCompileTimeClass(ObjectType.class); - ItemPath triggerPath = new ItemPath(ObjectType.F_TRIGGER, TriggerType.F_TIMESTAMP); - // PrismContainerDefinition triggerContainerDef = objectDef.findContainerDefinition(triggerPath); - ObjectFilter greater = GreaterFilter.createGreater(triggerPath, objectDef, thisScanTimestamp, false); - ObjectFilter lesser = LessFilter.createLess(triggerPath, objectDef, thisScanTimestamp, false); - AndFilter and = AndFilter.createAnd(greater, lesser); - LOGGER.info(and.debugDump()); - - ObjectQuery query = ObjectQuery.createObjectQuery(and); - String real = getInterpretedQuery(session, ObjectType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - private void addFullObjectProjectionList(String prefix, ProjectionList list, boolean group) { - if (prefix == null) { - prefix = ""; - } else { - prefix = prefix + "."; - } - - if (group) { - list.add(Projections.groupProperty(prefix + "fullObject")); - list.add(Projections.groupProperty(prefix + "stringsCount")); - list.add(Projections.groupProperty(prefix + "longsCount")); - list.add(Projections.groupProperty(prefix + "datesCount")); - list.add(Projections.groupProperty(prefix + "referencesCount")); - list.add(Projections.groupProperty(prefix + "polysCount")); - list.add(Projections.groupProperty(prefix + "booleansCount")); - } else { - list.add(Projections.property(prefix + "fullObject")); - list.add(Projections.property(prefix + "stringsCount")); - list.add(Projections.property(prefix + "longsCount")); - list.add(Projections.property(prefix + "datesCount")); - list.add(Projections.property(prefix + "referencesCount")); - list.add(Projections.property(prefix + "polysCount")); - list.add(Projections.property(prefix + "booleansCount")); - } - } - - @Test - public void countObjectOrderByName() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RUser.class, "u"); - main.add(Restrictions.and( - Restrictions.eq("u.name.orig", "cpt. Jack Sparrow"), - Restrictions.eq("u.name.norm", "cpt jack sparrow"))); - main.setProjection(Projections.rowCount()); - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter filter = EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, - null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - query.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - - String real = getInterpretedQuery(session, UserType.class, query, true); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void countObjectOrderByNameWithoutFilter() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RObject.class, "o"); - main.setProjection(Projections.rowCount()); - String expected = HibernateToSqlTranslator.toSql(main); - - ObjectPaging paging = ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING); - ObjectQuery query = ObjectQuery.createObjectQuery(null, paging); - - String real = getInterpretedQuery(session, ObjectType.class, query, true); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - /** - * Q{AND: (EQUALS: parent, PPV(null)),PAGING: O: 0,M: 5,BY: name, D:ASCENDING, - * - * @throws Exception - */ - @Test - public void countTaskOrderByName() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RTask.class, "t"); - main.add(Restrictions.isNull("t.parent")); - - main.setProjection(Projections.rowCount()); - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter filter = EqualFilter.createEqual(TaskType.F_PARENT, TaskType.class, prismContext, null); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - query.setPaging(ObjectPaging.createPaging(null, null, TaskType.F_NAME, OrderDirection.ASCENDING)); - - String real = getInterpretedQuery(session, TaskType.class, query, true); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void inOidTest() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - main.add(Restrictions.in("oid", Arrays.asList("1", "2"))); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - InOidFilter filter = InOidFilter.createInOid(Arrays.asList("1", "2")); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, ObjectType.class, query, false); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void queryOrgTreeFindOrgs() throws Exception { - Session session = open(); - - try { - - Criteria main = session.createCriteria(ROrg.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - DetachedCriteria detached = DetachedCriteria.forClass(RObjectReference.class, "p"); - detached.add(Restrictions.eq("referenceType", 0)); - detached.setProjection(Projections.distinct(Projections.property("p.ownerOid"))); - detached.add(Restrictions.eq("p.targetOid", "some oid")); - - main.add(Subqueries.propertyIn("o.oid", detached)); - main.addOrder(Order.asc("o.name.orig")); - - String expected = HibernateToSqlTranslator.toSql(main); - - OrgFilter orgFilter = OrgFilter.createOrg("some oid", OrgFilter.Scope.ONE_LEVEL); - ObjectQuery objectQuery = ObjectQuery.createObjectQuery(orgFilter); - objectQuery.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - - String real = getInterpretedQuery(session, OrgType.class, objectQuery); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - - OperationResult result = new OperationResult("query org structure"); - repositoryService.searchObjects(OrgType.class, objectQuery, null, result); - - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void asdf() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RUser.class, "u"); - Criteria a = main.createCriteria("assignments", "a"); - a.add(Restrictions.eq("a.assignmentOwner", RAssignmentOwner.FOCUS)); - Criteria e = a.createCriteria("a.extension"); - - Criteria s = e.createCriteria("strings", "s"); - - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("s.extensionType", RAssignmentExtensionType.EXTENSION)); - c2.add(Restrictions.eq("s.name", new QName("http://midpoint.evolveum.com/blabla", "foo"))); - c2.add(Restrictions.eq("s.value", "uid=jbond,ou=People,dc=example,dc=com")); - - Conjunction c1 = Restrictions.conjunction(); - c1.add(Restrictions.eq("a.targetRef.targetOid", "1234")); - c1.add(Restrictions.eq("a.targetRef.type", RObjectType.ORG)); - - main.add(Restrictions.and(c1, c2)); - - main.setProjection(Projections.property("u.fullObject")); - - String expected = HibernateToSqlTranslator.toSql(main); - LOGGER.info(">>> >>> {}", expected); - } finally { - close(session); - } - } - - @Test - public void test100ActivationQuery() throws Exception { - PrismObjectDefinition focusObjectDef = prismContext.getSchemaRegistry() - .findObjectDefinitionByCompileTimeClass(UserType.class); - - XMLGregorianCalendar thisScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - - OrFilter filter = OrFilter.createOr( - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(FocusType.F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - focusObjectDef, thisScanTimestamp, true), - LessFilter.createLess(new ItemPath(FocusType.F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - focusObjectDef, thisScanTimestamp, true) - ); - - Session session = open(); - try { - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, UserType.class, query, false); - - String expected = null; - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - } finally { - close(session); - } - } - - @Test - public void test200ActivationQuery() throws Exception { - PrismObjectDefinition focusObjectDef = prismContext.getSchemaRegistry() - .findObjectDefinitionByCompileTimeClass(UserType.class); - - XMLGregorianCalendar lastScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - XMLGregorianCalendar thisScanTimestamp = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - - OrFilter filter = OrFilter.createOr( - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), focusObjectDef, - thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), focusObjectDef, - thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - focusObjectDef, lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_FROM), - focusObjectDef, thisScanTimestamp, true) - ), - AndFilter.createAnd( - GreaterFilter.createGreater(new ItemPath(FocusType.F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - focusObjectDef, lastScanTimestamp, false), - LessFilter.createLess(new ItemPath(FocusType.F_ASSIGNMENT, FocusType.F_ACTIVATION, ActivationType.F_VALID_TO), - focusObjectDef, thisScanTimestamp, true) - ) - ); - - Session session = open(); - try { - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - String real = getInterpretedQuery(session, UserType.class, query, false); - - String expected = null; - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - } finally { - close(session); - } - } - - @Test - public void test300OrgQuery() throws Exception { - File objects = new File("src/test/resources/orgstruct/org-monkey-island.xml"); - OperationResult opResult = new OperationResult("test300OrgQuery"); - List> orgStruct = prismContext.parseObjects(objects); - - for (PrismObject o : orgStruct) { - repositoryService.addObject((PrismObject) o, null, opResult); - } - opResult.computeStatusIfUnknown(); - AssertJUnit.assertTrue(opResult.isSuccess()); - - checkQueryResult(ObjectType.class, "00000000-8888-6666-0000-100000000001", OrgFilter.Scope.ONE_LEVEL, 4); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-100000000001", OrgFilter.Scope.ONE_LEVEL, 1); - checkQueryResult(OrgType.class, "00000000-8888-6666-0000-100000000001", OrgFilter.Scope.ONE_LEVEL, 3); - checkQueryResult(OrgType.class, "00000000-8888-6666-0000-100000000001", OrgFilter.Scope.SUBTREE, 5); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-100000000001", OrgFilter.Scope.SUBTREE, 6); - checkQueryResult(ObjectType.class, "00000000-8888-6666-0000-100000000001", OrgFilter.Scope.SUBTREE, 11); - checkQueryResult(ObjectType.class, "00000000-8888-6666-0000-100000000006", OrgFilter.Scope.ONE_LEVEL, 4); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-100000000006", OrgFilter.Scope.ONE_LEVEL, 4); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-100000000006", OrgFilter.Scope.SUBTREE, 4); - checkQueryResult(OrgType.class, "00000000-8888-6666-0000-100000000006", OrgFilter.Scope.ONE_LEVEL, 0); - checkQueryResult(OrgType.class, "00000000-8888-6666-0000-100000000006", OrgFilter.Scope.SUBTREE, 0); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-200000000002", OrgFilter.Scope.ONE_LEVEL, 2); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-200000000002", OrgFilter.Scope.SUBTREE, 2); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-200000000001", OrgFilter.Scope.ONE_LEVEL, 1); - checkQueryResult(UserType.class, "00000000-8888-6666-0000-200000000001", OrgFilter.Scope.SUBTREE, 1); - } - - private void checkQueryResult(Class type, String oid, OrgFilter.Scope scope, int count) - throws Exception { - LOGGER.info("checkQueryResult"); - - OrgFilter orgFilter = OrgFilter.createOrg(oid, scope); - ObjectQuery query = ObjectQuery.createObjectQuery(orgFilter); - query.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - - OperationResult result = new OperationResult("checkQueryResult"); - List> objects = repositoryService.searchObjects(type, query, null, result); - for (PrismObject object : objects) { - LOGGER.info("{}", object.getOid()); - } - int realCount = objects.size(); - AssertJUnit.assertEquals("Expected count doesn't match for searchObjects " + orgFilter, count, realCount); - - result.computeStatusIfUnknown(); - AssertJUnit.assertTrue(result.isSuccess()); - - realCount = repositoryService.countObjects(type, query, result); - AssertJUnit.assertEquals("Expected count doesn't match for countObjects " + orgFilter, count, realCount); - - result.computeStatusIfUnknown(); - AssertJUnit.assertTrue(result.isSuccess()); - } - - @Test - public void test310QueryNameAndOrg() throws Exception { - Session session = open(); - - try { - DetachedCriteria detached = DetachedCriteria.forClass(RObjectReference.class, "p"); - detached.add(Restrictions.eq("referenceType", 0)); - detached.setProjection(Projections.distinct(Projections.property("p.ownerOid"))); - detached.add(Property.forName("targetOid").in( - DetachedCriteria.forClass(ROrgClosure.class, "cl") - .setProjection(Projections.property("cl.descendantOid")) - .add(Restrictions.eq("cl.ancestorOid", "1234")))); - - Criteria main = session.createCriteria(RUser.class, "u"); - String mainAlias = "u"; - - ProjectionList projections = Projections.projectionList(); - projections.add(Projections.property("fullObject")); - - projections.add(Projections.property("stringsCount")); - projections.add(Projections.property("longsCount")); - projections.add(Projections.property("datesCount")); - projections.add(Projections.property("referencesCount")); - projections.add(Projections.property("polysCount")); - projections.add(Projections.property("booleansCount")); - - main.setProjection(projections); - - Conjunction c = Restrictions.conjunction(); - c.add(Restrictions.and( - Restrictions.eq("u.name.orig", "cpt. Jack Sparrow"), - Restrictions.eq("u.name.norm", "cpt jack sparrow"))); - c.add(Subqueries.propertyIn(mainAlias + ".oid", detached)); - main.add(c); - - main.addOrder(Order.asc("u.name.orig")); - - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter eqFilter = EqualFilter.createEqual(ObjectType.F_NAME, ObjectType.class, prismContext, - null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); - - OrgFilter orgFilter = OrgFilter.createOrg("12341234-1234-1234-1234-123412341234"); - - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(eqFilter, orgFilter)); - query.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); - - String real = getInterpretedQuery(session, UserType.class, query); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test(enabled = false) - public void test320QueryEmployeeTypeAndOrgType() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RObject.class, "o"); - main.add(Restrictions.or( - Restrictions.and( - Restrictions.eq("o.name.orig", "some name"), - Restrictions.eq("o.employeeNumber", "123") - ), - Restrictions.eq("o.identifier", "1234") - )); - ProjectionList list = Projections.projectionList(); - addFullObjectProjectionList("o", list, false); - main.setProjection(list); - - List l = main.list(); - l.size(); - String expected = HibernateToSqlTranslator.toSql(main); - LOGGER.info("expected query>\n{}", new Object[]{expected}); - - -// EqualsFilter nameFilter = EqualsFilter.createEqual(ObjectType.F_NAME, ObjectType.class, prismContext, -// null, new PolyString("cpt. Jack Sparrow", "cpt jack sparrow")); -// -// EqualsFilter numberFilter = EqualsFilter.createEqual(UserType.F_EMPLOYEE_NUMBER, UserType.class, prismContext, -// null, "123"); -// -//// EqualsFilter orgTypeFilter = EqualsFilter.createEqual(OrgType.F_ORG_TYPE, OrgType.class, prismContext, -//// null, "orgtypevalue"); -// -// ObjectQuery query = ObjectQuery.createObjectQuery(OrFilter.createOr( -// AndFilter.createAnd(nameFilter, numberFilter)//, -//// orgTypeFilter -// )); -// query.setPaging(ObjectPaging.createPaging(null, null, ObjectType.F_NAME, OrderDirection.ASCENDING)); -// -// String real = getInterpretedQuery(session, ObjectType.class, query); -// -// LOGGER.info("real query>\n{}", new Object[]{real}); - } finally { - close(session); - } - } - - @Test - public void test330queryUserSubstringName() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - main.add(Restrictions.like("name.orig", "a%")); - String expected = HibernateToSqlTranslator.toSql(main); - - SubstringFilter substring = SubstringFilter.createSubstring(ObjectType.F_NAME, ObjectType.class, - prismContext, PolyStringOrigMatchingRule.NAME, "a"); - substring.setAnchorStart(true); - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(substring)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - - OperationResult result = new OperationResult("test330queryUserSubstringName"); - int count = repositoryService.countObjects(ObjectType.class, ObjectQuery.createObjectQuery(substring), result); - AssertJUnit.assertEquals(2, count); - - substring = SubstringFilter.createSubstring(ObjectType.F_NAME, ObjectType.class, - prismContext, PolyStringOrigMatchingRule.NAME, "a"); - count = repositoryService.countObjects(ObjectType.class, ObjectQuery.createObjectQuery(substring), result); - AssertJUnit.assertEquals(18, count); - } finally { - close(session); - } - } - - @Test - public void test340queryObjectClassTypeUser() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - main.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.USER)); - String expected = HibernateToSqlTranslator.toSql(main); - - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, null); - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void test350queryObjectClassTypeAbstractRole() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - List list = new ArrayList<>(); - list.add(RObjectType.ABSTRACT_ROLE); - list.add(RObjectType.ORG); - list.add(RObjectType.ROLE); - main.add(Restrictions.in("o." + RObject.F_OBJECT_TYPE_CLASS, list)); - String expected = HibernateToSqlTranslator.toSql(main); - - TypeFilter type = TypeFilter.createType(AbstractRoleType.COMPLEX_TYPE, null); - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void test360queryMetadataTimestamp() throws Exception { - Session session = open(); - - try { - Criteria main = session.createCriteria(RReportOutput.class, "r"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("r", projections, false); - main.setProjection(projections); - - XMLGregorianCalendar timeXml = XMLGregorianCalendarType.asXMLGregorianCalendar(new Date()); - - main.add(Restrictions.le("r.createTimestamp", timeXml)); - String expected = HibernateToSqlTranslator.toSql(main); - - LessFilter less = LessFilter.createLess( - new ItemPath(ReportOutputType.F_METADATA, MetadataType.F_CREATE_TIMESTAMP), - ReportOutputType.class, prismContext, timeXml, true); - - String real = getInterpretedQuery(session, ReportOutputType.class, ObjectQuery.createObjectQuery(less)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void test370queryObjectypeByTypeUserAndLocality() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Conjunction c = Restrictions.conjunction(); - main.add(c); - c.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.USER)); - c.add(Restrictions.and(Restrictions.eq("o.localityUser.orig", "Caribbean"), - Restrictions.eq("o.localityUser.norm", "caribbean"))); - - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter eq = EqualFilter.createEqual(new ItemPath(UserType.F_LOCALITY), UserType.class, prismContext, - new PolyString("Caribbean", "caribbean")); - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, eq); - - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - - checkQueryTypeAlias(real, "m_user", "locality_orig", "locality_norm"); - } finally { - close(session); - } - } - - /** - * This checks aliases, if they were generated correctly for query. Alias for table as "table" parameter - * must be used for columns in "properties" parameter. - * - * @param query - * @param table - * @param properties - */ - private void checkQueryTypeAlias(String query, String table, String... properties) { - String[] array = query.split(" "); - String alias = null; - for (int i = 0; i < array.length; i++) { - if (table.equals(array[i])) { - alias = array[i + 1]; - break; - } - } - AssertJUnit.assertNotNull(alias); - - for (String property : properties) { - for (String token : array) { - if (token.endsWith(property + "=?") && !token.startsWith("(" + alias + ".")) { - AssertJUnit.fail("Property '" + property + "' doesn't have proper alias '" - + alias + "' in token '" + token + "'"); - } - } - } - } - - @Test - public void test375queryObjectypeByTypeOrgAndLocality() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Conjunction c = Restrictions.conjunction(); - main.add(c); - c.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.ORG)); - c.add(Restrictions.and(Restrictions.eq("o.locality.orig", "Caribbean"), - Restrictions.eq("o.locality.norm", "caribbean"))); - - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter eq = EqualFilter.createEqual(new ItemPath(OrgType.F_LOCALITY), OrgType.class, prismContext, - new PolyString("Caribbean", "caribbean")); - TypeFilter type = TypeFilter.createType(OrgType.COMPLEX_TYPE, eq); - - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - - checkQueryTypeAlias(real, "m_org", "locality_orig", "locality_norm"); - } finally { - close(session); - } - } - - @Test - public void test380queryObjectypeByTypeAndExtensionAttribute() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Conjunction c = Restrictions.conjunction(); - main.add(c); - c.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.USER)); - - Conjunction c2 = Restrictions.conjunction(); - main.createCriteria("strings", "s", JoinType.LEFT_OUTER_JOIN); - c2.add(Restrictions.eq("s.ownerType", RObjectExtensionType.EXTENSION)); - c2.add(Restrictions.eq("s.name", new QName("http://example.com/p", "weapon"))); - c2.add(Restrictions.eq("s.value", "some weapon name")); - c.add(c2); - - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "weapon")), - UserType.class, prismContext, "some weapon name"); - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, eq); - - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void test390queryObjectypeByTypeAndReference() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Conjunction c = Restrictions.conjunction(); - main.add(c); - c.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.USER)); - - Criteria refs = main.createCriteria("linkRef", "l", JoinType.LEFT_OUTER_JOIN); - c.add(Restrictions.and(Restrictions.eq("l.targetOid", "123"),Restrictions.eq("l.relation", "#"))); - - String expected = HibernateToSqlTranslator.toSql(main); - - RefFilter ref = RefFilter.createReferenceEqual(UserType.F_LINK_REF, UserType.class, prismContext, "123"); - TypeFilter type = TypeFilter.createType(UserType.COMPLEX_TYPE, ref); - - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(type)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test - public void test400queryObjectypeByTypeComplex() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RObject.class, "o"); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("o", projections, false); - main.setProjection(projections); - - Conjunction c1 = Restrictions.conjunction(); - c1.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.USER)); - Criterion e1 = Restrictions.and(Restrictions.eq("o.localityUser.orig", "Caribbean"), - Restrictions.eq("o.localityUser.norm", "caribbean")); - Criterion e2 = Restrictions.and(Restrictions.eq("o.localityUser.orig", "Adriatic"), - Restrictions.eq("o.localityUser.norm", "adriatic")); - c1.add(Restrictions.or(e1, e2)); - - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.ORG)); - Criteria o1 = main.createCriteria("o.orgType", "o1", JoinType.LEFT_OUTER_JOIN); - c2.add(Restrictions.eq("o1.elements", "functional")); - - Criterion c3 = Restrictions.eq("o." + RObject.F_OBJECT_TYPE_CLASS, RObjectType.REPORT); - - main.add(Restrictions.or(c1, c2, c3)); - String expected = HibernateToSqlTranslator.toSql(main); - - - EqualFilter eq1 = EqualFilter.createEqual(UserType.F_LOCALITY, UserType.class, prismContext, - new PolyString("Caribbean", "caribbean")); - EqualFilter eq2 = EqualFilter.createEqual(UserType.F_LOCALITY, UserType.class, prismContext, - new PolyString("Adriatic", "adriatic")); - TypeFilter type1 = TypeFilter.createType(UserType.COMPLEX_TYPE, OrFilter.createOr(eq1, eq2)); - - EqualFilter equal = EqualFilter.createEqual(OrgType.F_ORG_TYPE, OrgType.class, prismContext, "functional"); - TypeFilter type2 = TypeFilter.createType(OrgType.COMPLEX_TYPE, equal); - - TypeFilter type3 = TypeFilter.createType(ReportType.COMPLEX_TYPE, null); - - OrFilter or = OrFilter.createOr(type1, type2, type3); - - String real = getInterpretedQuery(session, ObjectType.class, ObjectQuery.createObjectQuery(or)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - - @Test(expectedExceptions = QueryException.class) - public void test410QueryGenericClob() throws Exception { - Session session = open(); - try { - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "locations")), - GenericObjectType.class, prismContext, null); - - getInterpretedQuery(session, GenericObjectType.class, ObjectQuery.createObjectQuery(eq)); - } catch (QueryException ex) { - LOGGER.info("Exception", ex); - throw ex; - } finally { - close(session); - } - } - - @Test - public void test420QueryGenericString() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RGenericObject.class, "g"); - - Criteria stringExt = main.createCriteria("strings", "s", JoinType.LEFT_OUTER_JOIN); - - //and - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("s.ownerType", RObjectExtensionType.EXTENSION)); - c2.add(Restrictions.eq("s.name", new QName("http://example.com/p", "stringType"))); - c2.add(Restrictions.eq("s.value", "asdf")); - - main.add(c2); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("g", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, new QName("http://example.com/p", "stringType")), - GenericObjectType.class, prismContext, "asdf"); - - String real = getInterpretedQuery(session, GenericObjectType.class, ObjectQuery.createObjectQuery(eq)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - } finally { - close(session); - } - } - -// @Test -// public void atest100() throws Exception { -// Session session = open(); -// -// try { -// String expected = null;//HibernateToSqlTranslator.toSql(main); -// -// List secondaryEquals = new ArrayList<>(); -// EqualFilter eq = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstantsGenerated.ICF_S_UID), -// new PrismPropertyDefinition(SchemaConstantsGenerated.ICF_S_UID, DOMUtil.XSD_STRING, prismContext), -// "8daaeeae-f0c7-41c9-b258-2a3351aa8876"); -// secondaryEquals.add(eq); -// eq = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstantsGenerated.ICF_S_NAME), -// new PrismPropertyDefinition(SchemaConstantsGenerated.ICF_S_NAME, DOMUtil.XSD_STRING, prismContext), -// "some-name"); -// secondaryEquals.add(eq); -// -// OrFilter secondaryIdentifierFilter = OrFilter.createOr((List) secondaryEquals); -// RefFilter ref = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, -// prismContext, "ef2bc95b-76e0-48e2-86d6-3d4f02d3e1a2"); -// -// AndFilter filter = AndFilter.createAnd(ref, secondaryIdentifierFilter); -// ObjectQuery query = ObjectQuery.createObjectQuery(filter); -// LOGGER.debug("Query\n{}", query); -// -// QueryEngine engine = new QueryEngine(repositoryService.getConfiguration(), prismContext); -// RQuery rQuery = engine.interpret(query, ShadowType.class, null, false, session); -// RQueryCriteriaImpl rci = (RQueryCriteriaImpl) rQuery; -// System.out.println(rci); -// System.out.println(rci.getCriteria()); -// //just test if DB will handle it or throws some exception -// List l = rQuery.list(); -// LOGGER.info(">>>>>>>>asdfasdfasdfasdf{}",l.size()); -// -// String real = getInterpretedQuery(session, ShadowType.class, query); -// -// LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); -// AssertJUnit.assertEquals(expected, real); -// } finally { -// close(session); -// } -// } - - @Test - public void test430QueryGenericBoolean() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RGenericObject.class, "g"); - - Criteria stringExt = main.createCriteria("booleans", "b", JoinType.LEFT_OUTER_JOIN); - - //and - Conjunction c2 = Restrictions.conjunction(); - c2.add(Restrictions.eq("b.ownerType", RObjectExtensionType.EXTENSION)); - c2.add(Restrictions.eq("b.name", SKIP_AUTOGENERATION)); - c2.add(Restrictions.eq("b.value", true)); - - main.add(c2); - ProjectionList projections = Projections.projectionList(); - addFullObjectProjectionList("g", projections, false); - main.setProjection(projections); - - String expected = HibernateToSqlTranslator.toSql(main); - - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(ObjectType.F_EXTENSION, SKIP_AUTOGENERATION), - GenericObjectType.class, prismContext, true); - - String real = getInterpretedQuery(session, GenericObjectType.class, ObjectQuery.createObjectQuery(eq)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - - OperationResult result = new OperationResult("search"); - List> objects = repositoryService.searchObjects(GenericObjectType.class, - ObjectQuery.createObjectQuery(eq), null, result); - result.computeStatus(); - AssertJUnit.assertTrue(result.isSuccess()); - - AssertJUnit.assertNotNull(objects); - AssertJUnit.assertEquals(1, objects.size()); - - PrismObject obj = objects.get(0); - AssertJUnit.assertTrue(obj.getCompileTimeClass().equals(GenericObjectType.class)); - - result = new OperationResult("count"); - long count = repositoryService.countObjects(GenericObjectType.class, ObjectQuery.createObjectQuery(eq), - result); - result.computeStatus(); - AssertJUnit.assertTrue(result.isSuccess()); - AssertJUnit.assertEquals(1, count); - } finally { - close(session); - } - } - - @Test(enabled=false) - public void test440queryAssignmentExtensionBoolean() throws Exception { - Session session = open(); - try { - Criteria main = session.createCriteria(RUser.class, "u"); - Criteria a = main.createCriteria("assignments", "a"); - a.add(Restrictions.eq("a.assignmentOwner", RAssignmentOwner.FOCUS)); - Criteria e = a.createCriteria("a.extension"); - - Criteria b = e.createCriteria("booleans", "b"); - - Conjunction c1 = Restrictions.conjunction(); - c1.add(Restrictions.eq("b.extensionType", RAssignmentExtensionType.EXTENSION)); - c1.add(Restrictions.eq("b.name", SKIP_AUTOGENERATION)); - c1.add(Restrictions.eq("b.value", true)); - - main.add(c1); - main.setProjection(Projections.property("u.fullObject")); - - String expected = HibernateToSqlTranslator.toSql(main); - - SchemaRegistry registry = prismContext.getSchemaRegistry(); - PrismObjectDefinition userDef = registry.findObjectDefinitionByCompileTimeClass(UserType.class); - PrismContainerDefinition assignmentDef = userDef.findContainerDefinition(UserType.F_ASSIGNMENT); - PrismPropertyDefinition propDef = assignmentDef.createPropertyDefinition(SKIP_AUTOGENERATION, DOMUtil.XSD_BOOLEAN); - - EqualFilter eq = EqualFilter.createEqual( - new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_EXTENSION, SKIP_AUTOGENERATION), - propDef, null, true); - - String real = getInterpretedQuery(session, UserType.class, ObjectQuery.createObjectQuery(eq)); - - LOGGER.info("exp. query>\n{}\nreal query>\n{}", new Object[]{expected, real}); - AssertJUnit.assertEquals(expected, real); - - OperationResult result = new OperationResult("search"); - List> objects = repositoryService.searchObjects(UserType.class, - ObjectQuery.createObjectQuery(eq), null, result); - result.computeStatus(); - AssertJUnit.assertTrue(result.isSuccess()); - - AssertJUnit.assertNotNull(objects); - AssertJUnit.assertEquals(1, objects.size()); - - PrismObject obj = objects.get(0); - AssertJUnit.assertTrue(obj.getCompileTimeClass().equals(UserType.class)); - - result = new OperationResult("count"); - long count = repositoryService.countObjects(UserType.class, ObjectQuery.createObjectQuery(eq), result); - result.computeStatus(); - AssertJUnit.assertTrue(result.isSuccess()); - AssertJUnit.assertEquals(1, count); - } finally { - close(session); - } - } -} diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/RAnyConverterStaticTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/RAnyConverterStaticTest.java index cc3f9b37fbc..e73b6eb3fc4 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/RAnyConverterStaticTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/RAnyConverterStaticTest.java @@ -18,11 +18,7 @@ import java.util.Set; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismConstants; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.schema.SchemaRegistry; @@ -196,7 +192,7 @@ public void testExtensionEnum() throws Exception { AssertJUnit.assertNotNull(def); PrismProperty item = (PrismProperty) def.instantiate(); item.setValue(new PrismPropertyValue(BeforeAfterType.AFTER)); - def.setName(valueName); + ((ItemDefinitionImpl) def).setName(valueName); RAnyConverter converter = new RAnyConverter(prismContext); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchShadowOwnerTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchShadowOwnerTest.java index de435576510..b820a15ad13 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchShadowOwnerTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchShadowOwnerTest.java @@ -64,7 +64,7 @@ public void initSystem() throws Exception { //insert sample data final File OBJECTS_FILE = new File(FOLDER_BASIC, "objects.xml"); - List> elements = prismContext.parseObjects(OBJECTS_FILE); + List> elements = prismContext.parserFor(OBJECTS_FILE).parseObjects(); for (int i = 0; i < elements.size(); i++) { PrismObject object = elements.get(i); repositoryService.addObject(object, null, result); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchTest.java index f29c7e2ab0b..907f2889b20 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/SearchTest.java @@ -72,8 +72,8 @@ public void beforeClass() throws Exception { PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); - List> objects = prismContext.parseObjects(new File(FOLDER_BASIC, "objects.xml")); - objects.addAll(prismContext.parseObjects(new File(FOLDER_BASIC, "objects-2.xml"))); + List> objects = prismContext.parserFor(new File(FOLDER_BASIC, "objects.xml")).parseObjects(); + objects.addAll(prismContext.parserFor(new File(FOLDER_BASIC, "objects-2.xml")).parseObjects()); OperationResult result = new OperationResult("add objects"); for (PrismObject object : objects) { @@ -96,9 +96,9 @@ public boolean handle(PrismObject object, OperationResult parentResult) { } }; - EqualFilter filter = EqualFilter.createEqual(UserType.F_NAME, UserType.class, prismContext, - PolyStringStrictMatchingRule.NAME, new PolyString("asdf", "asdf")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_NAME).eqPoly("asdf", "asdf").matchingStrict() + .build(); repositoryService.searchObjectsIterative(UserType.class, query, handler, null, false, result); result.recomputeStatus(); @@ -176,9 +176,9 @@ public void caseSensitiveSearchTest() throws Exception { final String nonExistingNameOrig = "test UserX00003"; final String nameNorm = "test userx00003"; - EqualFilter filter = EqualFilter.createEqual(UserType.F_FULL_NAME, UserType.class, prismContext, - PolyStringOrigMatchingRule.NAME, new PolyString(existingNameOrig, nameNorm)); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME).eqPoly(existingNameOrig, nameNorm).matchingOrig() + .build(); OperationResult result = new OperationResult("search"); List> users = repositoryService.searchObjects(UserType.class, query, null, result); @@ -186,9 +186,9 @@ public void caseSensitiveSearchTest() throws Exception { assertTrue(result.isSuccess()); assertEquals("Should find one user", 1, users.size()); - filter = EqualFilter.createEqual(UserType.F_FULL_NAME, UserType.class, prismContext, - PolyStringOrigMatchingRule.NAME, new PolyString(nonExistingNameOrig, nameNorm)); - query = ObjectQuery.createObjectQuery(filter); + query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME).eqPoly(nonExistingNameOrig, nameNorm).matchingOrig() + .build(); users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); @@ -199,9 +199,9 @@ public void caseSensitiveSearchTest() throws Exception { @Test public void roleMembershipSearchTest() throws Exception { PrismReferenceValue r456 = new PrismReferenceValue("r456", RoleType.COMPLEX_TYPE); - RefFilter filter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ROLE_MEMBERSHIP_REF), UserType.class, prismContext, r456); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ROLE_MEMBERSHIP_REF).ref(r456) + .build(); OperationResult result = new OperationResult("search"); List> users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); @@ -210,9 +210,9 @@ public void roleMembershipSearchTest() throws Exception { assertEquals("Wrong user name", "atestuserX00003", users.get(0).getName().getOrig()); PrismReferenceValue r123 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE); - filter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ROLE_MEMBERSHIP_REF), UserType.class, prismContext, r123); - query = ObjectQuery.createObjectQuery(filter); - + query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ROLE_MEMBERSHIP_REF).ref(r123) + .build(); users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); assertTrue(result.isSuccess()); @@ -222,8 +222,9 @@ public void roleMembershipSearchTest() throws Exception { @Test public void assignmentOrgRefSearchTest() throws Exception { PrismReferenceValue o123456 = new PrismReferenceValue("o123456", OrgType.COMPLEX_TYPE); - RefFilter filter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_ORG_REF), UserType.class, prismContext, o123456); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(o123456) + .build(); OperationResult result = new OperationResult("search"); List> users = repositoryService.searchObjects(UserType.class, query, null, result); @@ -233,8 +234,9 @@ public void assignmentOrgRefSearchTest() throws Exception { assertEquals("Wrong user name", "atestuserX00002", users.get(0).getName().getOrig()); PrismReferenceValue o999 = new PrismReferenceValue("o999", RoleType.COMPLEX_TYPE); - filter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_ORG_REF), UserType.class, prismContext, o999); - query = ObjectQuery.createObjectQuery(filter); + query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(o999) + .build(); users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); @@ -245,8 +247,9 @@ public void assignmentOrgRefSearchTest() throws Exception { @Test public void assignmentResourceRefSearchTest() throws Exception { PrismReferenceValue resourceRef = new PrismReferenceValue("10000000-0000-0000-0000-000000000004", ResourceType.COMPLEX_TYPE); - RefFilter filter = RefFilter.createReferenceEqual(new ItemPath(RoleType.F_ASSIGNMENT, AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF), UserType.class, prismContext, resourceRef); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(RoleType.F_ASSIGNMENT, AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF).ref(resourceRef) + .build(); OperationResult result = new OperationResult("search"); List> roles = repositoryService.searchObjects(RoleType.class, query, null, result); @@ -256,22 +259,21 @@ public void assignmentResourceRefSearchTest() throws Exception { assertEquals("Wrong role name", "Judge", roles.get(0).getName().getOrig()); PrismReferenceValue resourceRef2 = new PrismReferenceValue("FFFFFFFF-0000-0000-0000-000000000004", ResourceType.COMPLEX_TYPE); - filter = RefFilter.createReferenceEqual(new ItemPath(RoleType.F_ASSIGNMENT, AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF), UserType.class, prismContext, resourceRef2); - query = ObjectQuery.createObjectQuery(filter); - + query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(RoleType.F_ASSIGNMENT, AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF).ref(resourceRef2) + .build(); roles = repositoryService.searchObjects(RoleType.class, query, null, result); result.recomputeStatus(); assertTrue(result.isSuccess()); assertEquals("Should find zero roles", 0, roles.size()); } - @Test + + @Test public void roleAssignmentSearchTest() throws Exception { PrismReferenceValue r456 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE); - RefFilter rFilter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, r456); - - - ObjectQuery query = ObjectQuery.createObjectQuery(rFilter); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(r456) + .build(); OperationResult result = new OperationResult("search"); List> users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); @@ -283,11 +285,10 @@ public void roleAssignmentSearchTest() throws Exception { @Test public void orgAssignmentSearchTest() throws Exception { - PrismReferenceValue org = new PrismReferenceValue("00000000-8888-6666-0000-100000000085", OrgType.COMPLEX_TYPE); - RefFilter oFilter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, org); - ObjectQuery query = ObjectQuery.createObjectQuery(oFilter); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(org) + .build(); OperationResult result = new OperationResult("search"); List> users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); @@ -300,12 +301,11 @@ public void orgAssignmentSearchTest() throws Exception { @Test(enabled = false) public void roleAndOrgAssignmentSearchTest() throws Exception { PrismReferenceValue r456 = new PrismReferenceValue("r123", RoleType.COMPLEX_TYPE); - RefFilter rFilter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, r456); - PrismReferenceValue org = new PrismReferenceValue("00000000-8888-6666-0000-100000000085", OrgType.COMPLEX_TYPE); - RefFilter oFilter = RefFilter.createReferenceEqual(new ItemPath(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF), UserType.class, prismContext, org); - ObjectQuery query = ObjectQuery.createObjectQuery(AndFilter.createAnd(rFilter, oFilter)); - + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(r456) + .and().item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(org) + .build(); OperationResult result = new OperationResult("search"); List> users = repositoryService.searchObjects(UserType.class, query, null, result); result.recomputeStatus(); @@ -317,11 +317,9 @@ public void roleAndOrgAssignmentSearchTest() throws Exception { @Test public void notBusinessRoleTypeSearchTest() throws Exception { - - EqualFilter equalFilter = EqualFilter.createEqual(new ItemPath(RoleType.F_ROLE_TYPE), RoleType.class, prismContext, "business"); - NotFilter notFilter = NotFilter.createNot(equalFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(notFilter); - + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .not().item(RoleType.F_ROLE_TYPE).eq("business") + .build(); OperationResult result = new OperationResult("search"); List> roles = repositoryService.searchObjects(RoleType.class, query, null, result); result.recomputeStatus(); @@ -335,10 +333,9 @@ public void notBusinessRoleTypeSearchTest() throws Exception { @Test public void businessRoleTypeSearchTest() throws Exception { - - EqualFilter equalFilter = EqualFilter.createEqual(new ItemPath(RoleType.F_ROLE_TYPE), RoleType.class, prismContext, "business"); - ObjectQuery query = ObjectQuery.createObjectQuery(equalFilter); - + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(RoleType.F_ROLE_TYPE).eq("business") + .build(); OperationResult result = new OperationResult("search"); List> roles = repositoryService.searchObjects(RoleType.class, query, null, result); result.recomputeStatus(); @@ -350,10 +347,9 @@ public void businessRoleTypeSearchTest() throws Exception { @Test public void emptyRoleTypeSearchTest() throws Exception { - - EqualFilter equalFilter = EqualFilter.createEqual(new ItemPath(RoleType.F_ROLE_TYPE), RoleType.class, prismContext, null); - ObjectQuery query = ObjectQuery.createObjectQuery(equalFilter); - + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .item(RoleType.F_ROLE_TYPE).isNull() + .build(); OperationResult result = new OperationResult("search"); List> roles = repositoryService.searchObjects(RoleType.class, query, null, result); result.recomputeStatus(); @@ -367,11 +363,9 @@ public void emptyRoleTypeSearchTest() throws Exception { @Test public void nonEmptyRoleTypeSearchTest() throws Exception { - - EqualFilter equalFilter = EqualFilter.createEqual(new ItemPath(RoleType.F_ROLE_TYPE), RoleType.class, prismContext, null); - NotFilter notFilter = NotFilter.createNot(equalFilter); - ObjectQuery query = ObjectQuery.createObjectQuery(notFilter); - + ObjectQuery query = QueryBuilder.queryFor(RoleType.class, prismContext) + .not().item(RoleType.F_ROLE_TYPE).isNull() + .build(); OperationResult result = new OperationResult("search"); List> roles = repositoryService.searchObjects(RoleType.class, query, null, result); result.recomputeStatus(); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/closure/AbstractOrgClosureTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/closure/AbstractOrgClosureTest.java index 9c8b9f635eb..c643ea75fa7 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/closure/AbstractOrgClosureTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/closure/AbstractOrgClosureTest.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrgFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.sql.BaseSQLRepoTest; import com.evolveum.midpoint.repo.sql.data.common.ROrgClosure; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; @@ -647,9 +648,9 @@ protected void removeOrgStructure(OperationResult result) throws Exception { protected void removeOrgStructure(String nodeOid, OperationResult result) throws Exception { removeUsersFromOrg(nodeOid, result); - ObjectQuery query = new ObjectQuery(); - ObjectFilter filter = OrgFilter.createOrg(nodeOid, OrgFilter.Scope.ONE_LEVEL); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(OrgType.class, prismContext) + .isDirectChildOf(nodeOid) + .build(); List> subOrgs = repositoryService.searchObjects(OrgType.class, query, null, result); for (PrismObject subOrg : subOrgs) { removeOrgStructure(subOrg.getOid(), result); @@ -663,9 +664,9 @@ protected void removeOrgStructure(String nodeOid, OperationResult result) throws } protected void removeUsersFromOrg(String nodeOid, OperationResult result) throws Exception { - ObjectQuery query = new ObjectQuery(); - ObjectFilter filter = OrgFilter.createOrg(nodeOid, OrgFilter.Scope.ONE_LEVEL); - query.setFilter(filter); + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .isDirectChildOf(nodeOid) + .build(); List> users = repositoryService.searchObjects(UserType.class, query, null, result); for (PrismObject user : users) { try { diff --git a/repo/repo-sql-impl-test/src/test/resources/basic/user-big.xml b/repo/repo-sql-impl-test/src/test/resources/basic/user-big.xml index d6301372c07..da0c0a3549d 100644 --- a/repo/repo-sql-impl-test/src/test/resources/basic/user-big.xml +++ b/repo/repo-sql-impl-test/src/test/resources/basic/user-big.xml @@ -19,8 +19,9 @@ xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"> + testuserX123 testuserx123 @@ -139,7 +140,7 @@ xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" - xsi:type="c:ProtectedStringType"> + xsi:type="t:ProtectedStringType"> diff --git a/repo/repo-sql-impl-test/src/test/resources/modify/user-with-extension.xml b/repo/repo-sql-impl-test/src/test/resources/modify/user-with-extension.xml index 63c9f54f88b..ea3f06fea8f 100644 --- a/repo/repo-sql-impl-test/src/test/resources/modify/user-with-extension.xml +++ b/repo/repo-sql-impl-test/src/test/resources/modify/user-with-extension.xml @@ -57,7 +57,7 @@ - + diff --git a/repo/repo-sql-impl/pom.xml b/repo/repo-sql-impl/pom.xml index daa82dcca64..6d07d748385 100644 --- a/repo/repo-sql-impl/pom.xml +++ b/repo/repo-sql-impl/pom.xml @@ -93,10 +93,10 @@ xml-apis xml-apis - - javax.xml.bind - jaxb-api - + + + + diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index 357021d5238..0a0354aaa6b 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -20,7 +20,10 @@ import com.evolveum.midpoint.audit.api.AuditEventType; import com.evolveum.midpoint.audit.api.AuditService; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.parser.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.query.NoneFilter; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventRecord; import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventStage; import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; @@ -205,7 +208,7 @@ private PrismObject resolve(Session session, String oid) throws SchemaException PrismObject result = null; if (object != null) { String xml = RUtil.getXmlFromByteArray(object.getFullObject(), getConfiguration().isUseZip()); - result = getPrismContext().parseObject(xml, XNodeProcessorEvaluationMode.COMPAT); + result = getPrismContext().parserFor(xml).compat().parse(); } return result; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/audit/RObjectDeltaOperation.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/audit/RObjectDeltaOperation.java index 0cc4c067f9e..4ff3d6e5a42 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/audit/RObjectDeltaOperation.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/audit/RObjectDeltaOperation.java @@ -281,11 +281,11 @@ public static ObjectDeltaOperation fromRepo(RObjectDeltaOperation operation, Pri ObjectDeltaOperation odo = new ObjectDeltaOperation(); try { if (operation.getDelta() != null) { - ObjectDeltaType delta = prismContext.parseAtomicValue(operation.getDelta(), ObjectDeltaType.COMPLEX_TYPE); + ObjectDeltaType delta = prismContext.parserFor(operation.getDelta()).parseRealValue(ObjectDeltaType.class); odo.setObjectDelta(DeltaConvertor.createObjectDelta(delta, prismContext)); } if (operation.getFullResult() != null) { - OperationResultType resultType = prismContext.parseAtomicValue(operation.getFullResult(), OperationResultType.COMPLEX_TYPE); + OperationResultType resultType = prismContext.parserFor(operation.getFullResult()).parseRealValue(OperationResultType.class); odo.setExecutionResult(OperationResult.createOperationResult(resultType)); } odo.setObjectName(RPolyString.fromRepo(operation.getObjectName())); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAnyConverter.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAnyConverter.java index 54fef132e6f..1f78e65102e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAnyConverter.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAnyConverter.java @@ -17,7 +17,7 @@ package com.evolveum.midpoint.repo.sql.data.common.any; import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.parser.PrismBeanInspector; +import com.evolveum.midpoint.prism.marshaller.PrismBeanInspector; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.sql.query.QueryException; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java index 48b87c441e4..216c07eebef 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.repo.sql.data.common.container; -import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.sql.data.common.RAccessCertificationCampaign; @@ -34,6 +33,7 @@ import com.evolveum.midpoint.repo.sql.util.DtoTranslationException; import com.evolveum.midpoint.repo.sql.util.MidPointSingleTablePersister; import com.evolveum.midpoint.repo.sql.util.RUtil; +import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -396,10 +396,11 @@ private static RAccessCertificationCase toRepo(AccessCertificationCaseType case1 PrismContainerValue cvalue = case1.asPrismContainerValue(); String xml; try { - xml = prismContext.serializeContainerValueToString(cvalue, new QName("value"), PrismContext.LANG_XML); + xml = prismContext.xmlSerializer().serialize(cvalue, SchemaConstantsGenerated.C_VALUE); } catch (SchemaException e) { throw new IllegalStateException("Couldn't serialize certification case to string", e); } + LOGGER.trace("RAccessCertificationCase full object\n{}", xml); byte[] fullObject = RUtil.getByteArrayFromXml(xml, false); rCase.setFullObject(fullObject); @@ -413,10 +414,9 @@ public AccessCertificationCaseType toJAXB(PrismContext prismContext) throws Sche // TODO find appropriate name public static AccessCertificationCaseType createJaxb(byte[] fullObject, PrismContext prismContext, boolean removeCampaignRef) throws SchemaException { String xml = RUtil.getXmlFromByteArray(fullObject, false); - PrismContainer caseContainer; + LOGGER.trace("RAccessCertificationCase full object to be parsed\n{}", xml); try { - // TODO tolerant mode - caseContainer = prismContext.parseContainer(xml, AccessCertificationCaseType.class, PrismContext.LANG_XML); + return prismContext.parserFor(xml).xml().compat().parseRealValue(AccessCertificationCaseType.class); } catch (SchemaException e) { LOGGER.debug("Couldn't parse certification case because of schema exception ({}):\nData: {}", e, xml); throw e; @@ -424,8 +424,6 @@ public static AccessCertificationCaseType createJaxb(byte[] fullObject, PrismCon LOGGER.debug("Couldn't parse certification case because of unexpected exception ({}):\nData: {}", e, xml); throw e; } - AccessCertificationCaseType aCase = caseContainer.getValue().asContainerable().clone(); // clone in order to make it parent-less //aCase.asPrismContainerValue().removeReference(AccessCertificationCaseType.F_CAMPAIGN_REF); - return aCase; } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java index ffb88012726..de8cf37617f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java @@ -18,7 +18,7 @@ import com.evolveum.midpoint.common.crypto.CryptoUtil; import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.parser.XNodeProcessorEvaluationMode; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorEvaluationMode; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ExistsFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; @@ -452,7 +452,7 @@ private PrismObject updateLoadedObject(GetObjectResult try { // "Postel mode": be tolerant what you read. We need this to tolerate (custom) schema changes ParsingContext parsingContext = ParsingContext.forMode(XNodeProcessorEvaluationMode.COMPAT); - prismObject = prismContext.parseObject(xml, parsingContext); + prismObject = prismContext.parserFor(xml).context(parsingContext).parse(); // TODO enable if needed // if (parsingContext.hasWarnings()) { // for (String warning : parsingContext.getWarnings()) { @@ -533,10 +533,10 @@ private void applyShadowAttributeDefinitions(Class anyValue if (item.getDefinition() == null) { RValueType rValType = (RValueType) value[2]; if (rValType == RValueType.PROPERTY) { - PrismPropertyDefinition def = new PrismPropertyDefinition(name, type, object.getPrismContext()); + PrismPropertyDefinition def = new PrismPropertyDefinitionImpl(name, type, object.getPrismContext()); item.applyDefinition(def, true); } else if (rValType == RValueType.REFERENCE) { - PrismReferenceDefinition def = new PrismReferenceDefinition(name, type, object.getPrismContext()); + PrismReferenceDefinition def = new PrismReferenceDefinitionImpl(name, type, object.getPrismContext()); item.applyDefinition(def, true); } else { throw new UnsupportedOperationException("Unsupported value type " + rValType); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java index b619845c200..d9afa8c022e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java @@ -251,7 +251,7 @@ public void updateFullObject(RObject object, PrismObject< xml = prismContext.serializeObjectToString(savedObject, PrismContext.LANG_XML); byte[] fullObject = RUtil.getByteArrayFromXml(xml, getConfiguration().isUseZip()); - if (LOGGER.isTraceEnabled()) LOGGER.trace("Storing full object\n{}", xml); + LOGGER.trace("Storing full object\n{}", xml); object.setFullObject(fullObject); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/AnyPropertyRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/AnyPropertyRestriction.java index 90fb1e4b760..10c6760a285 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/AnyPropertyRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/AnyPropertyRestriction.java @@ -21,7 +21,6 @@ import com.evolveum.midpoint.prism.path.ItemPathSegment; import com.evolveum.midpoint.prism.path.NameItemPathSegment; import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.PropertyValueFilter; import com.evolveum.midpoint.prism.query.ValueFilter; import com.evolveum.midpoint.repo.sql.data.common.any.RAnyConverter; import com.evolveum.midpoint.repo.sql.data.common.any.RAnyValue; @@ -35,13 +34,11 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; - import org.hibernate.criterion.Conjunction; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Restrictions; import javax.xml.namespace.QName; - import java.util.ArrayList; import java.util.List; @@ -105,7 +102,7 @@ public Criterion interpretInternal(ValueFilter filter) throws QueryException { conjunction.add(Restrictions.eq(propertyNamePrefix + RAnyValue.F_NAME, RUtil.qnameToString(name))); - Object testedValue = getValue(((PropertyValueFilter) filter).getValues()); + Object testedValue = getValue(filter.getValues()); Object value = RAnyConverter.getAggregatedRepoObject(testedValue); conjunction.add(createCriterion(propertyNamePrefix + RAnyValue.F_VALUE, value, filter)); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/ItemRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/ItemRestriction.java index acf10c18dd5..e2d2335fd30 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/ItemRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query/restriction/ItemRestriction.java @@ -496,8 +496,8 @@ protected Object getValue(List values) { protected Object getValueFromFilter(ValueFilter filter, PropertyDefinition def) throws QueryException { Object value; - if (filter instanceof PropertyValueFilter) { - value = getValue(((PropertyValueFilter) filter).getValues()); + if (filter != null) { + value = getValue((filter).getValues()); } else { throw new QueryException("Unknown filter '" + filter + "', can't get value from it."); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java index 02cfdf2bed4..fc902a4438c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java @@ -18,13 +18,11 @@ import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.query.LogicalFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrgFilter; -import com.evolveum.midpoint.prism.util.ValueSerializationUtil; import com.evolveum.midpoint.repo.sql.data.audit.RObjectDeltaOperation; import com.evolveum.midpoint.repo.sql.data.common.*; import com.evolveum.midpoint.repo.sql.data.common.any.*; @@ -60,7 +58,6 @@ import org.w3c.dom.Element; import javax.persistence.Table; -import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import java.io.ByteArrayInputStream; @@ -122,30 +119,6 @@ public static void revive(Objectable object, PrismContext } } - public static String toRepo(ItemDefinition parentDefinition, QName itemName, T value, - PrismContext prismContext) throws SchemaException, JAXBException { - if (value == null) { - return null; - } - - if (value instanceof Objectable) { - return prismContext.serializeObjectToString(((Objectable) value).asPrismObject(), - PrismContext.LANG_XML); - } - - ItemDefinition definition = null; - if (parentDefinition instanceof PrismContainerDefinition) { - definition = ((PrismContainerDefinition) parentDefinition).findItemDefinition(itemName); - if (definition == null) { - definition = parentDefinition; - } - } else { - definition = parentDefinition; - } - - return ValueSerializationUtil.serializeValue(value, definition, itemName, parentDefinition.getName(), prismContext, PrismContext.LANG_XML); - } - public static Element createFakeParentElement() { return DOMUtil.createElement(DOMUtil.getDocument(), CUSTOM_OBJECT); } @@ -312,7 +285,8 @@ public static void copyResultFromJAXB(ItemDefinition parentDef, QName itemName, repo.setStatus(getRepoEnumValue(jaxb.getStatus(), ROperationResultStatus.class)); if (repo instanceof OperationResultFull) { try { - ((OperationResultFull) repo).setFullResult(RUtil.toRepo(parentDef, itemName, jaxb, prismContext)); + String full = prismContext.xmlSerializer().serializeRealValue(jaxb, itemName); + ((OperationResultFull) repo).setFullResult(full); } catch (Exception ex) { throw new DtoTranslationException(ex.getMessage(), ex); } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index dbb9caa7f0b..75f6e43c97e 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.ConsistencyCheckScope; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Item; @@ -48,6 +49,7 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.repo.api.RepoAddOptions; @@ -60,6 +62,7 @@ import com.evolveum.midpoint.schema.internals.CachingStatistics; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.internals.InternalsConfig; +import com.evolveum.midpoint.schema.processor.*; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; @@ -108,6 +111,7 @@ import java.util.List; import java.util.Set; +import static com.evolveum.midpoint.test.util.TestUtil.assertSuccess; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertNotNull; @@ -254,7 +258,7 @@ protected PrismObject repoAddShadowFromFile(File file, OperationResu PrismContainer attrCont = object.findContainer(ShadowType.F_ATTRIBUTES); for (PrismProperty attr: attrCont.getValue().getProperties()) { if (attr.getDefinition() == null) { - ResourceAttributeDefinition attrDef = new ResourceAttributeDefinition<>(attr.getElementName(), + ResourceAttributeDefinition attrDef = new ResourceAttributeDefinitionImpl<>(attr.getElementName(), DOMUtil.XSD_STRING, prismContext); attr.setDefinition((PrismPropertyDefinition) attrDef); } @@ -413,24 +417,22 @@ protected PrismObject addResourceFromFile(File file, String connec protected PrismObject findConnectorByType(String connectorType, OperationResult result) throws SchemaException { - - EqualFilter equal = EqualFilter.createEqual(ConnectorType.F_CONNECTOR_TYPE, ConnectorType.class, prismContext, null, connectorType); - ObjectQuery query = ObjectQuery.createObjectQuery(equal); + ObjectQuery query = QueryBuilder.queryFor(ConnectorType.class, prismContext) + .item(ConnectorType.F_CONNECTOR_TYPE).eq(connectorType) + .build(); List> connectors = repositoryService.searchObjects(ConnectorType.class, query, null, result); if (connectors.size() != 1) { - throw new IllegalStateException("Cannot find connector type " + connectorType + ", got " - + connectors); + throw new IllegalStateException("Cannot find connector type " + connectorType + ", got " + connectors); } return connectors.get(0); } protected PrismObject findConnectorByTypeAndVersion(String connectorType, String connectorVersion, OperationResult result) throws SchemaException { - - EqualFilter equalType = EqualFilter.createEqual(ConnectorType.F_CONNECTOR_TYPE, ConnectorType.class, prismContext, null, connectorType); - EqualFilter equalVersion = EqualFilter.createEqual(ConnectorType.F_CONNECTOR_VERSION, ConnectorType.class, prismContext, null, connectorVersion); - AndFilter filter = AndFilter.createAnd(equalType, equalVersion); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(ConnectorType.class, prismContext) + .item(ConnectorType.F_CONNECTOR_TYPE).eq(connectorType) + .and().item(ConnectorType.F_CONNECTOR_VERSION).eq(connectorVersion) + .build(); List> connectors = repositoryService.searchObjects(ConnectorType.class, query, null, result); if (connectors.size() != 1) { throw new IllegalStateException("Cannot find connector type " + connectorType + ", version "+connectorVersion+", got " @@ -629,7 +631,7 @@ protected void assertShadowCommon(PrismObject shadow, String oid, St PrismAsserts.assertPropertyValue(shadow, ShadowType.F_NAME, PrismTestUtil.createPolyString(username)); - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); ObjectClassComplexTypeDefinition ocDef = rSchema.findObjectClassDefinition(objectClass); if (ocDef.getSecondaryIdentifiers().isEmpty()) { ResourceAttributeDefinition idDef = ocDef.getPrimaryIdentifiers().iterator().next(); @@ -696,7 +698,7 @@ protected void assertShadowRepo(PrismObject accountShadow, String oi } RefinedResourceSchema refinedSchema = null; try { - refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); } catch (SchemaException e) { AssertJUnit.fail(e.getMessage()); } @@ -708,7 +710,7 @@ protected void assertShadowRepo(PrismObject accountShadow, String oi // repo shadow should contains all secondary identifiers + ICF_UID assertRepoShadowAttributes(attributes, secIdentifiers.size()+1); } - + protected void assertRepoShadowAttributes(List> attributes, int expectedNumberOfIdentifiers) { assertEquals("Unexpected number of attributes in repo shadow", expectedNumberOfIdentifiers, attributes.size()); } @@ -922,7 +924,7 @@ protected PrismObject createShadow(PrismObject resourc resourceRef.setOid(resource.getOid()); shadowType.setResourceRef(resourceRef); shadowType.setKind(ShadowKindType.ACCOUNT); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition objectClassDefinition = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); shadowType.setObjectClass(objectClassDefinition.getTypeName()); ResourceAttributeContainer attrContainer = ShadowUtil.getOrCreateAttributesContainer(shadow, objectClassDefinition); @@ -952,7 +954,7 @@ protected PrismObject findAccountShadowByUsername(String username, P } protected PrismObject findShadowByName(ShadowKindType kind, String intent, String name, PrismObject resource, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition rOcDef = rSchema.getRefinedDefinition(kind,intent); ObjectQuery query = createShadowQuerySecondaryIdentifier(rOcDef, name, resource); List> shadows = repositoryService.searchObjects(ShadowType.class, query, null, result); @@ -964,7 +966,7 @@ protected PrismObject findShadowByName(ShadowKindType kind, String i } protected PrismObject findShadowByName(QName objectClass, String name, PrismObject resource, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition rOcDef = rSchema.getRefinedDefinition(objectClass); ObjectQuery query = createShadowQuerySecondaryIdentifier(rOcDef, name, resource); List> shadows = repositoryService.searchObjects(ShadowType.class, query, null, result); @@ -976,22 +978,21 @@ protected PrismObject findShadowByName(QName objectClass, String nam } protected ObjectQuery createAccountShadowQuery(String identifier, PrismObject resource) throws SchemaException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition rAccount = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); Collection identifierDefs = rAccount.getPrimaryIdentifiers(); assert identifierDefs.size() == 1 : "Unexpected identifier set in "+resource+" refined schema: "+identifierDefs; ResourceAttributeDefinition identifierDef = identifierDefs.iterator().next(); //TODO: set matching rule instead of null - EqualFilter idFilter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()), identifierDef, identifier); - EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, - rAccount.getObjectClassDefinition().getTypeName()); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resource); - AndFilter filter = AndFilter.createAnd(idFilter, ocFilter, resourceRefFilter); - return ObjectQuery.createObjectQuery(filter); + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(identifierDef, ShadowType.F_ATTRIBUTES, identifierDef.getName()).eq(identifier) + .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccount.getObjectClassDefinition().getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) + .build(); } protected ObjectQuery createAccountShadowQuerySecondaryIdentifier(String identifier, PrismObject resource) throws SchemaException { - RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); + RefinedResourceSchema rSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); RefinedObjectClassDefinition rAccount = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); return createShadowQuerySecondaryIdentifier(rAccount, identifier, resource); } @@ -1000,13 +1001,12 @@ protected ObjectQuery createShadowQuerySecondaryIdentifier(ObjectClassComplexTyp Collection identifierDefs = rAccount.getSecondaryIdentifiers(); assert identifierDefs.size() == 1 : "Unexpected identifier set in "+resource+" refined schema: "+identifierDefs; ResourceAttributeDefinition identifierDef = identifierDefs.iterator().next(); - //TODO: set matching rule instead of null - EqualFilter idFilter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()), identifierDef, identifier); - EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, - rAccount.getTypeName()); - RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resource); - AndFilter filter = AndFilter.createAnd(idFilter, ocFilter, resourceRefFilter); - return ObjectQuery.createObjectQuery(filter); + //TODO: set matching rule instead of null + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(identifierDef, ShadowType.F_ATTRIBUTES, identifierDef.getName()).eq(identifier) + .and().item(ShadowType.F_OBJECT_CLASS).eq(rAccount.getTypeName()) + .and().item(ShadowType.F_RESOURCE_REF).ref(resource.getOid()) + .build(); } protected PrismObjectDefinition getUserDefinition() { @@ -1022,7 +1022,7 @@ protected RefinedAttributeDefinition getAttributeDefinition(ResourceType resourc ShadowKindType kind, QName objectClassName, String attributeLocalName) throws SchemaException { - RefinedResourceSchema refinedResourceSchema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema refinedResourceSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); RefinedObjectClassDefinition refinedObjectClassDefinition = refinedResourceSchema.findRefinedDefinitionByObjectClassQName(kind, objectClassName); return refinedObjectClassDefinition.findAttributeDefinition(attributeLocalName); @@ -1145,12 +1145,12 @@ protected PolyString createPolyString(String string) { protected PolyStringType createPolyStringType(String string) { return PrismTestUtil.createPolyStringType(string); } - + protected void assertNumberOfAttributes(PrismObject shadow, Integer expectedNumberOfAttributes) { PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); assertNotNull("No attributes in repo shadow "+shadow, attributesContainer); List> attributes = attributesContainer.getValue().getItems(); - + assertFalse("Empty attributes in repo shadow "+shadow, attributes.isEmpty()); if (expectedNumberOfAttributes != null) { assertEquals("Unexpected number of attributes in repo shadow "+shadow, (int)expectedNumberOfAttributes, attributes.size()); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java index 7fc10edf951..3910d01a674 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java @@ -18,6 +18,7 @@ import com.evolveum.icf.dummy.resource.DummyGroup; import com.evolveum.icf.dummy.resource.ScriptHistoryEntry; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.match.MatchingRule; @@ -28,6 +29,7 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.util.PrismUtil; @@ -275,11 +277,14 @@ public static void assertAttributeNotNull(String message, ShadowType repoShadow, } public static void assertAttributeDefinition(ResourceAttribute attr, QName expectedType, int minOccurs, int maxOccurs, - boolean canRead, boolean canCreate, boolean canUpdate, Class expetcedAttributeDefinitionClass) { + boolean canRead, boolean canCreate, boolean canUpdate, Class expectedAttributeDefinitionClass) { ResourceAttributeDefinition definition = attr.getDefinition(); QName attrName = attr.getElementName(); assertNotNull("No definition for attribute "+attrName, definition); - assertEquals("Wrong class of definition for attribute"+attrName, expetcedAttributeDefinitionClass, definition.getClass()); + //assertEquals("Wrong class of definition for attribute"+attrName, expetcedAttributeDefinitionClass, definition.getClass()); + assertTrue("Wrong class of definition for attribute"+attrName+" (expected: " + expectedAttributeDefinitionClass + + ", real: " + definition.getClass() + ")", + expectedAttributeDefinitionClass.isAssignableFrom(definition.getClass())); assertEquals("Wrong type in definition for attribute"+attrName, expectedType, definition.getTypeName()); assertEquals("Wrong minOccurs in definition for attribute"+attrName, minOccurs, definition.getMinOccurs()); assertEquals("Wrong maxOccurs in definition for attribute"+attrName, maxOccurs, definition.getMaxOccurs()); @@ -544,17 +549,16 @@ public static void checkAllShadows(ResourceType resourceType, RepositoryService } public static ObjectQuery createAllShadowsQuery(ResourceType resourceType, PrismContext prismContext) throws SchemaException { - RefFilter equal = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, prismContext, resourceType.getOid()); - ObjectQuery query = ObjectQuery.createObjectQuery(equal); - return query; + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) + .build(); } public static ObjectQuery createAllShadowsQuery(ResourceType resourceType, QName objectClass, PrismContext prismContext) throws SchemaException { - AndFilter and = AndFilter.createAnd( - RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, prismContext, resourceType.getOid()), - EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, objectClass)); - ObjectQuery query = ObjectQuery.createObjectQuery(and); - return query; + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_RESOURCE_REF).ref(resourceType.getOid()) + .and().item(ShadowType.F_OBJECT_CLASS).eq(objectClass) + .build(); } public static ObjectQuery createAllShadowsQuery(ResourceType resourceType, String objectClassLocalName, PrismContext prismContext) throws SchemaException { @@ -602,7 +606,7 @@ public static void checkShadow(ShadowType shadowType, ResourceType resourceType, assertNotNull("no attributes",attrs); assertFalse("empty attributes",attrs.isEmpty()); - RefinedResourceSchema rschema = RefinedResourceSchema.getRefinedSchema(resourceType); + RefinedResourceSchema rschema = RefinedResourceSchemaImpl.getRefinedSchema(resourceType); ObjectClassComplexTypeDefinition objectClassDef = rschema.findObjectClassDefinition(shadowType); assertNotNull("cannot determine object class for "+shadowType, objectClassDef); @@ -687,20 +691,15 @@ private static ObjectQuery createShadowQuery(ShadowType resourceShadow, ObjectCl identifierValue = uidMatchingRule.normalize(identifierValue); } - ObjectFilter filter; PrismPropertyDefinition identifierDef = identifier.getDefinition(); - filter = AndFilter.createAnd( - RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, prismContext, ShadowUtil.getResourceOid(resourceShadow)), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()), identifierDef, new PrismPropertyValue(identifierValue))); - - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - return query; - + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .item(ShadowType.F_RESOURCE_REF).ref(ShadowUtil.getResourceOid(resourceShadow)) + .and().item(new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()), identifierDef).eq(identifierValue) + .build(); } public static void applyResourceSchema(ShadowType accountType, ResourceType resourceType, PrismContext prismContext) throws SchemaException { - ResourceSchema resourceSchema = RefinedResourceSchema.getResourceSchema(resourceType, prismContext); + ResourceSchema resourceSchema = RefinedResourceSchemaImpl.getResourceSchema(resourceType, prismContext); ShadowUtil.applyResourceSchema(accountType.asPrismObject(), resourceSchema); } @@ -916,7 +915,7 @@ public static ShadowAssociationType assertAssociation(PrismObject sh } } AssertJUnit.fail("No association for entitlement "+entitlementOid+" in "+shadow); - return null; // notreached + throw new IllegalStateException("not reached"); } public static void assertNoAssociation(PrismObject shadow, QName associationName, String entitlementOid) { diff --git a/repo/security-impl/src/main/java/com/evolveum/midpoint/security/impl/SecurityEnforcerImpl.java b/repo/security-impl/src/main/java/com/evolveum/midpoint/security/impl/SecurityEnforcerImpl.java index 8bd24790a1f..ce0c56293d6 100644 --- a/repo/security-impl/src/main/java/com/evolveum/midpoint/security/impl/SecurityEnforcerImpl.java +++ b/repo/security-impl/src/main/java/com/evolveum/midpoint/security/impl/SecurityEnforcerImpl.java @@ -22,6 +22,9 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; +import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.mutable.MutableBoolean; @@ -963,13 +966,14 @@ private ObjectFilter preProcessObje } ItemPath ownerRefPath = new ItemPath(AbstractRoleType.F_OWNER_REF); PrismReferenceDefinition ownerRefDef = objectDefinition.findReferenceDefinition(ownerRefPath); - ObjectFilter objSpecOwnerFilter = RefFilter.createReferenceEqual(ownerRefPath, ownerRefDef, principal.getUser().getOid()); + S_AtomicFilterExit builder = QueryBuilder.queryFor(AbstractRoleType.class, prismContext) + .item(ownerRefPath, ownerRefDef).ref(principal.getUser().getOid()); for (ObjectReferenceType subjectParentOrgRef: principal.getUser().getParentOrgRef()) { if (MiscSchemaUtil.compareRelation(null, subjectParentOrgRef.getRelation())) { - objSpecOwnerFilter = ObjectQueryUtil.filterOr(objSpecOwnerFilter, - RefFilter.createReferenceEqual(ownerRefPath, ownerRefDef, subjectParentOrgRef.getOid())); + builder = builder.or().item(ownerRefPath, ownerRefDef).ref(subjectParentOrgRef.getOid()); } } + ObjectFilter objSpecOwnerFilter = builder.buildFilter(); objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, objSpecOwnerFilter); LOGGER.trace(" applying owner filter {}", objSpecOwnerFilter); } else { @@ -1019,7 +1023,8 @@ private ObjectFilter preProcessObje // Org if (specOrgRef != null) { - OrgFilter orgFilter = OrgFilter.createOrg(specOrgRef.getOid()); + ObjectFilter orgFilter = QueryBuilder.queryFor(ObjectType.class, prismContext) + .isChildOf(specOrgRef.getOid()).buildFilter(); objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, orgFilter); LOGGER.trace(" applying org filter {}", orgFilter); } else { @@ -1032,23 +1037,21 @@ private ObjectFilter preProcessObje QName subjectRelation = specOrgRelation.getSubjectRelation(); for (ObjectReferenceType subjectParentOrgRef: principal.getUser().getParentOrgRef()) { if (MiscSchemaUtil.compareRelation(subjectRelation, subjectParentOrgRef.getRelation())) { - OrgFilter orgFilter = null; + S_FilterEntryOrEmpty q = QueryBuilder.queryFor(ObjectType.class, prismContext); + S_AtomicFilterExit q2; if (specOrgRelation.getScope() == null || specOrgRelation.getScope() == OrgScopeType.ALL_DESCENDANTS) { - orgFilter = OrgFilter.createOrg(subjectParentOrgRef.getOid(), OrgFilter.Scope.SUBTREE); + q2 = q.isChildOf(subjectParentOrgRef.getOid()); } else if (specOrgRelation.getScope() == OrgScopeType.DIRECT_DESCENDANTS) { - orgFilter = OrgFilter.createOrg(subjectParentOrgRef.getOid(), OrgFilter.Scope.ONE_LEVEL); + q2 = q.isDirectChildOf(subjectParentOrgRef.getOid()); } else if (specOrgRelation.getScope() == OrgScopeType.ALL_ANCESTORS) { - orgFilter = OrgFilter.createOrg(subjectParentOrgRef.getOid(), OrgFilter.Scope.ANCESTORS); + q2 = q.isParentOf(subjectParentOrgRef.getOid()); } else { throw new UnsupportedOperationException("Unknown orgRelation scope "+specOrgRelation.getScope()); } if (BooleanUtils.isTrue(specOrgRelation.isIncludeReferenceOrg())) { - InOidFilter oidFilter = InOidFilter.createInOid(subjectParentOrgRef.getOid()); - objSpecOrgRelationFilter = ObjectQueryUtil.filterAnd(objSpecOrgRelationFilter, - ObjectQueryUtil.filterOr(orgFilter, oidFilter)); - } else { - objSpecOrgRelationFilter = ObjectQueryUtil.filterAnd(objSpecOrgRelationFilter, orgFilter); + q2 = q2.or().id(subjectParentOrgRef.getOid()); } + objSpecOrgRelationFilter = ObjectQueryUtil.filterAnd(objSpecOrgRelationFilter, q2.buildFilter()); } } if (objSpecOrgRelationFilter == null) { diff --git a/repo/system-init/src/main/java/com/evolveum/midpoint/init/ConfigurablePrismContextFactory.java b/repo/system-init/src/main/java/com/evolveum/midpoint/init/ConfigurablePrismContextFactory.java index eab3de520e0..d8da9093935 100644 --- a/repo/system-init/src/main/java/com/evolveum/midpoint/init/ConfigurablePrismContextFactory.java +++ b/repo/system-init/src/main/java/com/evolveum/midpoint/init/ConfigurablePrismContextFactory.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration; import com.evolveum.midpoint.prism.schema.SchemaRegistry; +import com.evolveum.midpoint.prism.schema.SchemaRegistryImpl; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; @@ -50,7 +51,7 @@ public void setConfiguration(MidpointConfiguration configuration) { } @Override - protected void registerExtensionSchemas(SchemaRegistry schemaRegistry) throws SchemaException { + protected void registerExtensionSchemas(SchemaRegistryImpl schemaRegistry) throws SchemaException { Configuration config = configuration.getConfiguration(CONFIGURATION_GLOBAL); if (config == null) { LOGGER.warn("Global part 'midpoint.global' is not defined in configuration file."); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java index 1f336a81e33..78c9dd77d9c 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java @@ -22,11 +22,9 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.LessFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -47,16 +45,8 @@ import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPolicyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeErrorStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeExecutionStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationStatsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; - import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.quartz.JobKey; @@ -74,16 +64,8 @@ import javax.annotation.PreDestroy; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; - import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -155,7 +137,7 @@ public class TaskManagerQuartzImpl implements TaskManager, BeanFactoryAware { // Use ONLY for those actions that need to work with these instances, e.g. when calling heartbeat() methods on them. // For any other business please use LocalNodeManager.getLocallyRunningTasks(...). // Maps task id -> task - private HashMap locallyRunningTaskInstancesMap = new HashMap(); + private final HashMap locallyRunningTaskInstancesMap = new HashMap<>(); private ExecutorService lightweightHandlersExecutor = Executors.newCachedThreadPool(); @@ -1033,10 +1015,9 @@ public List> listSubtasksForTask(String taskIdentifier, Op if (StringUtils.isEmpty(taskIdentifier)) { return new ArrayList<>(); } - - ObjectFilter filter = null; - filter = EqualFilter.createEqual(TaskType.F_PARENT, TaskType.class, prismContext, null, taskIdentifier); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_PARENT).eq(taskIdentifier) + .build(); List> list; try { @@ -1658,24 +1639,17 @@ public PrismObject getTaskTypeByIdentifier(String identifier, Collecti result.addParam("identifier", identifier); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskManagerQuartzImpl.class); - PrismObject retval; + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_TASK_IDENTIFIER).eq(identifier) + .build(); -// TaskQuartzImpl transientTask = registeredTransientTasks.get(identifier); -// if (transientTask != null) { -// retval = transientTask.getTaskPrismObject(); -// } else { - // search the repo - ObjectFilter filter = EqualFilter.createEqual(TaskType.F_TASK_IDENTIFIER, TaskType.class, prismContext, null, identifier); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - - List> list = repositoryService.searchObjects(TaskType.class, query, options, result); - if (list.isEmpty()) { - throw new ObjectNotFoundException("Task with identifier " + identifier + " could not be found"); - } else if (list.size() > 1) { - throw new IllegalStateException("Found more than one task with identifier " + identifier + " (" + list.size() + " of them)"); - } - retval = list.get(0); -// } + List> list = repositoryService.searchObjects(TaskType.class, query, options, result); + if (list.isEmpty()) { + throw new ObjectNotFoundException("Task with identifier " + identifier + " could not be found"); + } else if (list.size() > 1) { + throw new IllegalStateException("Found more than one task with identifier " + identifier + " (" + list.size() + " of them)"); + } + PrismObject retval = list.get(0); if (SelectorOptions.hasToLoadPath(TaskType.F_SUBTASK, options)) { ClusterStatusInformation clusterStatusInformation = getClusterStatusInformation(options, TaskType.class, true, result); // returns null if noFetch is set fillInSubtasks(retval.asObjectable(), clusterStatusInformation, options, result); @@ -1716,10 +1690,10 @@ public void cleanupTasks(CleanupPolicyType policy, Task executionTask, Operation List> obsoleteTasks; try { - ObjectQuery obsoleteTasksQuery = ObjectQuery.createObjectQuery(AndFilter.createAnd( - LessFilter.createLess(TaskType.F_COMPLETION_TIMESTAMP, TaskType.class, getPrismContext(), timeXml, true), - EqualFilter.createEqual(TaskType.F_PARENT, TaskType.class, getPrismContext(), null))); - + ObjectQuery obsoleteTasksQuery = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_COMPLETION_TIMESTAMP).le(timeXml) + .and().item(TaskType.F_PARENT).isNull() + .build(); obsoleteTasks = repositoryService.searchObjects(TaskType.class, obsoleteTasksQuery, null, result); } catch (SchemaException e) { throw new SchemaException("Couldn't get the list of obsolete tasks: " + e.getMessage(), e); @@ -1843,29 +1817,20 @@ public void checkWaitingTasks(OperationResult result) throws SchemaException { try { ((TaskQuartzImpl) task).checkDependencies(result); count++; - } catch (SchemaException e) { - LoggingUtils.logException(LOGGER, "Couldn't check dependencies for task {}", e, task); - } catch (ObjectNotFoundException e) { + } catch (SchemaException | ObjectNotFoundException e) { LoggingUtils.logException(LOGGER, "Couldn't check dependencies for task {}", e, task); } - } + } LOGGER.trace("Check waiting tasks completed; {} tasks checked.", count); } private List listWaitingTasks(TaskWaitingReason reason, OperationResult result) throws SchemaException { - - ObjectFilter filter, filter1 = null, filter2 = null; -// try { - filter1 = EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, TaskType.class, prismContext, null, TaskExecutionStatusType.WAITING); - if (reason != null) { - filter2 = EqualFilter.createEqual(TaskType.F_WAITING_REASON, TaskType.class, prismContext, null, reason.toTaskType()); - } -// } catch (SchemaException e) { -// throw new SystemException("Cannot create filter for listing waiting tasks due to schema exception", e); -// } - filter = filter2 != null ? AndFilter.createAnd(filter1, filter2) : filter1; - ObjectQuery query = ObjectQuery.createObjectQuery(filter); -// query = new ObjectQuery(); // todo remove this hack when searching will work + S_AtomicFilterEntry q = QueryBuilder.queryFor(TaskType.class, prismContext); + q = q.item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.WAITING).and(); + if (reason != null) { + q = q.item(TaskType.F_WAITING_REASON).eq(reason.toTaskType()).and(); + } + ObjectQuery query = q.all().build(); List> prisms = repositoryService.searchObjects(TaskType.class, query, null, result); List tasks = resolveTasksFromTaskTypes(prisms, result); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java index db94681312b..ec2306f4aa2 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java @@ -41,6 +41,7 @@ import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.DeltaConvertor; @@ -2559,13 +2560,9 @@ public List> listPrerequisiteTasksRaw(OperationResult pare result.addContext(OperationResult.CONTEXT_OID, getOid()); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskQuartzImpl.class); - ObjectFilter filter = null; -// try { - filter = EqualFilter.createEqual(TaskType.F_DEPENDENT, TaskType.class, taskManager.getPrismContext(), null, getTaskIdentifier()); -// } catch (SchemaException e) { -// throw new SystemException("Cannot create filter for 'dependent contains task identifier' due to schema exception", e); -// } - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, getPrismContext()) + .item(TaskType.F_DEPENDENT).eq(getTaskIdentifier()) + .build(); List> list = taskManager.getRepositoryService().searchObjects(TaskType.class, query, null, result); result.recordSuccessIfUnknown(); diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/CleanupTest.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/CleanupTest.java index 2639dd9ad76..ec46da53a3c 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/CleanupTest.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/CleanupTest.java @@ -77,13 +77,11 @@ public void testTasksCleanup() throws Exception { // GIVEN final File file = new File(FOLDER_REPO, "tasks-for-cleanup.xml"); - List> elements = prismContext.parseObjects(file); + List> elements = prismContext.parserFor(file).parseObjects(); OperationResult result = new OperationResult("tasks cleanup"); - for (int i = 0; i < elements.size(); i++) { - PrismObject object = elements.get(i); - - String oid = repositoryService.addObject(object, null, result); + for (PrismObject object : elements) { + String oid = repositoryService.addObject((PrismObject) object, null, result); AssertJUnit.assertTrue(StringUtils.isNotEmpty(oid)); } diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java index 0f7a0d9b306..5e13fb6a634 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java @@ -34,6 +34,8 @@ import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.task.quartzimpl.execution.JobExecutor; @@ -257,7 +259,7 @@ public void test004aTaskBigProperty() throws Exception { // property definition QName bigStringQName = new QName("http://midpoint.evolveum.com/repo/test", "bigString"); - PrismPropertyDefinition bigStringDefinition = new PrismPropertyDefinition(bigStringQName, DOMUtil.XSD_STRING, taskManager.getPrismContext()); + PrismPropertyDefinitionImpl bigStringDefinition = new PrismPropertyDefinitionImpl(bigStringQName, DOMUtil.XSD_STRING, taskManager.getPrismContext()); bigStringDefinition.setIndexed(false); bigStringDefinition.setMinOccurs(0); bigStringDefinition.setMaxOccurs(1); @@ -285,7 +287,7 @@ public void test004aTaskBigProperty() throws Exception { task001.setExtensionProperty(bigStringProperty); // brutal hack, because task extension property has no "indexed" flag when retrieved from repo - task001.getExtensionProperty(bigStringQName).getDefinition().setIndexed(false); + ((PrismPropertyDefinitionImpl) task001.getExtensionProperty(bigStringQName).getDefinition()).setIndexed(false); System.out.println("2nd round: Task before save = " + task001.debugDump()); task001.savePendingModifications(result); // however, this does not work, because 'modifyObject' in repo first reads object, overwriting any existing definitions ... @@ -390,7 +392,7 @@ public void test004TaskProperties() throws Exception { System.out.println("Task extension = " + task.getExtension()); - PrismPropertyDefinition delayDefinition = new PrismPropertyDefinition(SchemaConstants.NOOP_DELAY_QNAME, DOMUtil.XSD_INT, taskManager.getPrismContext()); + PrismPropertyDefinition delayDefinition = new PrismPropertyDefinitionImpl(SchemaConstants.NOOP_DELAY_QNAME, DOMUtil.XSD_INT, taskManager.getPrismContext()); System.out.println("property definition = " + delayDefinition); PrismProperty property = (PrismProperty) delayDefinition.instantiate(); @@ -1415,8 +1417,8 @@ public void test020QueryByExecutionStatus() throws Exception { Task rootTask = taskManager.createTaskInstance((PrismObject) (PrismObject) addObjectFromFile(taskFilename(test)), result); String oid = rootTask.getOid(); - ObjectFilter filter1 = EqualFilter.createEqual(TaskType.F_EXECUTION_STATUS, TaskType.class, prismContext, null, TaskExecutionStatusType.WAITING); - ObjectFilter filter2 = EqualFilter.createEqual(TaskType.F_WAITING_REASON, TaskType.class, prismContext, null, TaskWaitingReasonType.WORKFLOW); + ObjectFilter filter1 = QueryBuilder.queryFor(TaskType.class, prismContext).item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.WAITING).buildFilter(); + ObjectFilter filter2 = QueryBuilder.queryFor(TaskType.class, prismContext).item(TaskType.F_WAITING_REASON).eq(TaskWaitingReasonType.WORKFLOW).buildFilter(); ObjectFilter filter3 = AndFilter.createAnd(filter1, filter2); List> prisms1 = repositoryService.searchObjects(TaskType.class, ObjectQuery.createObjectQuery(filter1), null, result); diff --git a/samples/objects/connector-dbtable.xml b/samples/objects/connector-dbtable.xml index 5a950f727cf..95895ce6118 100644 --- a/samples/objects/connector-dbtable.xml +++ b/samples/objects/connector-dbtable.xml @@ -22,7 +22,7 @@ discovered during system initialization. --> @@ -158,7 +158,7 @@ - + User Password diff --git a/samples/resources/scim1/Salesforce/resource-salesforce-scim-connector.xml b/samples/resources/scim1/Salesforce/resource-salesforce-scim-connector.xml index d81b50b4cfd..14187a44969 100644 --- a/samples/resources/scim1/Salesforce/resource-salesforce-scim-connector.xml +++ b/samples/resources/scim1/Salesforce/resource-salesforce-scim-connector.xml @@ -4,11 +4,11 @@ xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" - oid="2273edee-da5b-42ca-98e3-5563a7e5323a" - version="27"> + oid="714a197f-fa15-4eac-8f90-f1f2dfdcafc4" + version="15"> salesforce-scim-connector - 2016-10-27T10:14:47.254+02:00 + 2016-10-28T11:26:06.358+02:00 @@ -17,19 +17,22 @@ up - + + false + false true + false - - + + - 2016-10-27T10:15:05.763+02:00 - f2f1473497ffd1ac-11ce64a842ac5c8f + 2016-10-28T11:26:23.316+02:00 + 45a919c9bc0dea31-56642d0eab887904 120 + qn307:stringIgnoreCase displayName @@ -65,6 +69,7 @@ 130 + qn234:stringIgnoreCase members.external.value @@ -92,6 +97,7 @@ 160 + qn294:stringIgnoreCase members.User.value @@ -100,6 +106,7 @@ 170 + qn64:stringIgnoreCase members.uri.value @@ -111,6 +118,7 @@ 180 + qn373:stringIgnoreCase members.Group.value @@ -129,6 +137,7 @@ 190 read + qn451:stringIgnoreCase id @@ -137,6 +146,7 @@ 200 + qn318:stringIgnoreCase meta.version @@ -145,6 +155,7 @@ 210 + qn393:stringIgnoreCase meta.attributes @@ -160,101 +171,6 @@ - - - - - icfs:uid - icfs:name - icfs:name - icfs:name - Entitlements - - - - - - - 120 - displayName - - - - - - - 130 - meta.created - - - - - - - 140 - meta.lastModified - - - - - - - 150 - read - members.default.display - - - - - - - ConnId Name - 110 - __NAME__ - - - - - - - 160 - read - id - - - - - - - 170 - meta.version - - - - - - - 180 - members.default.value - - - - - - - ConnId UID - 100 - read - - - - - @@ -273,6 +189,7 @@ 120 + qn584:stringIgnoreCase phoneNumbers.work.value @@ -289,33 +206,36 @@ 140 + qn940:stringIgnoreCase phoneNumbers.work.display - + 150 - read - urn-salesforce-schemas-extension-external-1.0.accountId + qn627:stringIgnoreCase + phoneNumbers.fax.value - + 160 - phoneNumbers.fax.value + qn7:stringIgnoreCase + addresses.thumbnail.country - + 170 - addresses.thumbnail.country + urn-scim-schemas-extension-enterprise-1.0.delegatedApprover @@ -323,33 +243,37 @@ 180 + qn4:stringIgnoreCase phoneNumbers.mobile.value - + 190 - urn-scim-schemas-extension-enterprise-1.0.division + qn508:stringIgnoreCase + meta.version - + 200 - meta.version + qn237:stringIgnoreCase + name.givenName - + 210 - name.givenName + qn384:stringIgnoreCase + urn-scim-schemas-extension-enterprise-1.0.employeeNumber @@ -357,42 +281,46 @@ 220 + qn892:stringIgnoreCase profileUrl - + 230 - urn-scim-schemas-extension-enterprise-1.0.department + phoneNumbers.mobile.primary - + 240 - phoneNumbers.mobile.primary + qn502:stringIgnoreCase + userName - + 250 - userName + read + qn471:stringIgnoreCase + id - + 260 read - id + qn731:stringIgnoreCase + urn-scim-schemas-extension-enterprise-1.0.organization @@ -400,6 +328,7 @@ 270 + qn91:stringIgnoreCase timezone @@ -416,6 +345,7 @@ 290 + qn429:stringIgnoreCase addresses.work.streetAddress @@ -424,6 +354,7 @@ 300 + qn726:stringIgnoreCase emails.work.value @@ -432,6 +363,7 @@ 310 + qn728:stringIgnoreCase displayName @@ -440,17 +372,18 @@ 320 + qn890:stringIgnoreCase name.middleName 330 - urn-scim-schemas-extension-enterprise-1.0.manager + urn-salesforce-schemas-extension-00D58000000YfgfEAC @@ -458,24 +391,15 @@ 340 + qn943:stringIgnoreCase photos.thumbnail.value - - - - 350 - urn-scim-schemas-extension-enterprise-1.0.employeeNumber - - - - 360 + 350 photos.photo.primary @@ -483,7 +407,8 @@ - 370 + 360 + qn678:stringIgnoreCase roles.value @@ -491,7 +416,8 @@ - 380 + 370 + qn190:stringIgnoreCase name.familyName @@ -499,7 +425,8 @@ - 390 + 380 + qn238:stringIgnoreCase addresses.work.region @@ -507,7 +434,8 @@ - 400 + 390 + qn404:stringIgnoreCase addresses.thumbnail.locality @@ -515,7 +443,8 @@ - 410 + 400 + qn71:stringIgnoreCase nickName @@ -525,7 +454,8 @@ type="xsd:string"> - 420 + 410 + qn741:stringIgnoreCase addresses.thumbnail.streetAddress @@ -533,7 +463,8 @@ - 430 + 420 + qn94:stringIgnoreCase photos.photo.value @@ -541,17 +472,29 @@ - 440 + 430 + qn74:stringIgnoreCase groups.default.display + + + + 440 + urn-scim-schemas-extension-enterprise-1.0.manager + + + 450 + qn766:stringIgnoreCase addresses.thumbnail.formatted @@ -560,17 +503,19 @@ 460 + qn137:stringIgnoreCase preferredLanguage - 470 - urn-salesforce-schemas-extension-00D58000000YfgfEAC + read + qn498:stringIgnoreCase + urn-salesforce-schemas-extension-external-1.0.accountId @@ -578,6 +523,7 @@ 480 + qn927:stringIgnoreCase addresses.work.locality @@ -594,6 +540,7 @@ 500 + qn345:stringIgnoreCase roles.display @@ -610,6 +557,7 @@ 520 + qn983:stringIgnoreCase addresses.work.value @@ -618,6 +566,7 @@ 530 + qn222:stringIgnoreCase addresses.thumbnail.region @@ -626,6 +575,7 @@ 540 + qn65:stringIgnoreCase photos.photo.display @@ -650,6 +600,7 @@ 570 + qn155:stringIgnoreCase name.honorificSuffix @@ -658,6 +609,7 @@ 580 + qn231:stringIgnoreCase name.formatted @@ -676,6 +628,7 @@ 600 + qn126:stringIgnoreCase addresses.work.country @@ -684,6 +637,7 @@ 610 + qn189:stringIgnoreCase addresses.work.formatted @@ -692,6 +646,7 @@ 620 + qn637:stringIgnoreCase userType @@ -702,6 +657,7 @@ 630 + qn846:stringIgnoreCase addresses.thumbnail.postalCode @@ -723,52 +679,68 @@ - + 650 - entitlements.default.value + qn197:stringIgnoreCase + urn-salesforce-schemas-extension-external-1.0.contactId - + 660 - entitlements.default.display + qn482:stringIgnoreCase + urn-scim-schemas-extension-enterprise-1.0.division - + 670 - meta.lastModified + qn341:stringIgnoreCase + entitlements.default.value - + 680 - groups.default.value + qn815:stringIgnoreCase + entitlements.default.display - + 690 - read - urn-scim-schemas-extension-enterprise-1.0.organization + meta.lastModified - + 700 + qn798:stringIgnoreCase + groups.default.value + + + + + + + 710 + qn521:stringIgnoreCase addresses.thumbnail.value @@ -776,7 +748,8 @@ - 710 + 720 + qn696:stringIgnoreCase addresses.thumbnail.display @@ -784,7 +757,8 @@ - 720 + 730 + qn870:stringIgnoreCase addresses.work.display @@ -792,44 +766,38 @@ - 730 + 740 + qn907:stringIgnoreCase photos.thumbnail.display - 740 - urn-scim-schemas-extension-enterprise-1.0.delegatedApprover + 750 + qn756:stringIgnoreCase + urn-scim-schemas-extension-enterprise-1.0.department - 750 + 760 + qn771:stringIgnoreCase name.honorificPrefix - - - 760 - phoneNumbers.mobile.display - - - - 770 - urn-salesforce-schemas-extension-external-1.0.contactId + qn177:stringIgnoreCase + phoneNumbers.mobile.display @@ -837,6 +805,7 @@ 780 + qn699:stringIgnoreCase locale @@ -845,6 +814,7 @@ 790 + qn8:stringIgnoreCase phoneNumbers.fax.display @@ -853,6 +823,7 @@ 800 + qn191:stringIgnoreCase emails.work.display @@ -861,6 +832,7 @@ 810 + qn83:stringIgnoreCase addresses.work.postalCode @@ -877,6 +849,7 @@ 830 + qn429:stringIgnoreCase title @@ -892,6 +865,106 @@ + + + + + icfs:uid + icfs:name + icfs:name + icfs:name + Entitlements + + + + + + + 120 + qn416:stringIgnoreCase + displayName + + + + + + + 130 + meta.created + + + + + + + 140 + meta.lastModified + + + + + + + 150 + read + qn91:stringIgnoreCase + members.default.display + + + + + + + ConnId Name + 110 + __NAME__ + + + + + + + 160 + read + qn637:stringIgnoreCase + id + + + + + + + 170 + qn67:stringIgnoreCase + meta.version + + + + + + + 180 + qn551:stringIgnoreCase + members.default.value + + + + + + + ConnId UID + 100 + read + + + + + @@ -1239,8 +1312,8 @@ - 2016-10-27T10:15:11.888+02:00 - c19e0b3db5a3a89c-540f47a4e9ab9292 + 2016-10-28T11:26:31.256+02:00 + c830295a6053d6d3-6f8991bc5758331c diff --git a/samples/resources/scim1/Salesforce/role-default-salesforce-acount.xml b/samples/resources/scim1/Salesforce/role-default-salesforce-acount.xml index eabc2846df2..d1eeab41f7a 100644 --- a/samples/resources/scim1/Salesforce/role-default-salesforce-acount.xml +++ b/samples/resources/scim1/Salesforce/role-default-salesforce-acount.xml @@ -5,7 +5,7 @@ xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" oid="056f714a-efac-476f-b38e-9588b4907e5b" - version="6"> + version="7"> Default salesforce account 2016-07-01T14:32:58.978+02:00 @@ -17,7 +17,7 @@ account diff --git a/samples/resources/scim1/Salesforce/role-entitlement-metarole.xml b/samples/resources/scim1/Salesforce/role-entitlement-metarole.xml index f307075b51f..661aba02a6b 100644 --- a/samples/resources/scim1/Salesforce/role-entitlement-metarole.xml +++ b/samples/resources/scim1/Salesforce/role-entitlement-metarole.xml @@ -5,7 +5,7 @@ xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" oid="bf4e629b-de8c-4af2-b58d-99e18e270ebb" - version="10"> + version="11"> entitlement metarole 2016-07-19T17:47:56.771+02:00 @@ -17,7 +17,7 @@ account default diff --git a/samples/resources/scim1/Salesforce/role-group-metarole.xml b/samples/resources/scim1/Salesforce/role-group-metarole.xml index ec194a7bb18..b368002e1b7 100644 --- a/samples/resources/scim1/Salesforce/role-group-metarole.xml +++ b/samples/resources/scim1/Salesforce/role-group-metarole.xml @@ -5,7 +5,7 @@ xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" oid="a5bcd1cc-eb8a-469e-8ff2-3f5c6f97c463" - version="11"> + version="12"> group metarole 2016-07-14T13:31:38.481+02:00 @@ -17,7 +17,7 @@ account default diff --git a/samples/resources/scim1/Slack/resource-slack-scim-connector.xml b/samples/resources/scim1/Slack/resource-slack-scim-connector.xml index 5c04ab23997..8aa6b37bab3 100644 --- a/samples/resources/scim1/Slack/resource-slack-scim-connector.xml +++ b/samples/resources/scim1/Slack/resource-slack-scim-connector.xml @@ -4,11 +4,11 @@ xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" - oid="5d2b9b68-3bba-43b0-8089-b608f77f1c38" - version="7"> + oid="2556e12c-d5ef-42bb-8079-abea9526face" + version="10"> slack-scim-connector - 2016-10-27T11:49:26.257+02:00 + 2016-10-28T11:47:54.906+02:00 @@ -17,19 +17,38 @@ up - + + false + false true + false - - + + token + + + + http://www.w3.org/2001/04/xmlenc#aes128-cbc + + + 2Z/SQYgWVapuNTIU3bGrwHCi+04= + + + Iw7VIKi4OgNT9L3Q4cYXCPiXDthkU6cVoup+Hfn7uVfpZWca03uVCzxQreBxhKGYVeQ8Xt6igYMaec2SXtW/AsuCpdrxPQXHz7rDesRUu/uIEKkNhKHXdDVeLRGApArb + + + + /scim + /v1 + https://api.slack.com - 2016-10-27T11:49:35.169+02:00 - 32e50b9c813c3f68-9f17646c139b4704 + 2016-10-28T11:48:01.320+02:00 + 4a4506c1ebb47858-91158b52c815628e 120 read + qn443:stringIgnoreCase emails.other.display @@ -68,6 +88,7 @@ 130 + qn691:stringIgnoreCase emails.other.value @@ -88,6 +109,7 @@ 150 + qn723:stringIgnoreCase name.honorificSuffix @@ -96,6 +118,7 @@ 160 + qn770:stringIgnoreCase name.formatted @@ -112,6 +135,7 @@ 180 + qn14:stringIgnoreCase name.givenName @@ -120,6 +144,7 @@ 190 + qn153:stringIgnoreCase profileUrl @@ -128,6 +153,7 @@ 200 + qn719:stringIgnoreCase userName @@ -146,6 +172,7 @@ 210 read + qn560:stringIgnoreCase id @@ -154,6 +181,7 @@ 220 + qn350:stringIgnoreCase timezone @@ -163,6 +191,7 @@ 230 read + qn496:stringIgnoreCase emails.home.display @@ -179,6 +208,7 @@ 250 + qn492:stringIgnoreCase emails.work.value @@ -187,6 +217,7 @@ 260 + qn934:stringIgnoreCase displayName @@ -195,6 +226,7 @@ 270 + qn937:stringIgnoreCase emails.home.value @@ -203,6 +235,7 @@ 280 + qn418:stringIgnoreCase name.middleName @@ -212,6 +245,7 @@ 290 read + qn447:stringIgnoreCase groups.default.value @@ -236,6 +270,7 @@ 320 + qn587:stringIgnoreCase name.familyName @@ -244,6 +279,7 @@ 330 + qn476:stringIgnoreCase name.honorificPrefix @@ -252,6 +288,7 @@ 340 + qn461:stringIgnoreCase nickName @@ -264,6 +301,7 @@ 350 read + qn555:stringIgnoreCase groups.default.display @@ -273,6 +311,7 @@ 360 read + qn413:stringIgnoreCase emails.work.display @@ -281,6 +320,7 @@ 370 + qn926:stringIgnoreCase title @@ -329,6 +369,7 @@ 120 read + qn663:stringIgnoreCase displayName @@ -341,6 +382,7 @@ 130 read + qn104:stringIgnoreCase members.default.display @@ -359,6 +401,7 @@ 140 read + qn559:stringIgnoreCase id @@ -370,6 +413,7 @@ 150 read + qn306:stringIgnoreCase members.default.value @@ -629,8 +673,8 @@ - 2016-10-27T11:49:39.201+02:00 - eaef7e342ed70d48-5662263e87651497 + 2016-10-28T11:48:03.890+02:00 + 453b9048fccbcf02-a9092447aec1ddb @@ -647,12 +691,12 @@ + connector - diff --git a/samples/resources/scim1/Slack/role-default-slack-account.xml b/samples/resources/scim1/Slack/role-default-slack-account.xml index eaa104e0852..c508e379076 100644 --- a/samples/resources/scim1/Slack/role-default-slack-account.xml +++ b/samples/resources/scim1/Slack/role-default-slack-account.xml @@ -5,7 +5,7 @@ xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" oid="5ae47cad-f67d-4b34-a97b-03315666db68" - version="5"> + version="6"> Default slack account 2016-09-05T13:20:30.302+02:00 @@ -17,7 +17,7 @@ account diff --git a/samples/resources/scim1/Slack/role-group-metarole.xml b/samples/resources/scim1/Slack/role-group-metarole.xml index b0ae7cfc89d..c42be2a3836 100644 --- a/samples/resources/scim1/Slack/role-group-metarole.xml +++ b/samples/resources/scim1/Slack/role-group-metarole.xml @@ -5,7 +5,7 @@ xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" oid="1a641f93-0e91-4e23-9dc7-21523c7688ba" - version="12"> + version="13"> group metarole slack 2016-08-12T13:59:22.396+02:00 @@ -17,7 +17,7 @@ account default diff --git a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractEDirTest.java b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractEDirTest.java index b64a01fb89f..9ce28a2746c 100644 --- a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractEDirTest.java +++ b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractEDirTest.java @@ -27,6 +27,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import org.apache.directory.api.ldap.model.cursor.CursorException; import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.exception.LdapException; @@ -416,11 +417,11 @@ public void test190SeachLockedAccounts() throws Exception { // GIVEN Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - - ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext); - ObjectQueryUtil.filterAnd(query.getFilter(), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS), getShadowDefinition(), LockoutStatusType.LOCKED)); - + + ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassFilterPrefix(getResourceOid(), getAccountObjectClass(), prismContext) + .and().item(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).eq(LockoutStatusType.LOCKED) + .build(); + SearchResultList> searchResultList = doSearch(TEST_NAME, query, 1, task, result); assertConnectorOperationIncrement(1); @@ -916,10 +917,9 @@ public void test810SeachLockedAccounts() throws Exception { Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME); OperationResult result = task.getResult(); - ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext); - ObjectQueryUtil.filterAnd(query.getFilter(), - EqualFilter.createEqual(new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS), getShadowDefinition(), LockoutStatusType.LOCKED)); - + ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassFilterPrefix(getResourceOid(), getAccountObjectClass(), prismContext) + .and().item(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).eq(LockoutStatusType.LOCKED) + .build(); SearchResultList> searchResultList = doSearch(TEST_NAME, query, 0, task, result); assertConnectorOperationIncrement(1); diff --git a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapTest.java b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapTest.java index aa5a3520e23..a4b306bf521 100644 --- a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapTest.java +++ b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapTest.java @@ -40,6 +40,7 @@ import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.impl.sync.ReconciliationTaskHandler; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.Holder; import com.evolveum.midpoint.util.aspect.ProfilingDataManager; @@ -446,9 +447,10 @@ public void test020Schema() throws Exception { } protected ObjectFilter createAttributeFilter(String attrName, T attrVal) throws SchemaException { - ResourceAttributeDefinition ldapUidAttrDef = accountObjectClassDefinition.findAttributeDefinition(attrName); - return EqualFilter.createEqual( - new ItemPath(ShadowType.F_ATTRIBUTES, ldapUidAttrDef.getName()), ldapUidAttrDef, attrVal); + ResourceAttributeDefinition ldapAttrDef = accountObjectClassDefinition.findAttributeDefinition(attrName); + return QueryBuilder.queryFor(ShadowType.class, prismContext) + .itemWithDef(ldapAttrDef, ShadowType.F_ATTRIBUTES, ldapAttrDef.getName()).eq(attrVal) + .buildFilter(); } protected ObjectQuery createUidQuery(String uid) throws SchemaException { diff --git a/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java b/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java index d5e7045f143..13c31d8def1 100644 --- a/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java +++ b/testing/consistency-mechanism/src/test/java/com/evolveum/midpoint/testing/consistency/ConsistencyTest.java @@ -40,6 +40,7 @@ import javax.xml.namespace.QName; import javax.xml.ws.Holder; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import org.apache.commons.lang.StringUtils; import org.opends.server.types.Entry; import org.opends.server.util.EmbeddedUtils; @@ -2323,7 +2324,7 @@ private void checkOpenDjResource(ResourceType resource, String source) throws Sc } private void checkOpenDjSchema(ResourceType resource, String source) throws SchemaException { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition accountDefinition = schema.findObjectClassDefinition(RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS); assertNotNull("Schema does not define any account (resource from " + source + ")", accountDefinition); Collection identifiers = accountDefinition.getPrimaryIdentifiers(); diff --git a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java index ce5fdd037cf..303e4488d9f 100644 --- a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java +++ b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java @@ -50,21 +50,16 @@ import javax.xml.namespace.QName; import javax.xml.ws.Holder; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.task.api.TaskManagerException; import com.evolveum.midpoint.util.exception.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.opends.server.core.ModifyOperation; import org.opends.server.protocols.internal.InternalSearchOperation; -import org.opends.server.types.Attribute; -import org.opends.server.types.AttributeValue; -import org.opends.server.types.DereferencePolicy; -import org.opends.server.types.DirectoryException; +import org.opends.server.types.*; import org.opends.server.types.ModificationType; -import org.opends.server.types.RawModification; -import org.opends.server.types.ResultCode; -import org.opends.server.types.Entry; -import org.opends.server.types.SearchScope; import org.opends.server.util.ChangeRecordEntry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @@ -80,14 +75,6 @@ import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ItemDelta; @@ -96,7 +83,7 @@ import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.match.StringIgnoreCaseMatchingRule; -import com.evolveum.midpoint.prism.parser.util.XNodeProcessorUtil; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorUtil; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; @@ -589,7 +576,7 @@ private void checkOpenDjResource(ResourceType resource, String source) throws Sc } private void checkOpenDjSchema(ResourceType resource, String source) throws SchemaException { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition accountDefinition = schema.findObjectClassDefinition(RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS); assertNotNull("Schema does not define any account (resource from " + source + ")", accountDefinition); Collection identifiers = accountDefinition.getPrimaryIdentifiers(); @@ -709,14 +696,21 @@ public void test002AddDerbyResource() throws Exception { display("DB Connector: ", dbConnector); // Check if password was encrypted during import + // via JAXB Object configurationPropertiesElement = JAXBUtil.findElement(derbyResource.asObjectable().getConnectorConfiguration().getAny(), new QName(dbConnector.asObjectable().getNamespace(), "configurationProperties")); Object passwordElement = JAXBUtil.findElement(JAXBUtil.listChildElements(configurationPropertiesElement), new QName(dbConnector.asObjectable().getNamespace(), "password")); System.out.println("Password element: " + passwordElement); - - + // via prisms + PrismContainerValue configurationProperties = derbyResource.findContainer( + new ItemPath( + ResourceType.F_CONNECTOR_CONFIGURATION, + new QName("configurationProperties"))) + .getValue(); + PrismProperty password = configurationProperties.findProperty(new QName(dbConnector.asObjectable().getNamespace(), "password")); + System.out.println("Password property: " + password); } private void addObjectViaModelWS(ObjectType objectType, ModelExecuteOptionsType options, Holder oidHolder, Holder resultHolder) throws FaultMessage { @@ -1295,7 +1289,7 @@ public void test016ProvisioningSearchAccountsIterative() throws Exception { // GIVEN OperationResult result = new OperationResult(TestSanity.class.getName() + ".test016ProvisioningSearchAccountsIterative"); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceTypeOpenDjrepo, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceTypeOpenDjrepo, prismContext); final RefinedObjectClassDefinition refinedAccountDefinition = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); QName objectClass = refinedAccountDefinition.getObjectClassDefinition().getTypeName(); @@ -1489,7 +1483,7 @@ public void test023ChangeUserPasswordJAXB() throws Exception { passwordDelta.setPath(ModelClientUtil.createItemPathType("credentials/password/value")); ProtectedStringType pass = new ProtectedStringType(); pass.setClearValue(NEW_PASSWORD); - XNode passValue = prismContext.getBeanConverter().marshall(pass); + XNode passValue = ((PrismContextImpl) prismContext).getBeanMarshaller().marshall(pass); System.out.println("PASSWORD VALUE: " + passValue.debugDump()); RawType passwordValue = new RawType(passValue, prismContext); passwordDelta.getValue().add(passwordValue); @@ -1878,7 +1872,7 @@ public void test040UnlinkDerbyAccountFromUser() throws FileNotFoundException, JA modificationDeleteAccountRef.setModificationType(ModificationTypeType.DELETE); ObjectReferenceType accountRefToDelete = new ObjectReferenceType(); accountRefToDelete.setOid(accountShadowOidDerby); - RawType modificationValue = new RawType(prismContext.getBeanConverter().marshall(accountRefToDelete), prismContext); + RawType modificationValue = new RawType(((PrismContextImpl) prismContext).getBeanMarshaller().marshall(accountRefToDelete), prismContext); modificationDeleteAccountRef.getValue().add(modificationValue); modificationDeleteAccountRef.setPath(new ItemPathType(new ItemPath(UserType.F_LINK_REF))); objectChange.getItemDelta().add(modificationDeleteAccountRef); @@ -3782,8 +3776,8 @@ public void test500NotifyChangeCreateAccount() throws Exception{ ShadowType anglicaAccount = parseObjectType(new File(ACCOUNT_ANGELIKA_FILENAME), ShadowType.class); PrismProperty prop = anglicaAccount.asPrismObject().findContainer(ShadowType.F_ATTRIBUTES).getValue().createProperty( - new PrismPropertyDefinition<>(getOpenDjPrimaryIdentifierQName(), DOMUtil.XSD_STRING, prismContext)); - prop.setValue(new PrismPropertyValue(entryUuid)); + new PrismPropertyDefinitionImpl<>(getOpenDjPrimaryIdentifierQName(), DOMUtil.XSD_STRING, prismContext)); + prop.setValue(new PrismPropertyValue<>(entryUuid)); anglicaAccount.setResourceRef(ObjectTypeUtil.createObjectRef(RESOURCE_OPENDJ_OID, ObjectTypes.RESOURCE)); display("Angelica shadow: ", anglicaAccount.asPrismObject().debugDump()); @@ -3908,7 +3902,7 @@ public void test502NotifyChangeModifyAccountPassword() throws Exception{ ItemDeltaType passwordDelta = new ItemDeltaType(); passwordDelta.setModificationType(ModificationTypeType.REPLACE); passwordDelta.setPath(ModelClientUtil.createItemPathType("credentials/password/value")); - RawType passwordValue = new RawType(prismContext.getBeanConverter().marshall(ModelClientUtil.createProtectedString(newPassword)), prismContext); + RawType passwordValue = new RawType(((PrismContextImpl) prismContext).getBeanMarshaller().marshall(ModelClientUtil.createProtectedString(newPassword)), prismContext); passwordDelta.getValue().add(passwordValue); delta.getItemDelta().add(passwordDelta); diff --git a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java index 4e2353b8583..85dc5ed874f 100644 --- a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java +++ b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java @@ -45,21 +45,16 @@ import javax.xml.namespace.QName; import javax.xml.ws.Holder; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.task.api.TaskManagerException; import com.evolveum.midpoint.util.exception.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.opends.server.core.ModifyOperation; import org.opends.server.protocols.internal.InternalSearchOperation; -import org.opends.server.types.Attribute; -import org.opends.server.types.AttributeValue; -import org.opends.server.types.DereferencePolicy; -import org.opends.server.types.DirectoryException; +import org.opends.server.types.*; import org.opends.server.types.ModificationType; -import org.opends.server.types.RawModification; -import org.opends.server.types.ResultCode; -import org.opends.server.types.Entry; -import org.opends.server.types.SearchScope; import org.opends.server.util.ChangeRecordEntry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @@ -75,14 +70,6 @@ import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ItemDelta; @@ -91,7 +78,7 @@ import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.match.StringIgnoreCaseMatchingRule; -import com.evolveum.midpoint.prism.parser.util.XNodeProcessorUtil; +import com.evolveum.midpoint.prism.marshaller.XNodeProcessorUtil; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; @@ -577,7 +564,7 @@ private void checkOpenDjResource(ResourceType resource, String source) throws Sc } private void checkOpenDjSchema(ResourceType resource, String source) throws SchemaException { - ResourceSchema schema = RefinedResourceSchema.getResourceSchema(resource, prismContext); + ResourceSchema schema = RefinedResourceSchemaImpl.getResourceSchema(resource, prismContext); ObjectClassComplexTypeDefinition accountDefinition = schema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT); assertNotNull("Schema does not define any account (resource from " + source + ")", accountDefinition); Collection identifiers = accountDefinition.getPrimaryIdentifiers(); @@ -1058,14 +1045,14 @@ public void test016ProvisioningSearchAccountsIterative() throws Exception { // GIVEN OperationResult result = new OperationResult(TestSanityLegacy.class.getName() + ".test016ProvisioningSearchAccountsIterative"); - RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resourceTypeOpenDjrepo, prismContext); + RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resourceTypeOpenDjrepo, prismContext); final RefinedObjectClassDefinition refinedAccountDefinition = refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); QName objectClass = refinedAccountDefinition.getObjectClassDefinition().getTypeName(); ObjectQuery q = ObjectQueryUtil.createResourceAndObjectClassQuery(resourceTypeOpenDjrepo.getOid(), objectClass, prismContext); // ObjectQuery q = QueryConvertor.createObjectQuery(ResourceObjectShadowType.class, query, prismContext); - final Collection objects = new HashSet(); + final Collection objects = new HashSet<>(); final MatchingRule caseIgnoreMatchingRule = matchingRuleRegistry.getMatchingRule(StringIgnoreCaseMatchingRule.NAME, DOMUtil.XSD_STRING); ResultHandler handler = new ResultHandler() { @@ -1251,7 +1238,7 @@ public void test023ChangeUserPasswordJAXB() throws Exception { passwordDelta.setPath(ModelClientUtil.createItemPathType("credentials/password/value")); ProtectedStringType pass = new ProtectedStringType(); pass.setClearValue(NEW_PASSWORD); - XNode passValue = prismContext.getBeanConverter().marshall(pass); + XNode passValue = ((PrismContextImpl) prismContext).getBeanMarshaller().marshall(pass); System.out.println("PASSWORD VALUE: " + passValue.debugDump()); RawType passwordValue = new RawType(passValue, prismContext); passwordDelta.getValue().add(passwordValue); @@ -3579,7 +3566,7 @@ public void test502NotifyChangeModifyAccountPassword() throws Exception{ ItemDeltaType passwordDelta = new ItemDeltaType(); passwordDelta.setModificationType(ModificationTypeType.REPLACE); passwordDelta.setPath(ModelClientUtil.createItemPathType("credentials/password/value")); - RawType passwordValue = new RawType(prismContext.getBeanConverter().marshall(ModelClientUtil.createProtectedString(newPassword)), prismContext); + RawType passwordValue = new RawType(((PrismContextImpl) prismContext).getBeanMarshaller().marshall(ModelClientUtil.createProtectedString(newPassword)), prismContext); passwordDelta.getValue().add(passwordValue); // ItemDeltaType mod1 = new ItemDeltaType(); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java index 48d7aa45f5b..b2206ba43ee 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -28,6 +28,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestVillage.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestVillage.java index fd889f928ea..c6ab697f088 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestVillage.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestVillage.java @@ -943,11 +943,12 @@ public void test310ProjectJollyRogerNestedGroup() throws Exception { display("LDAP entries", openDJController.dumpEntries()); - ObjectFilter baseFilter = ObjectQueryUtil.createResourceAndObjectClassFilter(RESOURCE_OPENDJ_OID, GROUP_OF_UNIQUE_NAMES_OBJECTCLASS_QNAME, prismContext); - ObjectFilter filter = ObjectQueryUtil.filterAnd(baseFilter, EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, new QName(RESOURCE_OPENDJ_NAMESPACE, "cn")), - new PrismPropertyDefinition<>(new QName(RESOURCE_OPENDJ_NAMESPACE, "cn"), DOMUtil.XSD_STRING, prismContext), "admins")); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); - + ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassFilterPrefix(RESOURCE_OPENDJ_OID, GROUP_OF_UNIQUE_NAMES_OBJECTCLASS_QNAME, prismContext) + .and().itemWithDef( + new PrismPropertyDefinition<>(new QName(RESOURCE_OPENDJ_NAMESPACE, "cn"), DOMUtil.XSD_STRING, prismContext), + ShadowType.F_ATTRIBUTES, new QName(RESOURCE_OPENDJ_NAMESPACE, "cn")).eq("admins") + .build(); + // WHEN TestUtil.displayWhen(TEST_NAME); // TODO: search for cn=admins,ou=Jolly Roger,dc=example,dc=com diff --git a/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java b/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java index 52feb5c13d1..f52acf2ac80 100644 --- a/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java +++ b/tools/xjc-plugin/src/main/java/com/evolveum/midpoint/schema/xjc/schema/SchemaProcessor.java @@ -478,7 +478,10 @@ private JMethod createPrismContextContainerableConstructor(JDefinedClass defined constructor.param(PrismContext.class, "prismContext"); JBlock body = constructor.body(); - body.invoke(setupContainerMethod).arg(JExpr._new(CLASS_MAP.get(PrismContainerValue.class)).arg(constructor.params().get(0))); + body.invoke(setupContainerMethod) // setupContainerValue( + .arg(JExpr._new(CLASS_MAP.get(PrismContainerValue.class).narrow(new JClass[0])) // new PrismContainerValue<>( + .arg(JExpr._this()) // this, + .arg(constructor.params().get(0))); // prismContext); return constructor; } @@ -528,9 +531,12 @@ private void createAsPrismContainerValue(JDefinedClass definedClass, JVar contai //create method body JBlock body = getContainer.body(); - JBlock then = body._if(containerValueVar.eq(JExpr._null()))._then(); - then.assign(containerValueVar, JExpr._new(CLASS_MAP.get(PrismContainerValue.class))); - + body._if(containerValueVar.eq(JExpr._null())). // if (_containerValue == null) { + _then() // + .assign(containerValueVar, // _containerValue = + JExpr._new(CLASS_MAP.get(PrismContainerValue.class).narrow(new JClass[0])) // new PrismContainerValue<>( + .arg(JExpr._this()) // this) + ); body._return(containerValueVar); }