Beispiel #1
0
    @Override
    public int compare(ContainerWrapper c1, ContainerWrapper c2) {
      int size1 = c1.getPath() != null ? c1.getPath().size() : 0;
      int size2 = c2.getPath() != null ? c2.getPath().size() : 0;

      return size1 - size2;
    }
Beispiel #2
0
  private List<ContainerWrapper> createReportContainers(PageBase pageBase) throws SchemaException {
    List<ContainerWrapper> containers = new ArrayList<ContainerWrapper>();

    PrismContainer container = object.findContainer(ReportType.F_CONFIGURATION);
    ContainerStatus status = container != null ? ContainerStatus.MODIFYING : ContainerStatus.ADDING;

    if (container == null) {
      PrismSchema schema =
          ReportTypeUtil.parseReportConfigurationSchema(
              (PrismObject<ReportType>) object, object.getPrismContext());
      PrismContainerDefinition definition =
          ReportTypeUtil.findReportConfigurationDefinition(schema);
      if (definition == null) {
        return containers;
      }
      container = definition.instantiate();
    }

    ContainerWrapper wrapper =
        new ContainerWrapper(
            this, container, status, new ItemPath(ReportType.F_CONFIGURATION), pageBase);
    addSubresult(wrapper.getResult());

    containers.add(wrapper);

    return containers;
  }
Beispiel #3
0
 @Override
 public ItemDefinition getItemDefinition() {
   ItemDefinition propDef = null;
   if (container.getItemDefinition() != null) {
     propDef =
         container.getItemDefinition().findItemDefinition(property.getDefinition().getName());
   }
   if (propDef == null) {
     propDef = property.getDefinition();
   }
   return propDef;
 }
Beispiel #4
0
 public void revive(PrismContext prismContext) throws SchemaException {
   if (object != null) {
     object.revive(prismContext);
   }
   if (oldDelta != null) {
     oldDelta.revive(prismContext);
   }
   if (containers != null) {
     for (ContainerWrapper containerWrapper : containers) {
       containerWrapper.revive(prismContext);
     }
   }
 }
Beispiel #5
0
  public ContainerWrapper findContainerWrapper(ItemPath path) {
    for (ContainerWrapper wrapper : getContainers()) {
      if (path != null) {
        if (path.equivalent(wrapper.getPath())) {
          return wrapper;
        }
      } else {
        if (wrapper.getPath() == null) {
          return wrapper;
        }
      }
    }

    return null;
  }
Beispiel #6
0
 @Override
 public String getDisplayName() {
   if (StringUtils.isNotEmpty(displayName)) {
     return displayName;
   }
   return ContainerWrapper.getDisplayNameFromItem(property);
 }
Beispiel #7
0
  public boolean isVisible() {
    if (property.getDefinition().isOperational()) {
      return false;
    }

    return container.isItemVisible(this);
  }
Beispiel #8
0
  private boolean isThisPropertyActivationEnabled() {
    if (!new ItemPath(UserType.F_ACTIVATION).equivalent(container.getPath())) {
      return false;
    }

    if (!ActivationType.F_ADMINISTRATIVE_STATUS.equals(property.getElementName())) {
      return false;
    }

    if (ContainerStatus.MODIFYING.equals(container.getObject().getStatus())) {
      // when modifying then we don't want to create "true" value for c:activation/c:enabled, only
      // during add
      return false;
    }

    return true;
  }
Beispiel #9
0
 @Override
 public String toString() {
   StringBuilder builder = new StringBuilder();
   builder.append("ObjectWrapper(");
   builder.append(ContainerWrapper.getDisplayNameFromItem(object));
   builder.append(" (");
   builder.append(status);
   builder.append(") ");
   builder.append(getContainers() == null ? null : getContainers().size());
   builder.append(" containers)");
   return builder.toString();
 }
Beispiel #10
0
  private List<ContainerWrapper> createCustomContainerWrapper(
      PrismObject object, QName name, PageBase pageBase) {
    PrismContainer container = object.findContainer(name);
    ContainerStatus status = container == null ? ContainerStatus.ADDING : ContainerStatus.MODIFYING;
    List<ContainerWrapper> list = new ArrayList<ContainerWrapper>();
    if (container == null) {
      PrismContainerDefinition definition = getDefinition().findContainerDefinition(name);
      container = definition.instantiate();
    }

    ContainerWrapper wrapper =
        new ContainerWrapper(this, container, status, new ItemPath(name), pageBase);
    addSubresult(wrapper.getResult());
    list.add(wrapper);
    // list.addAll(createContainerWrapper(container, null, pageBase));
    if (!ShadowType.F_ASSOCIATION.equals(name)) {
      // [pm] is this OK? "name" is the name of the container itself; originally here was an empty
      // path - that seems more logical
      list.addAll(createContainerWrapper(container, new ItemPath(name), pageBase));
    }

    return list;
  }
Beispiel #11
0
  public PropertyWrapper(
      ContainerWrapper container, I property, boolean readonly, ValueStatus status) {
    Validate.notNull(property, "Property must not be null.");
    Validate.notNull(status, "Property status must not be null.");

    this.container = container;
    this.property = property;
    this.status = status;
    this.readonly = readonly;
    this.itemDefinition = getItemDefinition();

    ItemPath passwordPath =
        new ItemPath(SchemaConstantsGenerated.C_CREDENTIALS, CredentialsType.F_PASSWORD);
    if (passwordPath.equivalent(container.getPath())
        && PasswordType.F_VALUE.equals(property.getElementName())) {
      displayName = "prismPropertyPanel.name.credentials.password";
    }

    values = createValues();
  }
  // 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;
  }
Beispiel #13
0
  private ObjectDelta createAddingObjectDelta() throws SchemaException {
    PrismObject object = this.object.clone();

    List<ContainerWrapper> containers = getContainers();
    // sort containers by path size
    Collections.sort(containers, new PathSizeComparator());

    for (ContainerWrapper containerWrapper : getContainers()) {

      if (containerWrapper.getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) {
        PrismContainer associationContainer =
            object.findOrCreateContainer(ShadowType.F_ASSOCIATION);
        List<AssociationWrapper> associationItemWrappers =
            (List<AssociationWrapper>) containerWrapper.getItems();
        for (AssociationWrapper associationItemWrapper : associationItemWrappers) {
          List<ValueWrapper> assocValueWrappers = associationItemWrapper.getValues();
          for (ValueWrapper assocValueWrapper : assocValueWrappers) {
            PrismContainerValue<ShadowAssociationType> assocValue =
                (PrismContainerValue<ShadowAssociationType>) assocValueWrapper.getValue();
            associationContainer.add(assocValue.clone());
          }
        }
        continue;
      }

      if (!containerWrapper.hasChanged()) {
        continue;
      }

      PrismContainer container = containerWrapper.getItem();
      ItemPath path = containerWrapper.getPath();
      if (containerWrapper.getPath() != null) {
        container = container.clone();
        if (path.size() > 1) {
          ItemPath parentPath = path.allExceptLast();
          PrismContainer parent = object.findOrCreateContainer(parentPath);
          parent.add(container);
        } else {
          PrismContainer existing = object.findContainer(container.getElementName());
          if (existing == null) {
            object.add(container);
          } else {
            continue;
          }
        }
      } else {
        container = object;
      }

      for (ItemWrapper propertyWrapper : (List<ItemWrapper>) containerWrapper.getItems()) {
        if (!propertyWrapper.hasChanged()) {
          continue;
        }

        Item property = propertyWrapper.getItem().clone();
        if (container.findProperty(property.getElementName()) != null) {
          continue;
        }
        for (ValueWrapper valueWrapper : propertyWrapper.getValues()) {
          valueWrapper.normalize(object.getPrismContext());
          if (!valueWrapper.hasValueChanged()
              || ValueStatus.DELETED.equals(valueWrapper.getStatus())) {
            continue;
          }

          if (property.hasRealValue(valueWrapper.getValue())) {
            continue;
          }

          PrismValue cloned = clone(valueWrapper.getValue());
          if (cloned != null) {
            property.add(cloned);
          }
        }

        if (!property.isEmpty()) {
          container.add(property);
        }
      }
    }

    // cleanup empty containers
    cleanupEmptyContainers(object);

    ObjectDelta delta = ObjectDelta.createAddDelta(object);

    // returning container to previous order
    Collections.sort(containers, new ItemWrapperComparator());

    if (InternalsConfig.consistencyChecks) {
      delta.checkConsistence(true, true, true, ConsistencyCheckScope.THOROUGH);
    }

    return delta;
  }
Beispiel #14
0
  public ObjectDelta getObjectDelta() throws SchemaException {
    if (ContainerStatus.ADDING.equals(getStatus())) {
      return createAddingObjectDelta();
    }

    ObjectDelta delta =
        new ObjectDelta(object.getCompileTimeClass(), ChangeType.MODIFY, object.getPrismContext());
    delta.setOid(object.getOid());

    List<ContainerWrapper> containers = getContainers();
    // sort containers by path size
    Collections.sort(containers, new PathSizeComparator());

    for (ContainerWrapper containerWrapper : getContainers()) {
      // create ContainerDelta for association container
      // HACK HACK HACK create correct procession for association container data
      // according to its structure
      if (containerWrapper.getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) {
        ContainerDelta<ShadowAssociationType> associationDelta =
            ContainerDelta.createDelta(
                ShadowType.F_ASSOCIATION, containerWrapper.getItemDefinition());
        List<AssociationWrapper> associationItemWrappers =
            (List<AssociationWrapper>) containerWrapper.getItems();
        for (AssociationWrapper associationItemWrapper : associationItemWrappers) {
          List<ValueWrapper> assocValueWrappers = associationItemWrapper.getValues();
          for (ValueWrapper assocValueWrapper : assocValueWrappers) {
            PrismContainerValue<ShadowAssociationType> assocValue =
                (PrismContainerValue<ShadowAssociationType>) assocValueWrapper.getValue();
            if (assocValueWrapper.getStatus() == ValueStatus.DELETED) {
              associationDelta.addValueToDelete(assocValue.clone());
            } else if (assocValueWrapper.getStatus().equals(ValueStatus.ADDED)) {
              associationDelta.addValueToAdd(assocValue.clone());
            }
          }
        }
        delta.addModification(associationDelta);
      } else {
        if (!containerWrapper.hasChanged()) {
          continue;
        }

        for (ItemWrapper itemWrapper : (List<ItemWrapper>) containerWrapper.getItems()) {
          if (!itemWrapper.hasChanged()) {
            continue;
          }
          ItemPath containerPath =
              containerWrapper.getPath() != null ? containerWrapper.getPath() : new ItemPath();
          if (itemWrapper instanceof PropertyWrapper) {
            ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath);
            if (!pDelta.isEmpty()) {
              delta.addModification(pDelta);
            }
          }

          if (itemWrapper instanceof ReferenceWrapper) {
            ReferenceDelta pDelta =
                computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath);
            if (!pDelta.isEmpty()) {
              delta.addModification(pDelta);
            }
          }
        }
      }
    }
    // returning container to previous order
    Collections.sort(containers, new ItemWrapperComparator());

    // Make sure we have all the definitions
    if (object.getPrismContext() != null) {
      object.getPrismContext().adopt(delta);
    }
    return delta;
  }
Beispiel #15
0
  private List<ContainerWrapper> createContainerWrapper(
      PrismContainer parent, ItemPath path, PageBase pageBase) {

    PrismContainerDefinition definition = parent.getDefinition();
    List<ContainerWrapper> wrappers = new ArrayList<ContainerWrapper>();

    List<ItemPathSegment> segments = new ArrayList<ItemPathSegment>();
    if (path != null) {
      segments.addAll(path.getSegments());
    }
    ItemPath parentPath = new ItemPath(segments);
    for (ItemDefinition def : (Collection<ItemDefinition>) definition.getDefinitions()) {
      if (!(def instanceof PrismContainerDefinition)) {
        continue;
      }
      if (ObjectSpecificationType.COMPLEX_TYPE.equals(def.getTypeName())) {
        continue; // TEMPORARY FIX
      }
      if (TriggerType.COMPLEX_TYPE.equals(def.getTypeName())) {
        continue; // TEMPORARY FIX TODO: remove after getEditSchema
        // (authorization) will be fixed.
      }
      if (ApprovalSchemaType.COMPLEX_TYPE.equals(def.getTypeName())) {
        continue;
      }

      LOGGER.trace("ObjectWrapper.createContainerWrapper processing definition: {}", def);

      PrismContainerDefinition containerDef = (PrismContainerDefinition) def;
      if (!showAssignments && AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName())) {
        continue;
      }
      if (!showInheritedObjectAttributes) {
        boolean result = INHERITED_OBJECT_SUBCONTAINERS.contains(containerDef.getName());
        LOGGER.info("checking " + containerDef.getName() + ", result = " + result);
        if (result) {
          continue;
        }
      }

      ItemPath newPath = createPropertyPath(parentPath, containerDef.getName());

      // [med]
      // The following code fails to work when parent is multivalued or
      // potentially multivalued.
      // Therefore (as a brutal hack), for multivalued parents we simply
      // skip it.
      if (parent.size() <= 1) {

        // the same check as in getValue() implementation
        boolean isMultiValued =
            parent.getDefinition() != null
                && !parent.getDefinition().isDynamic()
                && !parent.getDefinition().isSingleValue();
        if (!isMultiValued) {
          PrismContainer prismContainer = parent.findContainer(def.getName());

          ContainerWrapper container;
          if (prismContainer != null) {
            container =
                new ContainerWrapper(
                    this, prismContainer, ContainerStatus.MODIFYING, newPath, pageBase);
          } else {
            prismContainer = containerDef.instantiate();
            container =
                new ContainerWrapper(
                    this, prismContainer, ContainerStatus.ADDING, newPath, pageBase);
          }
          addSubresult(container.getResult());
          wrappers.add(container);

          if (!AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName())
              || !ShadowType.F_ASSOCIATION.equals(parent.getElementName())) { // do
            // not
            // show
            // internals
            // of
            // Assignments
            // (e.g.
            // activation)
            wrappers.addAll(createContainerWrapper(prismContainer, newPath, pageBase));
          }
        }
      }
    }

    return wrappers;
  }
Beispiel #16
0
  private List<ContainerWrapper> createContainers(PageBase pageBase) {
    result = new OperationResult(CREATE_CONTAINERS);

    List<ContainerWrapper> containers = new ArrayList<ContainerWrapper>();

    try {
      Class clazz = object.getCompileTimeClass();
      if (ShadowType.class.isAssignableFrom(clazz)) {
        PrismContainer attributes = object.findContainer(ShadowType.F_ATTRIBUTES);
        ContainerStatus status = attributes != null ? getStatus() : ContainerStatus.ADDING;
        if (attributes == null) {
          PrismContainerDefinition definition =
              object.getDefinition().findContainerDefinition(ShadowType.F_ATTRIBUTES);
          attributes = definition.instantiate();
        }

        ContainerWrapper container =
            new ContainerWrapper(
                this, attributes, status, new ItemPath(ShadowType.F_ATTRIBUTES), pageBase);
        addSubresult(container.getResult());

        container.setMain(true);
        containers.add(container);

        if (hasResourceCapability(
            ((ShadowType) object.asObjectable()).getResource(), ActivationCapabilityType.class)) {
          containers.addAll(
              createCustomContainerWrapper(object, ShadowType.F_ACTIVATION, pageBase));
        }
        if (hasResourceCapability(
            ((ShadowType) object.asObjectable()).getResource(), CredentialsCapabilityType.class)) {
          containers.addAll(
              createCustomContainerWrapper(object, ShadowType.F_CREDENTIALS, pageBase));
        }

        PrismContainer<ShadowAssociationType> associationContainer =
            object.findOrCreateContainer(ShadowType.F_ASSOCIATION);
        container =
            new ContainerWrapper(
                this,
                associationContainer,
                ContainerStatus.MODIFYING,
                new ItemPath(ShadowType.F_ASSOCIATION),
                pageBase);
        addSubresult(container.getResult());
        containers.add(container);
      } else if (ResourceType.class.isAssignableFrom(clazz)) {
        containers = createResourceContainers(pageBase);
      } else if (ReportType.class.isAssignableFrom(clazz)) {
        containers = createReportContainers(pageBase);
      } else {
        ContainerWrapper container =
            new ContainerWrapper(this, object, getStatus(), null, pageBase);
        addSubresult(container.getResult());
        containers.add(container);

        containers.addAll(createContainerWrapper(object, null, pageBase));
      }
    } catch (Exception ex) {
      // TODO: shouldn't be this exception thrown????
      LoggingUtils.logUnexpectedException(LOGGER, "Error occurred during container wrapping", ex);
      result.recordFatalError(
          "Error occurred during container wrapping, reason: " + ex.getMessage(), ex);
    }

    Collections.sort(containers, new ItemWrapperComparator());
    result.recomputeStatus();
    result.recordSuccessIfUnknown();

    return containers;
  }