use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.
the class RObjectTextInfo method createItemsSet.
public static Set<RObjectTextInfo> createItemsSet(@NotNull ObjectType object, @NotNull RObject repo, @NotNull RepositoryContext repositoryContext) {
FullTextSearchConfigurationType config = repositoryContext.repositoryService.getFullTextSearchConfiguration();
if (!FullTextSearchUtil.isEnabled(config)) {
return Collections.emptySet();
}
Set<ItemPath> paths = FullTextSearchUtil.getFullTextSearchItemPaths(config, object.getClass());
List<PrismValue> values = new ArrayList<>();
for (ItemPath path : paths) {
Object o = object.asPrismObject().find(path);
if (o == null) {
// shouldn't occur
} else if (o instanceof PrismValue) {
values.add((PrismValue) o);
} else if (o instanceof Item) {
values.addAll(((Item<?, ?>) o).getValues());
} else {
throw new IllegalStateException("Unexpected value " + o + " in " + object + " at " + path);
}
}
// not a (hash) set in order to preserve order
List<String> allWords = new ArrayList<>();
for (PrismValue value : values) {
if (value == null) {
continue;
}
if (value instanceof PrismPropertyValue) {
Object realValue = value.getRealValue();
if (realValue == null) {
// skip
} else if (realValue instanceof String) {
append(allWords, (String) realValue, repositoryContext.prismContext);
} else if (realValue instanceof PolyString) {
append(allWords, (PolyString) realValue, repositoryContext.prismContext);
} else {
append(allWords, realValue.toString(), repositoryContext.prismContext);
}
}
}
int maxTextSize = repositoryContext.configuration.getTextInfoColumnSize();
LOGGER.trace("Indexing {}:\n items: {}\n values: {}\n words: {}\n max text size: {}", object, paths, values, allWords, maxTextSize);
return createItemsSet(repo, allWords, maxTextSize);
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.
the class ApprovalProcessExecutionInformationPanel method initLayout.
protected void initLayout() {
// TODO clean this code up!!!
ListView<ApprovalStageExecutionInformationDto> stagesList = new ListView<ApprovalStageExecutionInformationDto>(ID_STAGES, new PropertyModel<>(getModel(), ApprovalProcessExecutionInformationDto.F_STAGES)) {
@Override
protected void populateItem(ListItem<ApprovalStageExecutionInformationDto> stagesListItem) {
ApprovalProcessExecutionInformationDto process = ApprovalProcessExecutionInformationPanel.this.getModelObject();
ApprovalStageExecutionInformationDto stage = stagesListItem.getModelObject();
int stageNumber = stage.getStageNumber();
int numberOfStages = process.getNumberOfStages();
int currentStageNumber = process.getCurrentStageNumber();
WebMarkupContainer arrow = new WebMarkupContainer(ID_ARROW);
arrow.add(new VisibleBehaviour(() -> stageNumber > 1));
stagesListItem.add(arrow);
WebMarkupContainer currentStageMarker = new WebMarkupContainer(ID_CURRENT_STAGE_MARKER);
currentStageMarker.add(new VisibleBehaviour(() -> stageNumber == currentStageNumber && process.isRunning()));
stagesListItem.add(currentStageMarker);
ListView<ApproverEngagementDto> approversList = new ListView<ApproverEngagementDto>(ID_APPROVERS, new PropertyModel<>(stagesListItem.getModel(), ApprovalStageExecutionInformationDto.F_APPROVER_ENGAGEMENTS)) {
@Override
protected void populateItem(ListItem<ApproverEngagementDto> approversListItem) {
ApproverEngagementDto ae = approversListItem.getModelObject();
// original approver name
approversListItem.add(createReferencedObjectLabel(ID_APPROVER_NAME, "ApprovalProcessExecutionInformationPanel.approver", ae.getApproverRef(), true));
// outcome
WorkItemOutcomeType outcome = ae.getOutput() != null ? ApprovalUtils.fromUri(ae.getOutput().getOutcome()) : null;
ApprovalOutcomeIcon outcomeIcon;
if (outcome != null) {
switch(outcome) {
case APPROVE:
outcomeIcon = ApprovalOutcomeIcon.APPROVED;
break;
case REJECT:
outcomeIcon = ApprovalOutcomeIcon.REJECTED;
break;
// perhaps should throw AssertionError instead
default:
outcomeIcon = ApprovalOutcomeIcon.UNKNOWN;
break;
}
} else {
if (stageNumber < currentStageNumber) {
// history: do not show anything for work items with no outcome
outcomeIcon = ApprovalOutcomeIcon.EMPTY;
} else if (stageNumber == currentStageNumber) {
outcomeIcon = process.isRunning() && stage.isReachable() ? ApprovalOutcomeIcon.IN_PROGRESS : // currently open
ApprovalOutcomeIcon.CANCELLED;
} else {
outcomeIcon = process.isRunning() && stage.isReachable() ? ApprovalOutcomeIcon.FUTURE : ApprovalOutcomeIcon.CANCELLED;
}
}
ImagePanel outcomePanel = new ImagePanel(ID_OUTCOME, Model.of(outcomeIcon.getIcon()), Model.of(getString(outcomeIcon.getTitle())));
outcomePanel.add(new VisibleBehaviour(() -> outcomeIcon != ApprovalOutcomeIcon.EMPTY));
approversListItem.add(outcomePanel);
// content (incl. performer)
WebMarkupContainer approvalBoxContent = new WebMarkupContainer(ID_APPROVAL_BOX_CONTENT);
approversListItem.add(approvalBoxContent);
approvalBoxContent.setVisible(performerVisible(ae) || attorneyVisible(ae));
approvalBoxContent.add(createReferencedObjectLabel(ID_PERFORMER_NAME, "ApprovalProcessExecutionInformationPanel.performer", ae.getCompletedBy(), performerVisible(ae)));
approvalBoxContent.add(createReferencedObjectLabel(ID_ATTORNEY_NAME, "ApprovalProcessExecutionInformationPanel.attorney", ae.getAttorney(), attorneyVisible(ae)));
// junction
// or "+" for first decides? probably not
Label junctionLabel = new Label(ID_JUNCTION, stage.isFirstDecides() ? "" : " & ");
// not showing "" to save space (if aligned vertically)
junctionLabel.setVisible(!stage.isFirstDecides() && !ae.isLast());
approversListItem.add(junctionLabel);
}
};
approversList.setVisible(stage.getAutomatedCompletionReason() == null);
stagesListItem.add(approversList);
String autoCompletionKey;
if (stage.getAutomatedCompletionReason() != null) {
switch(stage.getAutomatedCompletionReason()) {
case AUTO_COMPLETION_CONDITION:
autoCompletionKey = "DecisionDto.AUTO_COMPLETION_CONDITION";
break;
case NO_ASSIGNEES_FOUND:
autoCompletionKey = "DecisionDto.NO_ASSIGNEES_FOUND";
break;
// or throw an exception?
default:
autoCompletionKey = null;
}
} else {
autoCompletionKey = null;
}
Label automatedOutcomeLabel = new Label(ID_AUTOMATED_OUTCOME, autoCompletionKey != null ? getString(autoCompletionKey) : "");
automatedOutcomeLabel.setVisible(stage.getAutomatedCompletionReason() != null);
stagesListItem.add(automatedOutcomeLabel);
stagesListItem.add(new Label(ID_STAGE_NAME, getStageNameLabel(stage, stageNumber, numberOfStages)));
ApprovalLevelOutcomeType stageOutcome = stage.getOutcome();
ApprovalOutcomeIcon stageOutcomeIcon;
if (stageOutcome != null) {
switch(stageOutcome) {
case APPROVE:
stageOutcomeIcon = ApprovalOutcomeIcon.APPROVED;
break;
case REJECT:
stageOutcomeIcon = ApprovalOutcomeIcon.REJECTED;
break;
case SKIP:
stageOutcomeIcon = ApprovalOutcomeIcon.SKIPPED;
break;
// perhaps should throw AssertionError instead
default:
stageOutcomeIcon = ApprovalOutcomeIcon.UNKNOWN;
break;
}
} else {
if (stageNumber < currentStageNumber) {
// history: do not show anything (shouldn't occur, as historical stages are filled in)
stageOutcomeIcon = ApprovalOutcomeIcon.EMPTY;
} else if (stageNumber == currentStageNumber) {
stageOutcomeIcon = process.isRunning() && stage.isReachable() ? ApprovalOutcomeIcon.IN_PROGRESS : // currently open
ApprovalOutcomeIcon.CANCELLED;
} else {
stageOutcomeIcon = process.isRunning() && stage.isReachable() ? ApprovalOutcomeIcon.FUTURE : ApprovalOutcomeIcon.CANCELLED;
}
}
ImagePanel stageOutcomePanel = new ImagePanel(ID_STAGE_OUTCOME, Model.of(stageOutcomeIcon.getIcon()), Model.of(getString(stageOutcomeIcon.getTitle())));
stageOutcomePanel.add(new VisibleBehaviour(() -> stageOutcomeIcon != ApprovalOutcomeIcon.EMPTY));
stagesListItem.add(stageOutcomePanel);
}
};
add(stagesList);
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.
the class ValuePolicyProcessor method cardinalityCounter.
/**
* Count cardinality
*/
private Map<Integer, List<String>> cardinalityCounter(Map<StringLimitType, List<String>> lims, List<String> password, Boolean skipMatchedLims, boolean uniquenessReached, OperationResult op) {
HashMap<String, Integer> counter = new HashMap<>();
for (Map.Entry<StringLimitType, List<String>> entry : lims.entrySet()) {
final StringLimitType key = entry.getKey();
int counterKey = 1;
List<String> chars = entry.getValue();
int i;
if (password != null) {
i = charIntersectionCounter(entry.getValue(), password);
} else {
i = 0;
}
// If max is exceed then error unable to continue
if (key.getMaxOccurs() != null && i > key.getMaxOccurs()) {
OperationResult o = new OperationResult("Limitation check :" + key.getDescription());
o.recordFatalError("Exceeded maximal value for this limitation. " + i + ">" + key.getMaxOccurs());
op.addSubresult(o);
return null;
// if max is all ready reached or skip enabled for minimal skip
// counting
} else if (key.getMaxOccurs() != null && i == key.getMaxOccurs()) {
continue;
// other cases minimum is not reached
} else if ((key.getMinOccurs() == null || i >= key.getMinOccurs()) && !skipMatchedLims) {
continue;
}
for (String s : chars) {
if (null == password || !password.contains(s) || uniquenessReached) {
counter.put(s, counterKey);
}
}
// TODO this is suspicious
counterKey++;
}
// If need to remove disabled chars (already reached limitations)
if (password != null) {
for (Map.Entry<StringLimitType, List<String>> entry : lims.entrySet()) {
StringLimitType l = entry.getKey();
int i = charIntersectionCounter(entry.getValue(), password);
if (l.getMaxOccurs() != null && i > l.getMaxOccurs()) {
OperationResult o = new OperationResult("Limitation check :" + l.getDescription());
o.recordFatalError("Exceeded maximal value for this limitation. " + i + ">" + l.getMaxOccurs());
op.addSubresult(o);
return null;
} else if (l.getMaxOccurs() != null && i == l.getMaxOccurs()) {
// limitation matched remove all used chars
LOGGER.trace("Skip " + l.getDescription());
for (String charToRemove : entry.getValue()) {
counter.remove(charToRemove);
}
}
}
}
// Transpose to better format
Map<Integer, List<String>> ret = new HashMap<>();
for (Map.Entry<String, Integer> entry : counter.entrySet()) {
// if not there initialize
ret.computeIfAbsent(entry.getValue(), k -> new ArrayList<>());
ret.get(entry.getValue()).add(entry.getKey());
}
return ret;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.
the class TestSanity method test400ImportFromResource.
@Test
public void test400ImportFromResource() throws Exception {
final String TEST_NAME = "test400ImportFromResource";
TestUtil.displayTestTile(TEST_NAME);
// GIVEN
checkAllShadows();
assertNoRepoCache();
OperationResult result = new OperationResult(TestSanity.class.getName() + "." + TEST_NAME);
// Make sure Mr. Gibbs has "l" attribute set to the same value as an outbound expression is setting
ChangeRecordEntry entry = openDJController.executeLdifChange(LDIF_GIBBS_MODIFY_FILE);
display("Entry from LDIF", entry);
// Let's add an entry with multiple uids.
Entry addEntry = openDJController.addEntryFromLdifFile(LDIF_HERMAN_FILENAME);
display("Entry from LDIF", addEntry);
// WHEN
TestUtil.displayWhen(TEST_NAME);
TaskType taskType = modelWeb.importFromResource(RESOURCE_OPENDJ_OID, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS);
// THEN
TestUtil.displayThen(TEST_NAME);
assertNoRepoCache();
displayJaxb("importFromResource result", taskType.getResult(), SchemaConstants.C_RESULT);
AssertJUnit.assertEquals("importFromResource has failed", OperationResultStatusType.IN_PROGRESS, taskType.getResult().getStatus());
// Convert the returned TaskType to a more usable Task
Task task = taskManager.createTaskInstance(taskType.asPrismObject(), result);
AssertJUnit.assertNotNull(task);
assertNotNull(task.getOid());
AssertJUnit.assertTrue(task.isAsynchronous());
AssertJUnit.assertEquals(TaskExecutionStatus.RUNNABLE, task.getExecutionStatus());
// AssertJUnit.assertEquals(TaskExclusivityStatus.CLAIMED, task.getExclusivityStatus());
display("Import task after launch", task);
PrismObject<TaskType> tObject = repositoryService.getObject(TaskType.class, task.getOid(), null, result);
TaskType taskAfter = tObject.asObjectable();
display("Import task in repo after launch", taskAfter);
result.computeStatus();
TestUtil.assertSuccess("getObject has failed", result);
final String taskOid = task.getOid();
waitFor("Waiting for import to complete", new Checker() {
@Override
public boolean check() throws CommonException {
Holder<OperationResultType> resultHolder = new Holder<OperationResultType>();
Holder<ObjectType> objectHolder = new Holder<ObjectType>();
OperationResult opResult = new OperationResult("import check");
assertNoRepoCache();
SelectorQualifiedGetOptionsType options = new SelectorQualifiedGetOptionsType();
try {
modelWeb.getObject(ObjectTypes.TASK.getTypeQName(), taskOid, options, objectHolder, resultHolder);
} catch (FaultMessage faultMessage) {
throw new SystemException(faultMessage);
}
assertNoRepoCache();
// display("getObject result (wait loop)",resultHolder.value);
TestUtil.assertSuccess("getObject has failed", resultHolder.value);
Task task = taskManager.createTaskInstance((PrismObject<TaskType>) objectHolder.value.asPrismObject(), opResult);
System.out.println(new Date() + ": Import task status: " + task.getExecutionStatus() + ", progress: " + task.getProgress());
if (task.getExecutionStatus() == TaskExecutionStatus.CLOSED) {
// Task closed, wait finished
return true;
}
// IntegrationTestTools.display("Task result while waiting: ", task.getResult());
return false;
}
@Override
public void timeout() {
// No reaction, the test will fail right after return from this
}
}, 180000);
// wait a second until the task will be definitely saved
Thread.sleep(1000);
//### Check task state after the task is finished ###
Holder<ObjectType> objectHolder = new Holder<ObjectType>();
Holder<OperationResultType> resultHolder = new Holder<OperationResultType>();
SelectorQualifiedGetOptionsType options = new SelectorQualifiedGetOptionsType();
assertNoRepoCache();
modelWeb.getObject(ObjectTypes.TASK.getTypeQName(), task.getOid(), options, objectHolder, resultHolder);
assertNoRepoCache();
TestUtil.assertSuccess("getObject has failed", resultHolder.value);
task = taskManager.createTaskInstance((PrismObject<TaskType>) objectHolder.value.asPrismObject(), result);
display("Import task after finish (fetched from model)", task);
AssertJUnit.assertEquals(TaskExecutionStatus.CLOSED, task.getExecutionStatus());
assertNotNull("Null lastRunStartTimestamp in " + task, task.getLastRunStartTimestamp());
assertNotNull("Null lastRunFinishTimestamp in " + task, task.getLastRunFinishTimestamp());
long importDuration = task.getLastRunFinishTimestamp() - task.getLastRunStartTimestamp();
double usersPerSec = (task.getProgress() * 1000) / importDuration;
display("Imported " + task.getProgress() + " users in " + importDuration + " milliseconds (" + usersPerSec + " users/sec)");
OperationResult taskResult = task.getResult();
AssertJUnit.assertNotNull("Task has no result", taskResult);
TestUtil.assertSuccess("Import task result is not success", taskResult);
AssertJUnit.assertTrue("Task failed", taskResult.isSuccess());
AssertJUnit.assertTrue("No progress", task.getProgress() > 0);
//### Check if the import created users and shadows ###
// Listing of shadows is not supported by the provisioning. So we need
// to look directly into repository
List<PrismObject<ShadowType>> sobjects = repositoryService.searchObjects(ShadowType.class, null, null, result);
result.computeStatus();
TestUtil.assertSuccess("listObjects has failed", result);
AssertJUnit.assertFalse("No shadows created", sobjects.isEmpty());
for (PrismObject<ShadowType> aObject : sobjects) {
ShadowType shadow = aObject.asObjectable();
display("Shadow object after import (repo)", shadow);
// This would be really strange ;-)
assertNotEmpty("No OID in shadow", shadow.getOid());
assertNotEmpty("No name in shadow", shadow.getName());
AssertJUnit.assertNotNull("No objectclass in shadow", shadow.getObjectClass());
AssertJUnit.assertNotNull("Null attributes in shadow", shadow.getAttributes());
String resourceOid = shadow.getResourceRef().getOid();
if (resourceOid.equals(RESOURCE_OPENDJ_OID)) {
assertAttributeNotNull("No identifier in shadow", shadow, getOpenDjPrimaryIdentifierQName());
} else {
assertAttributeNotNull("No UID in shadow", shadow, SchemaConstants.ICFS_UID);
}
}
Holder<ObjectListType> listHolder = new Holder<>();
assertNoRepoCache();
modelWeb.searchObjects(ObjectTypes.USER.getTypeQName(), null, null, listHolder, resultHolder);
assertNoRepoCache();
ObjectListType uobjects = listHolder.value;
TestUtil.assertSuccess("listObjects has failed", resultHolder.value);
AssertJUnit.assertFalse("No users created", uobjects.getObject().isEmpty());
// TODO: use another account, not guybrush
display("Users after import " + uobjects.getObject().size());
for (ObjectType oo : uobjects.getObject()) {
UserType user = (UserType) oo;
if (SystemObjectsType.USER_ADMINISTRATOR.value().equals(user.getOid())) {
//skip administrator check
continue;
}
display("User after import (repo)", user);
// This would be
assertNotEmpty("No OID in user", user.getOid());
// really
// strange ;-)
assertNotEmpty("No name in user", user.getName());
assertNotNull("No fullName in user", user.getFullName());
assertNotEmpty("No fullName in user", user.getFullName().getOrig());
assertNotEmpty("No familyName in user", user.getFamilyName().getOrig());
if (user.getName().getOrig().equals(USER_GUYBRUSH_USERNAME)) {
// skip the rest of checks for guybrush, he does not have LDAP account now
continue;
}
assertTrue("User " + user.getName() + " is disabled (" + user.getActivation().getAdministrativeStatus() + ")", user.getActivation() == null || user.getActivation().getAdministrativeStatus() == ActivationStatusType.ENABLED);
List<ObjectReferenceType> accountRefs = user.getLinkRef();
AssertJUnit.assertEquals("Wrong accountRef for user " + user.getName(), 1, accountRefs.size());
ObjectReferenceType accountRef = accountRefs.get(0);
boolean found = false;
for (PrismObject<ShadowType> aObject : sobjects) {
ShadowType acc = aObject.asObjectable();
if (accountRef.getOid().equals(acc.getOid())) {
found = true;
break;
}
}
if (!found) {
AssertJUnit.fail("accountRef does not point to existing account " + accountRef.getOid());
}
PrismObject<ShadowType> aObject = modelService.getObject(ShadowType.class, accountRef.getOid(), null, task, result);
ShadowType account = aObject.asObjectable();
display("Account after import ", account);
String attributeValueL = ShadowUtil.getMultiStringAttributeValueAsSingle(account, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "l"));
// assertEquals("Unexcpected value of l", "middle of nowhere", attributeValueL);
assertEquals("Unexcpected value of l", getUserLocality(user), attributeValueL);
}
// This also includes "idm" user imported from LDAP. Later we need to ignore that one.
assertEquals("Wrong number of users after import", 10, uobjects.getObject().size());
checkAllShadows();
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.
the class ConnectorInstanceConnIdImpl method parseResourceSchema.
private void parseResourceSchema(org.identityconnectors.framework.common.objects.Schema icfSchema, List<QName> generateObjectClasses) {
AttributeInfo passwordAttributeInfo = null;
AttributeInfo enableAttributeInfo = null;
AttributeInfo enableDateAttributeInfo = null;
AttributeInfo disableDateAttributeInfo = null;
AttributeInfo lockoutAttributeInfo = null;
AttributeInfo auxiliaryObjectClasseAttributeInfo = null;
// New instance of midPoint schema object
setResourceSchema(new ResourceSchemaImpl(getSchemaNamespace(), prismContext));
if (legacySchema == null) {
legacySchema = detectLegacySchema(icfSchema);
}
LOGGER.trace("Converting resource schema (legacy mode: {})", legacySchema);
Set<ObjectClassInfo> objectClassInfoSet = icfSchema.getObjectClassInfo();
// Let's convert every objectclass in the ICF schema ...
for (ObjectClassInfo objectClassInfo : objectClassInfoSet) {
// "Flat" ICF object class names needs to be mapped to QNames
QName objectClassXsdName = connIdNameMapper.objectClassToQname(new ObjectClass(objectClassInfo.getType()), getSchemaNamespace(), legacySchema);
if (!shouldBeGenerated(generateObjectClasses, objectClassXsdName)) {
LOGGER.trace("Skipping object class {} ({})", objectClassInfo.getType(), objectClassXsdName);
continue;
}
LOGGER.trace("Convering object class {} ({})", objectClassInfo.getType(), objectClassXsdName);
// ResourceObjectDefinition is a midPpoint way how to represent an
// object class.
// The important thing here is the last "type" parameter
// (objectClassXsdName). The rest is more-or-less cosmetics.
ObjectClassComplexTypeDefinition ocDef = ((ResourceSchemaImpl) resourceSchema).createObjectClassDefinition(objectClassXsdName);
// objectclass. So mark it appropriately.
if (ObjectClass.ACCOUNT_NAME.equals(objectClassInfo.getType())) {
((ObjectClassComplexTypeDefinitionImpl) ocDef).setKind(ShadowKindType.ACCOUNT);
((ObjectClassComplexTypeDefinitionImpl) ocDef).setDefaultInAKind(true);
}
ResourceAttributeDefinition<String> uidDefinition = null;
ResourceAttributeDefinition<String> nameDefinition = null;
boolean hasUidDefinition = false;
int displayOrder = ConnectorFactoryConnIdImpl.ATTR_DISPLAY_ORDER_START;
// Let's iterate over all attributes in this object class ...
Set<AttributeInfo> attributeInfoSet = objectClassInfo.getAttributeInfo();
for (AttributeInfo attributeInfo : attributeInfoSet) {
String icfName = attributeInfo.getName();
if (OperationalAttributes.PASSWORD_NAME.equals(icfName)) {
// This attribute will not go into the schema
// instead a "password" capability is used
passwordAttributeInfo = attributeInfo;
// Skip this attribute, capability is sufficient
continue;
}
if (OperationalAttributes.ENABLE_NAME.equals(icfName)) {
enableAttributeInfo = attributeInfo;
// Skip this attribute, capability is sufficient
continue;
}
if (OperationalAttributes.ENABLE_DATE_NAME.equals(icfName)) {
enableDateAttributeInfo = attributeInfo;
// Skip this attribute, capability is sufficient
continue;
}
if (OperationalAttributes.DISABLE_DATE_NAME.equals(icfName)) {
disableDateAttributeInfo = attributeInfo;
// Skip this attribute, capability is sufficient
continue;
}
if (OperationalAttributes.LOCK_OUT_NAME.equals(icfName)) {
lockoutAttributeInfo = attributeInfo;
// Skip this attribute, capability is sufficient
continue;
}
if (PredefinedAttributes.AUXILIARY_OBJECT_CLASS_NAME.equals(icfName)) {
auxiliaryObjectClasseAttributeInfo = attributeInfo;
// Skip this attribute, capability is sufficient
continue;
}
String processedAttributeName = icfName;
if ((Name.NAME.equals(icfName) || Uid.NAME.equals(icfName)) && attributeInfo.getNativeName() != null) {
processedAttributeName = attributeInfo.getNativeName();
}
QName attrXsdName = connIdNameMapper.convertAttributeNameToQName(processedAttributeName, ocDef);
QName attrXsdType = ConnIdUtil.icfTypeToXsdType(attributeInfo.getType(), false);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Attr conversion ICF: {}({}) -> XSD: {}({})", icfName, attributeInfo.getType().getSimpleName(), PrettyPrinter.prettyPrint(attrXsdName), PrettyPrinter.prettyPrint(attrXsdType));
}
// Create ResourceObjectAttributeDefinition, which is midPoint
// way how to express attribute schema.
ResourceAttributeDefinitionImpl attrDef = new ResourceAttributeDefinitionImpl(attrXsdName, attrXsdType, prismContext);
attrDef.setMatchingRuleQName(icfAttributeInfoToMatchingRule(attributeInfo));
if (Name.NAME.equals(icfName)) {
nameDefinition = attrDef;
if (uidDefinition != null && attrXsdName.equals(uidDefinition.getName())) {
attrDef.setDisplayOrder(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_ORDER);
uidDefinition = attrDef;
hasUidDefinition = true;
} else {
if (attributeInfo.getNativeName() == null) {
// Set a better display name for __NAME__. The "name" is s very
// overloaded term, so let's try to make things
// a bit clearer
attrDef.setDisplayName(ConnectorFactoryConnIdImpl.ICFS_NAME_DISPLAY_NAME);
}
attrDef.setDisplayOrder(ConnectorFactoryConnIdImpl.ICFS_NAME_DISPLAY_ORDER);
}
} else if (Uid.NAME.equals(icfName)) {
// UID can be the same as other attribute
ResourceAttributeDefinition existingDefinition = ocDef.findAttributeDefinition(attrXsdName);
if (existingDefinition != null) {
hasUidDefinition = true;
((ResourceAttributeDefinitionImpl) existingDefinition).setDisplayOrder(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_ORDER);
uidDefinition = existingDefinition;
continue;
} else {
uidDefinition = attrDef;
if (attributeInfo.getNativeName() == null) {
attrDef.setDisplayName(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_NAME);
}
attrDef.setDisplayOrder(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_ORDER);
}
} else {
// Check conflict with UID definition
if (uidDefinition != null && attrXsdName.equals(uidDefinition.getName())) {
attrDef.setDisplayOrder(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_ORDER);
uidDefinition = attrDef;
hasUidDefinition = true;
} else {
attrDef.setDisplayOrder(displayOrder);
displayOrder += ConnectorFactoryConnIdImpl.ATTR_DISPLAY_ORDER_INCREMENT;
}
}
attrDef.setNativeAttributeName(attributeInfo.getNativeName());
attrDef.setFrameworkAttributeName(icfName);
// Now we are going to process flags such as optional and
// multi-valued
Set<Flags> flagsSet = attributeInfo.getFlags();
// System.out.println(flagsSet);
attrDef.setMinOccurs(0);
attrDef.setMaxOccurs(1);
boolean canCreate = true;
boolean canUpdate = true;
boolean canRead = true;
for (Flags flags : flagsSet) {
if (flags == Flags.REQUIRED) {
attrDef.setMinOccurs(1);
}
if (flags == Flags.MULTIVALUED) {
attrDef.setMaxOccurs(-1);
}
if (flags == Flags.NOT_CREATABLE) {
canCreate = false;
}
if (flags == Flags.NOT_READABLE) {
canRead = false;
}
if (flags == Flags.NOT_UPDATEABLE) {
canUpdate = false;
}
if (flags == Flags.NOT_RETURNED_BY_DEFAULT) {
attrDef.setReturnedByDefault(false);
}
}
attrDef.setCanAdd(canCreate);
attrDef.setCanModify(canUpdate);
attrDef.setCanRead(canRead);
if (!Uid.NAME.equals(icfName)) {
((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 ResourceAttributeDefinitionImpl<>(SchemaConstants.ICFS_UID, DOMUtil.XSD_STRING, prismContext);
// DO NOT make it mandatory. It must not be present on create hence it cannot be mandatory.
((ResourceAttributeDefinitionImpl) uidDefinition).setMinOccurs(0);
((ResourceAttributeDefinitionImpl) uidDefinition).setMaxOccurs(1);
// Make it read-only
((ResourceAttributeDefinitionImpl) uidDefinition).setReadOnly();
// Set a default display name
((ResourceAttributeDefinitionImpl) uidDefinition).setDisplayName(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_NAME);
((ResourceAttributeDefinitionImpl) uidDefinition).setDisplayOrder(ConnectorFactoryConnIdImpl.ICFS_UID_DISPLAY_ORDER);
// Uid is a primary identifier of every object (this is the ICF way)
}
if (!hasUidDefinition) {
((ObjectClassComplexTypeDefinitionImpl) ocDef).add(uidDefinition);
}
((ObjectClassComplexTypeDefinitionImpl) ocDef).addPrimaryIdentifier(uidDefinition);
if (uidDefinition != nameDefinition) {
((ObjectClassComplexTypeDefinitionImpl) ocDef).addSecondaryIdentifier(nameDefinition);
}
// Add schema annotations
((ObjectClassComplexTypeDefinitionImpl) ocDef).setNativeObjectClass(objectClassInfo.getType());
((ObjectClassComplexTypeDefinitionImpl) ocDef).setDisplayNameAttribute(nameDefinition.getName());
((ObjectClassComplexTypeDefinitionImpl) ocDef).setNamingAttribute(nameDefinition.getName());
((ObjectClassComplexTypeDefinitionImpl) ocDef).setAuxiliary(objectClassInfo.isAuxiliary());
}
// This is the default for all resources.
// (Currently there is no way how to obtain it from the connector.)
// It can be disabled manually.
AddRemoveAttributeValuesCapabilityType addRemove = new AddRemoveAttributeValuesCapabilityType();
capabilities.add(CAPABILITY_OBJECT_FACTORY.createAddRemoveAttributeValues(addRemove));
ActivationCapabilityType capAct = null;
if (enableAttributeInfo != null) {
if (capAct == null) {
capAct = new ActivationCapabilityType();
}
ActivationStatusCapabilityType capActStatus = new ActivationStatusCapabilityType();
capAct.setStatus(capActStatus);
if (!enableAttributeInfo.isReturnedByDefault()) {
capActStatus.setReturnedByDefault(false);
}
}
if (enableDateAttributeInfo != null) {
if (capAct == null) {
capAct = new ActivationCapabilityType();
}
ActivationValidityCapabilityType capValidFrom = new ActivationValidityCapabilityType();
capAct.setValidFrom(capValidFrom);
if (!enableDateAttributeInfo.isReturnedByDefault()) {
capValidFrom.setReturnedByDefault(false);
}
}
if (disableDateAttributeInfo != null) {
if (capAct == null) {
capAct = new ActivationCapabilityType();
}
ActivationValidityCapabilityType capValidTo = new ActivationValidityCapabilityType();
capAct.setValidTo(capValidTo);
if (!disableDateAttributeInfo.isReturnedByDefault()) {
capValidTo.setReturnedByDefault(false);
}
}
if (lockoutAttributeInfo != null) {
if (capAct == null) {
capAct = new ActivationCapabilityType();
}
ActivationLockoutStatusCapabilityType capActStatus = new ActivationLockoutStatusCapabilityType();
capAct.setLockoutStatus(capActStatus);
if (!lockoutAttributeInfo.isReturnedByDefault()) {
capActStatus.setReturnedByDefault(false);
}
}
if (capAct != null) {
capabilities.add(CAPABILITY_OBJECT_FACTORY.createActivation(capAct));
}
if (passwordAttributeInfo != null) {
CredentialsCapabilityType capCred = new CredentialsCapabilityType();
PasswordCapabilityType capPass = new PasswordCapabilityType();
if (!passwordAttributeInfo.isReturnedByDefault()) {
capPass.setReturnedByDefault(false);
}
if (passwordAttributeInfo.isReadable()) {
capPass.setReadable(true);
}
capCred.setPassword(capPass);
capabilities.add(CAPABILITY_OBJECT_FACTORY.createCredentials(capCred));
}
if (auxiliaryObjectClasseAttributeInfo != null) {
AuxiliaryObjectClassesCapabilityType capAux = new AuxiliaryObjectClassesCapabilityType();
capabilities.add(CAPABILITY_OBJECT_FACTORY.createAuxiliaryObjectClasses(capAux));
}
boolean canPageSize = false;
boolean canPageOffset = false;
boolean canSort = false;
for (OperationOptionInfo searchOption : icfSchema.getSupportedOptionsByOperation(SearchApiOp.class)) {
switch(searchOption.getName()) {
case OperationOptions.OP_PAGE_SIZE:
canPageSize = true;
break;
case OperationOptions.OP_PAGED_RESULTS_OFFSET:
canPageOffset = true;
break;
case OperationOptions.OP_SORT_KEYS:
canSort = true;
break;
case OperationOptions.OP_RETURN_DEFAULT_ATTRIBUTES:
supportsReturnDefaultAttributes = true;
break;
}
}
if (canPageSize || canPageOffset || canSort) {
PagedSearchCapabilityType capPage = new PagedSearchCapabilityType();
capabilities.add(CAPABILITY_OBJECT_FACTORY.createPagedSearch(capPage));
}
}
Aggregations