private <F extends ObjectType> void recordValidityDelta( LensFocusContext<F> focusContext, TimeIntervalStatusType validityStatusNew, XMLGregorianCalendar now) throws SchemaException { PrismContainerDefinition<ActivationType> activationDefinition = getActivationDefinition(); PrismPropertyDefinition<TimeIntervalStatusType> validityStatusDef = activationDefinition.findPropertyDefinition(ActivationType.F_VALIDITY_STATUS); PropertyDelta<TimeIntervalStatusType> validityStatusDelta = validityStatusDef.createEmptyDelta( new ItemPath(UserType.F_ACTIVATION, ActivationType.F_VALIDITY_STATUS)); if (validityStatusNew == null) { validityStatusDelta.setValueToReplace(); } else { validityStatusDelta.setValueToReplace( new PrismPropertyValue<TimeIntervalStatusType>( validityStatusNew, OriginType.USER_POLICY, null)); } focusContext.swallowToProjectionWaveSecondaryDelta(validityStatusDelta); PrismPropertyDefinition<XMLGregorianCalendar> validityChangeTimestampDef = activationDefinition.findPropertyDefinition(ActivationType.F_VALIDITY_CHANGE_TIMESTAMP); PropertyDelta<XMLGregorianCalendar> validityChangeTimestampDelta = validityChangeTimestampDef.createEmptyDelta( new ItemPath(UserType.F_ACTIVATION, ActivationType.F_VALIDITY_CHANGE_TIMESTAMP)); validityChangeTimestampDelta.setValueToReplace( new PrismPropertyValue<XMLGregorianCalendar>(now, OriginType.USER_POLICY, null)); focusContext.swallowToProjectionWaveSecondaryDelta(validityChangeTimestampDelta); }
public <P extends PrismProperty> P instantiateEmptyProperty() { PrismPropertyDefinition propertyDefinition = getPropertyDefinition(); if (propertyDefinition == null) { throw new IllegalArgumentException( "Cannot instantiate property " + getElementName() + " from delta " + this + ": no definition"); } return (P) propertyDefinition.instantiate(getElementName()); }
/** * @return Returns proper {@link PropertyModel} based on different types like {@link * com.evolveum.midpoint.prism.polystring.PolyString} or {@link * com.evolveum.midpoint.xml.ns._public.common.common_2a.ProtectedStringType} */ private IModel createValueModel() { FieldToken token = model.getObject().getField().getToken(); PrismPropertyDefinition definition = token.getDefinition(); final String baseExpression = "value.value"; // pointing to prism property real value if (ProtectedStringType.COMPLEX_TYPE.equals(definition.getTypeName())) { return new PropertyModel<String>(model, baseExpression + ".clearValue"); } else if (SchemaConstants.T_POLY_STRING_TYPE.equals(definition.getTypeName())) { return new PropertyModel<String>(model, baseExpression + ".orig"); } return new PropertyModel(model, baseExpression); }
private boolean isEnum(PrismProperty property) { PrismPropertyDefinition definition = property.getDefinition(); //// Object realValue = property.getAnyRealValue(); if (definition == null) { return property.getValueClass().isEnum(); } // // QName defName = definition.getName(); // Class clazz = // definition.getPrismContext().getSchemaRegistry().determineCompileTimeClass(defName); // // return ((clazz != null && clazz.isEnum()) || // ActivationType.F_ADMINISTRATIVE_STATUS.equals(definition.getName()) // || ActivationType.F_LOCKOUT_STATUS.equals(definition.getName()) || ); return (definition.getAllowedValues() != null && definition.getAllowedValues().size() > 0); }
/** * This methods check if we want to show property in form (e.g. failedLogins, fetchResult, * lastFailedLoginTimestamp must be invisible) * * @return * @deprecated will be implemented through annotations in schema */ @Deprecated private boolean skipProperty(PrismPropertyDefinition def) { final List<QName> names = new ArrayList<QName>(); names.add(PasswordType.F_FAILED_LOGINS); names.add(PasswordType.F_LAST_FAILED_LOGIN); names.add(PasswordType.F_LAST_SUCCESSFUL_LOGIN); names.add(PasswordType.F_PREVIOUS_SUCCESSFUL_LOGIN); names.add(ObjectType.F_FETCH_RESULT); // activation names.add(ActivationType.F_EFFECTIVE_STATUS); names.add(ActivationType.F_VALIDITY_STATUS); // user names.add(UserType.F_RESULT); // org and roles names.add(OrgType.F_APPROVAL_PROCESS); names.add(OrgType.F_APPROVER_EXPRESSION); names.add(OrgType.F_AUTOMATICALLY_APPROVED); names.add(OrgType.F_CONDITION); for (QName name : names) { if (name.equals(def.getName())) { return true; } } return false; }
// region Serializing properties - specific functionality private <T> XNode serializePropertyValue( PrismPropertyValue<T> value, PrismPropertyDefinition<T> definition) throws SchemaException { QName typeQName = definition.getTypeName(); T realValue = value.getValue(); if (realValue instanceof PolyString) { return serializePolyString((PolyString) realValue); } else if (beanConverter.canProcess(typeQName)) { XNode xnode = beanConverter.marshall(realValue); if (realValue instanceof ProtectedDataType<?> && definition.isDynamic()) { // why is this? xnode.setExplicitTypeDeclaration(true); xnode.setTypeQName(definition.getTypeName()); } return xnode; } else { // primitive value return createPrimitiveXNode(realValue, typeQName); } }
@Override public void setObject(Object object) { try { PrismProperty property = getPrismObject().findOrCreateProperty(path); if (object != null) { PrismPropertyDefinition def = property.getDefinition(); if (PolyString.class.equals(def.getTypeClass())) { object = new PolyString((String) object); } property.setValue(new PrismPropertyValue(object, OriginType.USER_ACTION, null)); } else { PrismContainerValue parent = (PrismContainerValue) property.getParent(); parent.remove(property); } } catch (Exception ex) { LoggingUtils.logException(LOGGER, "Couldn't update prism property model", ex); } }
private boolean hasCapability(PrismPropertyDefinition def) { ShadowType shadow = (ShadowType) getObject().getObject().asObjectable(); ActivationCapabilityType cap = ResourceTypeUtil.getEffectiveCapability( shadow.getResource(), ActivationCapabilityType.class); if (ActivationType.F_VALID_FROM.equals(def.getName()) && cap.getValidFrom() == null) { return false; } if (ActivationType.F_VALID_TO.equals(def.getName()) && cap.getValidTo() == null) { return false; } if (ActivationType.F_ADMINISTRATIVE_STATUS.equals(def.getName()) && cap.getStatus() == null) { return false; } return true; }
private <F extends ObjectType> void recordEffectiveStatusDelta( LensFocusContext<F> focusContext, ActivationStatusType effectiveStatusNew, XMLGregorianCalendar now) throws SchemaException { PrismContainerDefinition<ActivationType> activationDefinition = getActivationDefinition(); PrismPropertyDefinition<ActivationStatusType> effectiveStatusDef = activationDefinition.findPropertyDefinition(ActivationType.F_EFFECTIVE_STATUS); PropertyDelta<ActivationStatusType> effectiveStatusDelta = effectiveStatusDef.createEmptyDelta( new ItemPath(UserType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS)); effectiveStatusDelta.setValueToReplace( new PrismPropertyValue<ActivationStatusType>( effectiveStatusNew, OriginType.USER_POLICY, null)); focusContext.swallowToProjectionWaveSecondaryDelta(effectiveStatusDelta); PropertyDelta<XMLGregorianCalendar> timestampDelta = LensUtil.createActivationTimestampDelta( effectiveStatusNew, now, activationDefinition, OriginType.USER_POLICY); focusContext.swallowToProjectionWaveSecondaryDelta(timestampDelta); }
public static <T> PropertyDelta<T> createModificationDeleteProperty( ItemPath propertyPath, PrismPropertyDefinition propertyDefinition, T... propertyValues) { PropertyDelta<T> propertyDelta = new PropertyDelta<T>( propertyPath, propertyDefinition, propertyDefinition.getPrismContext()); // hoping the prismContext is there Collection<PrismPropertyValue<T>> pValues = new ArrayList<PrismPropertyValue<T>>(propertyValues.length); for (T val : propertyValues) { pValues.add(new PrismPropertyValue<T>(val)); } propertyDelta.addValuesToDelete(pValues); return propertyDelta; }
public static <T> String serializeValue( T value, PrismPropertyDefinition def, QName itemName, PrismContext prismContext, String langXml) throws SchemaException { // System.out.println("value serialization"); if (value == null) { return null; } XNodeSerializer serializer = prismContext.getXnodeProcessor().createSerializer(); if (value instanceof List) { List<T> values = (List<T>) value; if (values.isEmpty()) { return null; } if (def instanceof PrismPropertyDefinition) { PrismProperty prop = (PrismProperty) def.instantiate(); for (T val : values) { PrismPropertyValue<T> pValue = new PrismPropertyValue<T>(val); prop.add(pValue); } XNode node = serializer.serializeItem(prop); if (node instanceof ListXNode) { ListXNode xList = (ListXNode) node; MapXNode xmap = new MapXNode(); xmap.put(def.getName(), xList); String s = prismContext.getParserDom().serializeToString(xmap, def.getName()); // System.out.println("serialized: " + s); return s; } String s = prismContext.getParserDom().serializeToString(node, def.getName()); // System.out.println("serialized: " + s); return s; } } PrismValue pVal = null; if (value instanceof Containerable) { pVal = ((Containerable) value).asPrismContainerValue(); } else if (value instanceof Referencable) { pVal = ((Referencable) value).asReferenceValue(); } else { PrismProperty pp = def.instantiate(); pVal = new PrismPropertyValue<T>(value); pp.add(pVal); XNode xnode = serializer.serializeItemValue(pVal, def); if (xnode == null) { throw new IllegalArgumentException("null node after serialization"); } MapXNode xmap = null; if (xnode instanceof RootXNode) { XNode sub = ((RootXNode) xnode).getSubnode(); if (!(sub instanceof MapXNode)) { throw new IllegalArgumentException("not uspported yet"); } xmap = (MapXNode) sub; } else if (xnode instanceof MapXNode) { xmap = (MapXNode) xnode; } else if (xnode instanceof PrimitiveXNode) { String s = ((PrimitiveXNode) xnode).getStringValue(); return s; // } else { throw new IllegalStateException("hmmm"); } XNode node = xmap.get(itemName); String s = prismContext.getParserDom().serializeToString(node, itemName); } XNode node = serializer.serializeItemValue(pVal, def); String s = prismContext.getParserDom().serializeToString(node, itemName); // System.out.println("serialized: " + s); return s; // throw new UnsupportedOperationException("need to be implemented"); }
private <F extends FocusType> void processFocusFocus( LensContext<F> context, String activityDescription, XMLGregorianCalendar now, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, PolicyViolationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { LensFocusContext<F> focusContext = context.getFocusContext(); ObjectTemplateType objectTemplate = context.getFocusTemplate(); boolean resetOnRename = true; // This is fixed now. TODO: make it configurable int maxIterations = 0; IterationSpecificationType iterationSpecificationType = null; if (objectTemplate != null) { iterationSpecificationType = objectTemplate.getIteration(); maxIterations = LensUtil.determineMaxIterations(iterationSpecificationType); } int iteration = focusContext.getIteration(); String iterationToken = focusContext.getIterationToken(); boolean wasResetIterationCounter = false; PrismObject<F> focusCurrent = focusContext.getObjectCurrent(); if (focusCurrent != null && iterationToken == null) { Integer focusIteration = focusCurrent.asObjectable().getIteration(); if (focusIteration != null) { iteration = focusIteration; } iterationToken = focusCurrent.asObjectable().getIterationToken(); } while (true) { ObjectTypeTemplateType objectPolicyConfigurationType = focusContext.getObjectPolicyConfigurationType(); if (objectPolicyConfigurationType != null && BooleanUtils.isTrue(objectPolicyConfigurationType.isOidNameBoundMode())) { // Generate the name now - unless it is already present PrismObject<F> focusNew = focusContext.getObjectNew(); if (focusNew != null) { PolyStringType focusNewName = focusNew.asObjectable().getName(); if (focusNewName == null) { String newName = focusNew.getOid(); if (newName == null) { newName = OidUtil.generateOid(); } LOGGER.trace("Generating new name (bound to OID): {}", newName); PrismObjectDefinition<F> focusDefinition = focusContext.getObjectDefinition(); PrismPropertyDefinition<PolyString> focusNameDef = focusDefinition.findPropertyDefinition(FocusType.F_NAME); PropertyDelta<PolyString> nameDelta = focusNameDef.createEmptyDelta(new ItemPath(FocusType.F_NAME)); nameDelta.setValueToReplace( new PrismPropertyValue<PolyString>( new PolyString(newName), OriginType.USER_POLICY, null)); focusContext.swallowToSecondaryDelta(nameDelta); focusContext.recompute(); } } } ExpressionVariables variables = Utils.getDefaultExpressionVariables( focusContext.getObjectNew(), null, null, null, context.getSystemConfiguration()); if (iterationToken == null) { iterationToken = LensUtil.formatIterationToken( context, focusContext, iterationSpecificationType, iteration, expressionFactory, variables, task, result); } // We have to remember the token and iteration in the context. // The context can be recomputed several times. But we always want // to use the same iterationToken if possible. If there is a random // part in the iterationToken expression that we need to avoid recomputing // the token otherwise the value can change all the time (even for the same inputs). // Storing the token in the secondary delta is not enough because secondary deltas can be // dropped // if the context is re-projected. focusContext.setIteration(iteration); focusContext.setIterationToken(iterationToken); LOGGER.trace( "Focus {} processing, iteration {}, token '{}'", new Object[] {focusContext.getHumanReadableName(), iteration, iterationToken}); String conflictMessage; if (!LensUtil.evaluateIterationCondition( context, focusContext, iterationSpecificationType, iteration, iterationToken, true, expressionFactory, variables, task, result)) { conflictMessage = "pre-iteration condition was false"; LOGGER.debug( "Skipping iteration {}, token '{}' for {} because the pre-iteration condition was false", new Object[] {iteration, iterationToken, focusContext.getHumanReadableName()}); } else { // INBOUND if (consistencyChecks) context.checkConsistence(); // Loop through the account changes, apply inbound expressions inboundProcessor.processInbound(context, now, task, result); if (consistencyChecks) context.checkConsistence(); context.recomputeFocus(); LensUtil.traceContext(LOGGER, activityDescription, "inbound", false, context, false); if (consistencyChecks) context.checkConsistence(); // ACTIVATION processActivation(context, now, result); // OBJECT TEMPLATE (before assignments) objectTemplateProcessor.processTemplate( context, ObjectTemplateMappingEvaluationPhaseType.BEFORE_ASSIGNMENTS, now, task, result); // ASSIGNMENTS assignmentProcessor.processAssignmentsProjections(context, now, task, result); assignmentProcessor.processOrgAssignments(context, result); context.recompute(); assignmentProcessor.checkForAssignmentConflicts(context, result); // OBJECT TEMPLATE (after assignments) objectTemplateProcessor.processTemplate( context, ObjectTemplateMappingEvaluationPhaseType.AFTER_ASSIGNMENTS, now, task, result); context.recompute(); // PASSWORD POLICY passwordPolicyProcessor.processPasswordPolicy(focusContext, context, result); // Processing done, check for success if (resetOnRename && !wasResetIterationCounter && willResetIterationCounter(focusContext)) { // Make sure this happens only the very first time during the first recompute. // Otherwise it will always change the token (especially if the token expression has a // random part) // hence the focusContext.getIterationToken() == null wasResetIterationCounter = true; if (iteration != 0) { iteration = 0; iterationToken = null; LOGGER.trace("Resetting iteration counter and token because rename was detected"); cleanupContext(focusContext); continue; } } PrismObject<F> previewObjectNew = focusContext.getObjectNew(); if (previewObjectNew == null) { // this must be delete } else { // Explicitly check for name. The checker would check for this also. But checking it here // will produce better error message PolyStringType objectName = previewObjectNew.asObjectable().getName(); if (objectName == null || objectName.getOrig().isEmpty()) { throw new SchemaException( "No name in new object " + objectName + " as produced by template " + objectTemplate + " in iteration " + iteration + ", we cannot process an object without a name"); } } // Check if iteration constraints are OK FocusConstraintsChecker<F> checker = new FocusConstraintsChecker<>(); checker.setPrismContext(prismContext); checker.setContext(context); checker.setRepositoryService(cacheRepositoryService); checker.check(previewObjectNew, result); if (checker.isSatisfiesConstraints()) { LOGGER.trace( "Current focus satisfies uniqueness constraints. Iteration {}, token '{}'", iteration, iterationToken); if (LensUtil.evaluateIterationCondition( context, focusContext, iterationSpecificationType, iteration, iterationToken, false, expressionFactory, variables, task, result)) { // stop the iterations break; } else { conflictMessage = "post-iteration condition was false"; LOGGER.debug( "Skipping iteration {}, token '{}' for {} because the post-iteration condition was false", new Object[] {iteration, iterationToken, focusContext.getHumanReadableName()}); } } else { LOGGER.trace( "Current focus does not satisfy constraints. Conflicting object: {}; iteration={}, maxIterations={}", new Object[] {checker.getConflictingObject(), iteration, maxIterations}); conflictMessage = checker.getMessages(); } if (!wasResetIterationCounter) { wasResetIterationCounter = true; if (iteration != 0) { iterationToken = null; iteration = 0; LOGGER.trace("Resetting iteration counter and token after conflict"); cleanupContext(focusContext); continue; } } } // Next iteration iteration++; iterationToken = null; if (iteration > maxIterations) { StringBuilder sb = new StringBuilder(); if (iteration == 1) { sb.append("Error processing "); } else { sb.append("Too many iterations (" + iteration + ") for "); } sb.append(focusContext.getHumanReadableName()); if (iteration == 1) { sb.append(": constraint violation: "); } else { sb.append(": cannot determine values that satisfy constraints: "); } if (conflictMessage != null) { sb.append(conflictMessage); } throw new ObjectAlreadyExistsException(sb.toString()); } cleanupContext(focusContext); } addIterationTokenDeltas(focusContext, iteration, iterationToken); if (consistencyChecks) context.checkConsistence(); }
// normally this method returns an InputPanel; // however, for some special readonly types (like ObjectDeltaType) it will return a Panel private Panel createTypedInputComponent(String id) { final Item item = model.getObject().getItem().getItem(); Panel panel = null; if (item instanceof PrismProperty) { final PrismProperty property = (PrismProperty) item; PrismPropertyDefinition definition = property.getDefinition(); QName valueType = definition.getTypeName(); final String baseExpression = "value.value"; // pointing to prism property real value ContainerWrapper containerWrapper = model.getObject().getItem().getContainer(); if (containerWrapper != null && containerWrapper.getPath() != null) { if (ShadowType.F_ASSOCIATION.getLocalPart().equals(containerWrapper.getPath().toString())) { return new TextDetailsPanel(id, new PropertyModel<String>(model, baseExpression)) { @Override public String createAssociationTooltip() { return createAssociationTooltipText(property); } }; } } // fixing MID-1230, will be improved with some kind of annotation or something like that // now it works only in description if (ObjectType.F_DESCRIPTION.equals(definition.getName())) { return new TextAreaPanel(id, new PropertyModel(model, baseExpression)); } // the same for requester and approver comments in workflows [mederly] - this is really ugly, // as it is specific to each approval form if (AssignmentCreationApprovalFormType.F_REQUESTER_COMMENT.equals(definition.getName()) || AssignmentCreationApprovalFormType.F_COMMENT.equals(definition.getName())) { return new TextAreaPanel(id, new PropertyModel(model, baseExpression)); } if (ActivationType.F_ADMINISTRATIVE_STATUS.equals(definition.getName())) { return WebMiscUtil.createEnumPanel( ActivationStatusType.class, id, new PropertyModel<ActivationStatusType>(model, baseExpression), this); } else if (ActivationType.F_LOCKOUT_STATUS.equals(definition.getName())) { return WebMiscUtil.createEnumPanel( LockoutStatusType.class, id, new PropertyModel<LockoutStatusType>(model, baseExpression), this); } else { // nothing to do } if (DOMUtil.XSD_DATETIME.equals(valueType)) { panel = new DatePanel(id, new PropertyModel<XMLGregorianCalendar>(model, baseExpression)); } else if (ProtectedStringType.COMPLEX_TYPE.equals(valueType)) { panel = new PasswordPanel( id, new PropertyModel<ProtectedStringType>(model, baseExpression), model.getObject().isReadonly()); } else if (DOMUtil.XSD_BOOLEAN.equals(valueType)) { panel = new TriStateComboPanel(id, new PropertyModel<Boolean>(model, baseExpression)); } else if (SchemaConstants.T_POLY_STRING_TYPE.equals(valueType)) { InputPanel inputPanel; PrismPropertyDefinition def = property.getDefinition(); if (def.getValueEnumerationRef() != null) { PrismReferenceValue valueEnumerationRef = def.getValueEnumerationRef(); String lookupTableUid = valueEnumerationRef.getOid(); Task task = pageBase.createSimpleTask("loadLookupTable"); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection( LookupTableType.F_ROW, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)); final PrismObject<LookupTableType> lookupTable = WebModelUtils.loadObject( LookupTableType.class, lookupTableUid, options, pageBase, task, result); inputPanel = new AutoCompleteTextPanel<String>( id, new LookupPropertyModel<String>( model, baseExpression + ".orig", lookupTable.asObjectable()), String.class) { @Override public Iterator<String> getIterator(String input) { return prepareAutoCompleteList(input, lookupTable).iterator(); } }; } else { inputPanel = new TextPanel<>( id, new PropertyModel<String>(model, baseExpression + ".orig"), String.class); } if (ObjectType.F_NAME.equals(def.getName()) || UserType.F_FULL_NAME.equals(def.getName())) { inputPanel.getBaseFormComponent().setRequired(true); } panel = inputPanel; } else if (DOMUtil.XSD_BASE64BINARY.equals(valueType)) { panel = new UploadDownloadPanel(id, model.getObject().isReadonly()) { @Override public InputStream getStream() { return new ByteArrayInputStream( (byte[]) ((PrismPropertyValue) model.getObject().getValue()).getValue()); // return super.getStream(); } @Override public void updateValue(byte[] file) { ((PrismPropertyValue) model.getObject().getValue()).setValue(file); } @Override public void uploadFilePerformed(AjaxRequestTarget target) { super.uploadFilePerformed(target); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } @Override public void removeFilePerformed(AjaxRequestTarget target) { super.removeFilePerformed(target); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } @Override public void uploadFileFailed(AjaxRequestTarget target) { super.uploadFileFailed(target); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); target.add(((PageBase) getPage()).getFeedbackPanel()); } }; } else if (ObjectDeltaType.COMPLEX_TYPE.equals(valueType)) { panel = new ModificationsPanel( id, new AbstractReadOnlyModel<DeltaDto>() { @Override public DeltaDto getObject() { if (model.getObject() == null || model.getObject().getValue() == null || ((PrismPropertyValue) model.getObject().getValue()).getValue() == null) { return null; } PrismContext prismContext = ((PageBase) getPage()).getPrismContext(); ObjectDeltaType objectDeltaType = (ObjectDeltaType) ((PrismPropertyValue) model.getObject().getValue()).getValue(); try { ObjectDelta delta = DeltaConvertor.createObjectDelta(objectDeltaType, prismContext); return new DeltaDto(delta); } catch (SchemaException e) { throw new IllegalStateException( "Couldn't convert object delta: " + objectDeltaType); } } }); } else { Class type = XsdTypeMapper.getXsdToJavaMapping(valueType); if (type != null && type.isPrimitive()) { type = ClassUtils.primitiveToWrapper(type); } if (isEnum(property)) { return WebMiscUtil.createEnumPanel( definition, id, new PropertyModel<>(model, baseExpression), this); } // // default QName validation is a bit weird, so let's treat QNames as // strings [TODO finish this - at the parsing side] // if (type == QName.class) { // type = String.class; // } PrismPropertyDefinition def = property.getDefinition(); if (def.getValueEnumerationRef() != null) { PrismReferenceValue valueEnumerationRef = def.getValueEnumerationRef(); String lookupTableUid = valueEnumerationRef.getOid(); Task task = pageBase.createSimpleTask("loadLookupTable"); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection( LookupTableType.F_ROW, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)); final PrismObject<LookupTableType> lookupTable = WebModelUtils.loadObject( LookupTableType.class, lookupTableUid, options, pageBase, task, result); panel = new AutoCompleteTextPanel<String>( id, new LookupPropertyModel<String>( model, baseExpression, lookupTable == null ? null : lookupTable.asObjectable()), type) { @Override public Iterator<String> getIterator(String input) { return prepareAutoCompleteList(input, lookupTable).iterator(); } @Override public void checkInputValue( AutoCompleteTextField input, AjaxRequestTarget target, LookupPropertyModel model) { Iterator<String> lookupTableValuesIterator = prepareAutoCompleteList("", lookupTable).iterator(); String value = input.getInput(); boolean isValueExist = false; if (value != null) { if (value.trim().equals("")) { isValueExist = true; } else { while (lookupTableValuesIterator.hasNext()) { String lookupTableValue = lookupTableValuesIterator.next(); if (value.trim().equals(lookupTableValue)) { isValueExist = true; break; } } } } if (isValueExist) { input.setModelValue(new String[] {value}); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } else { input.error( "Entered value doesn't match any of available values and will not be saved."); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } } }; } else { panel = new TextPanel<>(id, new PropertyModel<String>(model, baseExpression), type); } } } else if (item instanceof PrismReference) { // ((PrismReferenceDefinition) item.getDefinition()). Class typeFromName = null; PrismContext prismContext = item.getPrismContext(); if (prismContext == null) { prismContext = pageBase.getPrismContext(); } QName targetTypeName = ((PrismReferenceDefinition) item.getDefinition()).getTargetTypeName(); if (targetTypeName != null && prismContext != null) { typeFromName = prismContext.getSchemaRegistry().determineCompileTimeClass(targetTypeName); } final Class typeClass = typeFromName != null ? typeFromName : (item.getDefinition().getTypeClassIfKnown() != null ? item.getDefinition().getTypeClassIfKnown() : FocusType.class); panel = new ValueChoosePanel( id, new PropertyModel<>(model, "value"), item.getValues(), false, typeClass); } return panel; }
private boolean isPassword(PrismPropertyDefinition def) { // in the future, this option could apply as well return CredentialsType.F_PASSWORD.equals(container.getElementName()) || CredentialsType.F_PASSWORD.equals(def.getName()); }
private List<ItemWrapper> createProperties(PageBase pageBase) { result = new OperationResult(CREATE_PROPERTIES); List<ItemWrapper> properties = new ArrayList<ItemWrapper>(); PrismContainerDefinition definition = null; PrismObject parent = getObject().getObject(); Class clazz = parent.getCompileTimeClass(); if (ShadowType.class.isAssignableFrom(clazz)) { QName name = containerDefinition.getName(); if (ShadowType.F_ATTRIBUTES.equals(name)) { try { definition = objectWrapper.getRefinedAttributeDefinition(); if (definition == null) { PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF); PrismObject<ResourceType> resource = resourceRef.getValue().getObject(); definition = pageBase .getModelInteractionService() .getEditObjectClassDefinition( (PrismObject<ShadowType>) objectWrapper.getObject(), resource, AuthorizationPhaseType.REQUEST) .toResourceAttributeContainerDefinition(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Refined account def:\n{}", definition.debugDump()); } } } catch (Exception ex) { LoggingUtils.logException( LOGGER, "Couldn't load definitions from refined schema for shadow", ex); result.recordFatalError( "Couldn't load definitions from refined schema for shadow, reason: " + ex.getMessage(), ex); return properties; } } else { definition = containerDefinition; } } else if (ResourceType.class.isAssignableFrom(clazz)) { if (containerDefinition != null) { definition = containerDefinition; } else { definition = container.getDefinition(); } } else { definition = containerDefinition; } if (definition == null) { LOGGER.error( "Couldn't get property list from null definition {}", new Object[] {container.getElementName()}); return properties; } // assignments are treated in a special way -- we display names of // org.units and roles // (but only if ObjectWrapper.isShowAssignments() is true; otherwise // they are filtered out by ObjectWrapper) if (container.getCompileTimeClass() != null && AssignmentType.class.isAssignableFrom(container.getCompileTimeClass())) { for (Object o : container.getValues()) { PrismContainerValue<AssignmentType> pcv = (PrismContainerValue<AssignmentType>) o; AssignmentType assignmentType = pcv.asContainerable(); if (assignmentType.getTargetRef() == null) { continue; } // 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, DOMUtil.XSD_STRING, pcv.getPrismContext()); if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { def.setDisplayName("Org.Unit"); def.setDisplayOrder(100); } else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { def.setDisplayName("Role"); def.setDisplayOrder(200); } else { continue; } PrismProperty<Object> temp = def.instantiate(); String value = formatAssignmentBrief(assignmentType); temp.setValue(new PrismPropertyValue<Object>(value)); // TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all // cases) properties.add(new PropertyWrapper(this, temp, this.isReadonly(), ValueStatus.NOT_CHANGED)); } } else if (isShadowAssociation()) { PrismContext prismContext = objectWrapper.getObject().getPrismContext(); Map<QName, PrismContainer<ShadowAssociationType>> assocMap = new HashMap<>(); if (objectWrapper.getAssociations() != null) { for (PrismContainerValue<ShadowAssociationType> cval : objectWrapper.getAssociations()) { ShadowAssociationType associationType = cval.asContainerable(); QName assocName = associationType.getName(); PrismContainer<ShadowAssociationType> fractionalContainer = assocMap.get(assocName); if (fractionalContainer == null) { fractionalContainer = new PrismContainer<>( ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext()); fractionalContainer.setDefinition(cval.getParent().getDefinition()); // HACK: set the name of the association as the element name so wrapper.getName() will // return correct data. fractionalContainer.setElementName(assocName); assocMap.put(assocName, fractionalContainer); } try { fractionalContainer.add(cval.clone()); } catch (SchemaException e) { // Should not happen throw new SystemException("Unexpected error: " + e.getMessage(), e); } } } PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF); PrismObject<ResourceType> resource = resourceRef.getValue().getObject(); // HACK. The revive should not be here. Revive is no good. The next use of the resource will // cause parsing of resource schema. We need some centralized place to maintain live cached // copies // of resources. try { resource.revive(prismContext); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } RefinedResourceSchema refinedSchema; CompositeRefinedObjectClassDefinition rOcDef; try { refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); rOcDef = refinedSchema.determineCompositeObjectClassDefinition(parent); } 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()) { QName name = assocDef.getName(); if (!assocMap.containsKey(name)) { PrismContainer<ShadowAssociationType> fractionalContainer = new PrismContainer<>( ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext); fractionalContainer.setDefinition(getItemDefinition()); // HACK: set the name of the association as the element name so wrapper.getName() will // return correct data. fractionalContainer.setElementName(name); assocMap.put(name, fractionalContainer); } } for (Entry<QName, PrismContainer<ShadowAssociationType>> assocEntry : assocMap.entrySet()) { // HACK HACK HACK, the container wrapper should not parse itself. This code should not be // here. AssociationWrapper assocWrapper = new AssociationWrapper( this, assocEntry.getValue(), this.isReadonly(), ValueStatus.NOT_CHANGED); properties.add(assocWrapper); } } else { // if not an assignment if ((container.getValues().size() == 1 || container.getValues().isEmpty()) && (containerDefinition == null || containerDefinition.isSingleValue())) { // there's no point in showing properties for non-single-valued // parent containers, // so we continue only if the parent is single-valued Collection<ItemDefinition> propertyDefinitions = definition.getDefinitions(); for (ItemDefinition itemDef : propertyDefinitions) { if (itemDef instanceof PrismPropertyDefinition) { PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef; if (def.isIgnored() || skipProperty(def)) { continue; } if (!showInheritedObjectAttributes && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { continue; } // capability handling for activation properties if (isShadowActivation() && !hasCapability(def)) { continue; } if (isShadowAssociation()) { continue; } PrismProperty property = container.findProperty(def.getName()); boolean propertyIsReadOnly; // decision is based on parent object status, not this // container's one (because container can be added also // to an existing object) if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) { propertyIsReadOnly = !def.canModify(); } else { propertyIsReadOnly = !def.canAdd(); } if (property == null) { properties.add( new PropertyWrapper( this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED)); } else { properties.add( new PropertyWrapper(this, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED)); } } else if (itemDef instanceof PrismReferenceDefinition) { PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef; if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { continue; } PrismReference reference = container.findReference(def.getName()); boolean propertyIsReadOnly; // decision is based on parent object status, not this // container's one (because container can be added also // to an existing object) if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) { propertyIsReadOnly = !def.canModify(); } else { propertyIsReadOnly = !def.canAdd(); } if (reference == null) { properties.add( new ReferenceWrapper( this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED)); } else { properties.add( new ReferenceWrapper( this, reference, propertyIsReadOnly, ValueStatus.NOT_CHANGED)); } } } } } Collections.sort(properties, new ItemWrapperComparator()); result.recomputeStatus(); return properties; }
// normally this method returns an InputPanel; // however, for some special readonly types (like ObjectDeltaType) it will return a Panel private Panel createTypedInputComponent(String id) { // ValueWrapper valueWrapper = model.getObject(); // ItemWrapper itemWrapper = final Item item = valueWrapperModel.getObject().getItem().getItem(); Panel panel = null; if (item instanceof PrismProperty) { final PrismProperty property = (PrismProperty) item; PrismPropertyDefinition definition = property.getDefinition(); final QName valueType = definition.getTypeName(); final String baseExpression = "value.value"; // pointing to prism property real value // fixing MID-1230, will be improved with some kind of annotation or something like that // now it works only in description if (ObjectType.F_DESCRIPTION.equals(definition.getName())) { return new TextAreaPanel(id, new PropertyModel(valueWrapperModel, baseExpression), null); } if (ActivationType.F_ADMINISTRATIVE_STATUS.equals(definition.getName())) { return WebComponentUtil.createEnumPanel( ActivationStatusType.class, id, new PropertyModel<ActivationStatusType>(valueWrapperModel, baseExpression), this); } else if (ActivationType.F_LOCKOUT_STATUS.equals(definition.getName())) { return new LockoutStatusPanel( id, new PropertyModel<LockoutStatusType>(valueWrapperModel, baseExpression)); } else { // nothing to do } if (DOMUtil.XSD_DATETIME.equals(valueType)) { panel = new DatePanel( id, new PropertyModel<XMLGregorianCalendar>(valueWrapperModel, baseExpression)); } else if (ProtectedStringType.COMPLEX_TYPE.equals(valueType)) { boolean showRemovePasswordButton = true; if (pageBase instanceof PageUser && ((PageUser) pageBase).getObjectWrapper().getObject() != null && ((PageUser) pageBase).getObjectWrapper().getObject().getOid() != null && ((PageUser) pageBase) .getObjectWrapper() .getObject() .getOid() .equals(SecurityUtils.getPrincipalUser().getOid())) { showRemovePasswordButton = false; } panel = new PasswordPanel( id, new PropertyModel<ProtectedStringType>(valueWrapperModel, baseExpression), valueWrapperModel.getObject().isReadonly(), showRemovePasswordButton); } else if (DOMUtil.XSD_BOOLEAN.equals(valueType)) { panel = new TriStateComboPanel( id, new PropertyModel<Boolean>(valueWrapperModel, baseExpression)); } else if (SchemaConstants.T_POLY_STRING_TYPE.equals(valueType)) { InputPanel inputPanel; PrismPropertyDefinition def = property.getDefinition(); if (def.getValueEnumerationRef() != null) { PrismReferenceValue valueEnumerationRef = def.getValueEnumerationRef(); String lookupTableUid = valueEnumerationRef.getOid(); Task task = pageBase.createSimpleTask("loadLookupTable"); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection( LookupTableType.F_ROW, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)); final PrismObject<LookupTableType> lookupTable = WebModelServiceUtils.loadObject( LookupTableType.class, lookupTableUid, options, pageBase, task, result); if (lookupTable != null) { inputPanel = new AutoCompleteTextPanel<String>( id, new LookupPropertyModel<String>( valueWrapperModel, baseExpression + ".orig", lookupTable.asObjectable()), String.class) { @Override public Iterator<String> getIterator(String input) { return prepareAutoCompleteList(input, lookupTable).iterator(); } }; } else { inputPanel = new TextPanel<>( id, new PropertyModel<String>(valueWrapperModel, baseExpression + ".orig"), String.class); } } else { inputPanel = new TextPanel<>( id, new PropertyModel<String>(valueWrapperModel, baseExpression + ".orig"), String.class); } if (ObjectType.F_NAME.equals(def.getName()) || UserType.F_FULL_NAME.equals(def.getName())) { inputPanel.getBaseFormComponent().setRequired(true); } panel = inputPanel; } else if (DOMUtil.XSD_BASE64BINARY.equals(valueType)) { panel = new UploadDownloadPanel(id, valueWrapperModel.getObject().isReadonly()) { @Override public InputStream getStream() { Object object = ((PrismPropertyValue) valueWrapperModel.getObject().getValue()).getValue(); return object != null ? new ByteArrayInputStream((byte[]) object) : new ByteArrayInputStream(new byte[0]); // return super.getStream(); } @Override public void updateValue(byte[] file) { ((PrismPropertyValue) valueWrapperModel.getObject().getValue()).setValue(file); } @Override public void uploadFilePerformed(AjaxRequestTarget target) { super.uploadFilePerformed(target); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } @Override public void removeFilePerformed(AjaxRequestTarget target) { super.removeFilePerformed(target); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } @Override public void uploadFileFailed(AjaxRequestTarget target) { super.uploadFileFailed(target); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); target.add(((PageBase) getPage()).getFeedbackPanel()); } }; } else if (ObjectDeltaType.COMPLEX_TYPE.equals(valueType)) { panel = new ModificationsPanel( id, new AbstractReadOnlyModel<DeltaDto>() { @Override public DeltaDto getObject() { if (valueWrapperModel.getObject() == null || valueWrapperModel.getObject().getValue() == null || ((PrismPropertyValue) valueWrapperModel.getObject().getValue()) .getValue() == null) { return null; } PrismContext prismContext = ((PageBase) getPage()).getPrismContext(); ObjectDeltaType objectDeltaType = (ObjectDeltaType) ((PrismPropertyValue) valueWrapperModel.getObject().getValue()) .getValue(); try { ObjectDelta delta = DeltaConvertor.createObjectDelta(objectDeltaType, prismContext); return new DeltaDto(delta); } catch (SchemaException e) { throw new IllegalStateException( "Couldn't convert object delta: " + objectDeltaType); } } }); } else if (QueryType.COMPLEX_TYPE.equals(valueType) || CleanupPoliciesType.COMPLEX_TYPE.equals(valueType)) { return new TextAreaPanel( id, new AbstractReadOnlyModel() { @Override public Object getObject() { if (valueWrapperModel.getObject() == null || valueWrapperModel.getObject().getValue() == null) { return null; } PrismPropertyValue ppv = (PrismPropertyValue) valueWrapperModel.getObject().getValue(); if (ppv == null || ppv.getValue() == null) { return null; } QName name = property.getElementName(); if (name == null && property.getDefinition() != null) { name = property.getDefinition().getName(); } if (name == null) { name = SchemaConstants.C_VALUE; } PrismContext prismContext = ((PageBase) getPage()).getPrismContext(); try { return prismContext.serializeAnyData(ppv.getValue(), name, PrismContext.LANG_XML); } catch (SchemaException e) { throw new SystemException( "Couldn't serialize property value of type: " + valueType + ": " + e.getMessage(), e); } } }, 10); } else { Class type = XsdTypeMapper.getXsdToJavaMapping(valueType); if (type != null && type.isPrimitive()) { type = ClassUtils.primitiveToWrapper(type); } if (isEnum(property)) { return WebComponentUtil.createEnumPanel( definition, id, new PropertyModel<>(valueWrapperModel, baseExpression), this); } // // default QName validation is a bit weird, so let's treat QNames as // strings [TODO finish this - at the parsing side] // if (type == QName.class) { // type = String.class; // } PrismPropertyDefinition def = property.getDefinition(); if (def.getValueEnumerationRef() != null) { PrismReferenceValue valueEnumerationRef = def.getValueEnumerationRef(); String lookupTableUid = valueEnumerationRef.getOid(); Task task = pageBase.createSimpleTask("loadLookupTable"); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection( LookupTableType.F_ROW, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)); final PrismObject<LookupTableType> lookupTable = WebModelServiceUtils.loadObject( LookupTableType.class, lookupTableUid, options, pageBase, task, result); if (lookupTable != null) { panel = new AutoCompleteTextPanel<String>( id, new LookupPropertyModel<String>( valueWrapperModel, baseExpression, lookupTable == null ? null : lookupTable.asObjectable()), type) { @Override public Iterator<String> getIterator(String input) { return prepareAutoCompleteList(input, lookupTable).iterator(); } @Override public void checkInputValue( AutoCompleteTextField input, AjaxRequestTarget target, LookupPropertyModel model) { Iterator<String> lookupTableValuesIterator = prepareAutoCompleteList("", lookupTable).iterator(); String value = input.getInput(); boolean isValueExist = false; if (value != null) { if (value.trim().equals("")) { isValueExist = true; } else { while (lookupTableValuesIterator.hasNext()) { String lookupTableValue = lookupTableValuesIterator.next(); if (value.trim().equals(lookupTableValue)) { isValueExist = true; break; } } } } if (isValueExist) { input.setModelValue(new String[] {value}); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } else { input.error( "Entered value doesn't match any of available values and will not be saved."); target.add(PrismValuePanel.this.get(ID_FEEDBACK)); } } }; } else { panel = new TextPanel<>( id, new PropertyModel<String>(valueWrapperModel, baseExpression), type); } } else { panel = new TextPanel<>( id, new PropertyModel<String>(valueWrapperModel, baseExpression), type); } } } else if (item instanceof PrismReference) { PrismContext prismContext = item.getPrismContext(); if (prismContext == null) { prismContext = pageBase.getPrismContext(); } QName targetTypeName = ((PrismReferenceDefinition) item.getDefinition()).getTargetTypeName(); Class targetClass = null; if (targetTypeName != null && prismContext != null) { targetClass = prismContext.getSchemaRegistry().determineCompileTimeClass(targetTypeName); } final Class typeClass = targetClass != null ? targetClass : (item.getDefinition().getTypeClassIfKnown() != null ? item.getDefinition().getTypeClassIfKnown() : FocusType.class); Collection typeClasses = new ArrayList(); // HACK HACK MID-3201 MID-3231 if (isUserOrgItem(item, typeClass)) { typeClasses.add(UserType.class); typeClasses.add(OrgType.class); } else { typeClasses.add(typeClass); } panel = new ValueChoosePanel( id, new PropertyModel<>(valueWrapperModel, "value"), item.getValues(), false, typeClasses); } else if (item instanceof PrismContainer<?>) { AssociationWrapper itemWrapper = (AssociationWrapper) valueWrapperModel.getObject().getItem(); final PrismContainer container = (PrismContainer) item; PrismContainerDefinition definition = container.getDefinition(); QName valueType = definition.getTypeName(); if (ShadowAssociationType.COMPLEX_TYPE.equals(valueType)) { PrismContext prismContext = item.getPrismContext(); if (prismContext == null) { prismContext = pageBase.getPrismContext(); } ShadowType shadowType = ((ShadowType) itemWrapper.getContainer().getObject().getObject().asObjectable()); PrismObject<ResourceType> resource = shadowType.getResource().asPrismObject(); // HACK. The revive should not be here. Revive is no good. The next use of the resource will // cause parsing of resource schema. We need some centralized place to maintain live cached // copies // of resources. try { resource.revive(prismContext); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } RefinedResourceSchema refinedSchema; CompositeRefinedObjectClassDefinition rOcDef; try { refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); rOcDef = refinedSchema.determineCompositeObjectClassDefinition(shadowType.asPrismObject()); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } RefinedAssociationDefinition assocDef = itemWrapper.getRefinedAssociationDefinition(); RefinedObjectClassDefinition assocTargetDef = assocDef.getAssociationTarget(); ObjectQuery query = getAssociationsSearchQuery( prismContext, resource, assocTargetDef.getTypeName(), assocTargetDef.getKind(), assocTargetDef.getIntent()); List values = item.getValues(); return new AssociationValueChoicePanel( id, valueWrapperModel, values, false, ShadowType.class, query, assocTargetDef); } } return panel; }