Example #1
0
  private CallableResult<List<AssignmentItemDto>> loadAssignments() throws Exception {
    LOGGER.debug("Loading assignments.");
    CallableResult callableResult = new CallableResult();
    List<AssignmentItemDto> list = new ArrayList<AssignmentItemDto>();
    callableResult.setValue(list);

    PrismObject<UserType> user = principalModel.getObject();
    if (user == null || user.findContainer(UserType.F_ASSIGNMENT) == null) {
      return callableResult;
    }

    Task task = createSimpleTask(OPERATION_LOAD_ASSIGNMENTS);
    OperationResult result = task.getResult();
    callableResult.setResult(result);

    PrismContainer assignments = user.findContainer(UserType.F_ASSIGNMENT);
    List<PrismContainerValue> values = assignments.getValues();
    for (PrismContainerValue assignment : values) {
      AssignmentItemDto item = createAssignmentItem(user, assignment, task, result);
      if (item != null) {
        list.add(item);
      }
    }
    result.recordSuccessIfUnknown();
    result.recomputeStatus();

    Collections.sort(list);

    LOGGER.debug("Finished assignments loading.");

    return callableResult;
  }
 public static ResourceSchema getResourceSchema(
     PrismObject<ResourceType> 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 RefinedResourceSchema getRefinedSchema(
      PrismObject<ResourceType> 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 void setParsedResourceSchemaConditional(
     ResourceType resourceType, ResourceSchema parsedSchema) {
   if (hasParsedSchema(resourceType)) {
     return;
   }
   PrismObject<ResourceType> resource = resourceType.asPrismObject();
   resource.setUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA, parsedSchema);
 }
Example #5
0
  private AssignmentItemDto createAssignmentItem(
      PrismObject<UserType> user,
      PrismContainerValue assignment,
      Task task,
      OperationResult result) {
    PrismReference targetRef = assignment.findReference(AssignmentType.F_TARGET_REF);
    if (targetRef == null || targetRef.isEmpty()) {
      // account construction
      PrismContainer construction = assignment.findContainer(AssignmentType.F_CONSTRUCTION);
      String name = null;
      String description = null;
      if (construction.getValue().asContainerable() != null && !construction.isEmpty()) {
        ConstructionType constr = (ConstructionType) construction.getValue().asContainerable();
        description =
            (String)
                construction.getPropertyRealValue(ConstructionType.F_DESCRIPTION, String.class);

        if (constr.getResourceRef() != null) {
          ObjectReferenceType resourceRef = constr.getResourceRef();

          PrismObject resource =
              WebModelUtils.loadObject(
                  ResourceType.class, resourceRef.getOid(), this, task, result);
          name = WebMiscUtil.getName(resource);
        }
      }

      return new AssignmentItemDto(
          AssignmentEditorDtoType.ACCOUNT_CONSTRUCTION, name, description, null);
    }

    PrismReferenceValue refValue = targetRef.getValue();
    PrismObject value = refValue.getObject();
    if (value == null) {
      // resolve reference
      value = WebModelUtils.loadObject(ObjectType.class, refValue.getOid(), this, task, result);
    }

    if (value == null) {
      // we couldn't resolve assignment details
      return new AssignmentItemDto(null, null, null, null);
    }

    String name = WebMiscUtil.getName(value);
    AssignmentEditorDtoType type = AssignmentEditorDtoType.getType(value.getCompileTimeClass());
    String relation = refValue.getRelation() != null ? refValue.getRelation().getLocalPart() : null;
    String description = null;
    if (RoleType.class.isAssignableFrom(value.getCompileTimeClass())) {
      description = (String) value.getPropertyRealValue(RoleType.F_DESCRIPTION, String.class);
    }

    return new AssignmentItemDto(type, name, description, relation);
  }
Example #6
0
  private AccountCallableResult<List<SimpleAccountDto>> loadAccounts() throws Exception {
    LOGGER.debug("Loading accounts.");

    AccountCallableResult callableResult = new AccountCallableResult();
    List<SimpleAccountDto> list = new ArrayList<SimpleAccountDto>();
    callableResult.setValue(list);
    PrismObject<UserType> user = principalModel.getObject();
    if (user == null) {
      return callableResult;
    }

    Task task = createSimpleTask(OPERATION_LOAD_ACCOUNTS);
    OperationResult result = task.getResult();
    callableResult.setResult(result);
    Collection<SelectorOptions<GetOperationOptions>> options =
        SelectorOptions.createCollection(
            ShadowType.F_RESOURCE, GetOperationOptions.createResolve());

    List<ObjectReferenceType> references = user.asObjectable().getLinkRef();
    for (ObjectReferenceType reference : references) {
      PrismObject<ShadowType> account =
          WebModelUtils.loadObject(
              ShadowType.class, reference.getOid(), options, this, task, result);
      if (account == null) {
        continue;
      }

      ShadowType accountType = account.asObjectable();

      OperationResultType fetchResult = accountType.getFetchResult();

      if (fetchResult != null) {
        callableResult.getFetchResults().add(OperationResult.createOperationResult(fetchResult));
      }

      ResourceType resource = accountType.getResource();
      String resourceName = WebMiscUtil.getName(resource);
      list.add(
          new SimpleAccountDto(
              WebMiscUtil.getOrigStringFromPoly(accountType.getName()), resourceName));
    }
    result.recordSuccessIfUnknown();
    result.recomputeStatus();

    LOGGER.debug("Finished accounts loading.");

    return callableResult;
  }
Example #7
0
  private List<String> prepareAutoCompleteList(
      String input, PrismObject<LookupTableType> lookupTable) {
    List<String> values = new ArrayList<>();

    if (lookupTable == null) {
      return values;
    }

    List<LookupTableRowType> rows = lookupTable.asObjectable().getRow();

    if (input == null || input.isEmpty()) {
      for (LookupTableRowType row : rows) {
        values.add(WebComponentUtil.getOrigStringFromPoly(row.getLabel()));
      }
    } else {
      for (LookupTableRowType row : rows) {
        if (WebComponentUtil.getOrigStringFromPoly(row.getLabel()) != null
            && WebComponentUtil.getOrigStringFromPoly(row.getLabel())
                .toLowerCase()
                .contains(input.toLowerCase())) {
          values.add(WebComponentUtil.getOrigStringFromPoly(row.getLabel()));
        }
      }
    }

    return values;
  }
Example #8
0
 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;
   }
 }
  @Override
  public CompositeRefinedObjectClassDefinition determineCompositeObjectClassDefinition(
      PrismObject<ShadowType> shadow, Collection<QName> 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<QName> auxiliaryObjectClassQNames = shadowType.getAuxiliaryObjectClass();
    if (additionalAuxiliaryObjectClassQNames != null) {
      auxiliaryObjectClassQNames.addAll(additionalAuxiliaryObjectClassQNames);
    }
    Collection<RefinedObjectClassDefinition> 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);
  }
 public static RefinedResourceSchema parse(
     PrismObject<ResourceType> resource, PrismContext prismContext) throws SchemaException {
   return parse(resource.asObjectable(), prismContext);
 }
 public static boolean hasParsedSchema(ResourceType resourceType) {
   PrismObject<ResourceType> resource = resourceType.asPrismObject();
   return resource.getUserData(USER_DATA_KEY_PARSED_RESOURCE_SCHEMA) != null;
 }
 public static boolean hasRefinedSchema(ResourceType resourceType) {
   PrismObject<ResourceType> resource = resourceType.asPrismObject();
   return resource.getUserData(USER_DATA_KEY_REFINED_SCHEMA) != null;
 }
 public static RefinedResourceSchema getRefinedSchema(PrismObject<ResourceType> resource)
     throws SchemaException {
   return getRefinedSchema(resource, resource.getPrismContext());
 }
Example #14
0
  // 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;
  }