/*
* Copyright (c) 2010-2017 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.web.component.wizard.resource;
import com.evolveum.midpoint.gui.api.model.NonEmptyLoadableModel;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.util.ItemPathUtil;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ResourceTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.component.data.paging.NavigatorPanel;
import com.evolveum.midpoint.web.component.form.multivalue.MultiValueTextEditPanel;
import com.evolveum.midpoint.web.component.util.ListDataProvider;
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
import com.evolveum.midpoint.web.component.wizard.WizardStep;
import com.evolveum.midpoint.web.component.wizard.WizardUtil;
import com.evolveum.midpoint.web.component.wizard.resource.component.schemahandling.*;
import com.evolveum.midpoint.web.component.wizard.resource.dto.ResourceObjectTypeDefinitionTypeDto;
import com.evolveum.midpoint.web.component.wizard.resource.dto.SchemaHandlingDto;
import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnChangeAjaxFormUpdatingBehavior;
import com.evolveum.midpoint.web.page.admin.resources.PageResourceWizard;
import com.evolveum.midpoint.web.session.UserProfileStorage;
import com.evolveum.midpoint.web.util.ExpressionUtil;
import com.evolveum.midpoint.web.util.InfoTooltipBehavior;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.string.Strings;
import org.jetbrains.annotations.NotNull;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import static com.evolveum.midpoint.schema.util.ResourceTypeUtil.fillDefault;
/**
* @author lazyman
* @author shood
*/
public class SchemaHandlingStep extends WizardStep {
private static final Trace LOGGER = TraceManager.getTrace(SchemaHandlingStep.class);
private static final String DOT_CLASS = SchemaHandlingStep.class.getName() + ".";
private static final String OPERATION_SAVE_SCHEMA_HANDLING = DOT_CLASS + "saveSchemaHandling";
private static final String ID_ROWS = "tableRows";
private static final String ID_ROW_OBJECT_TYPE = "objectTypeRow";
private static final String ID_LINK_OBJECT_TYPE = "objectTypeLink";
private static final String ID_NAME_OBJECT_TYPE = "objectTypeName";
private static final String ID_BUTTON_DELETE_OBJECT_TYPE = "objectTypeDelete";
private static final String ID_PAGING_OBJECT_TYPE = "objectTypePaging";
private static final String ID_BUTTON_ADD_OBJECT_TYPE = "objectTypeAddButton";
private static final String ID_OBJECT_TYPE_EDITOR = "objectTypeConfig";
private static final String ID_THIRD_ROW_CONTAINER = "thirdRowContainer";
private static final String ID_EDITOR_NAME = "editorName";
private static final String ID_EDITOR_KIND = "editorKind";
private static final String ID_EDITOR_INTENT = "editorIntent";
private static final String ID_EDITOR_DISPLAY_NAME = "editorDisplayName";
private static final String ID_EDITOR_DESCRIPTION = "editorDescription";
private static final String ID_EDITOR_DEFAULT = "editorDefault";
private static final String ID_EDITOR_BUTTON_DEPENDENCY = "editorDependencyButton";
private static final String ID_EDITOR_OBJECT_CLASS = "editorObjectClass";
private static final String ID_EDITOR_ASSIGNMENT_POLICY = "editorAssignmentPolicyRef";
private static final String ID_EDITOR_BUTTON_ITERATION = "editorIterationButton";
private static final String ID_EDITOR_BUTTON_PROTECTED = "editorProtectedButton";
private static final String ID_EDITOR_BUTTON_ACTIVATION = "editorActivationButton";
private static final String ID_EDITOR_BUTTON_CREDENTIALS = "editorCredentialsButton";
private static final String ID_EDITOR_ATTRIBUTES = "editorAttributes";
private static final String ID_EDITOR_ASSOCIATIONS = "editorAssociations";
private static final String ID_T_KIND = "kindTooltip";
private static final String ID_T_INTENT = "intentTooltip";
private static final String ID_T_DEFAULT = "defaultTooltip";
private static final String ID_T_DEPENDENCY = "dependencyTooltip";
private static final String ID_T_OBJECT_CLASS = "objectClassTooltip";
private static final String ID_T_ATTRIBUTES = "attributesTooltip";
private static final String ID_T_ASSOCIATIONS = "associationsTooltip";
private static final String ID_T_ASSIGNMENT_POLICY_REF = "assignmentPolicyRefTooltip";
private static final String ID_T_ITERATION = "iterationTooltip";
private static final String ID_T_PROTECTED = "protectedTooltip";
private static final String ID_T_ACTIVATION = "activationTooltip";
private static final String ID_T_CREDENTIALS = "credentialsTooltip";
private static final Integer AUTO_COMPLETE_LIST_SIZE = 10;
@NotNull final private PageResourceWizard parentPage;
@NotNull final private NonEmptyLoadableModel<PrismObject<ResourceType>> resourceModel;
@NotNull final private NonEmptyLoadableModel<SchemaHandlingDto> schemaHandlingDtoModel;
public SchemaHandlingStep(@NotNull final NonEmptyLoadableModel<PrismObject<ResourceType>> resourceModel, @NotNull PageResourceWizard parentPage) {
super(parentPage);
this.parentPage = parentPage;
this.resourceModel = resourceModel;
schemaHandlingDtoModel = new NonEmptyLoadableModel<SchemaHandlingDto>(false) {
@Override
@NotNull
protected SchemaHandlingDto load() {
return loadSchemaHandlingDto();
}
@Override
public void reset() {
LOGGER.trace("Resetting schemaHandlingDtoModel {}", schemaHandlingDtoModel);
super.reset();
}
};
parentPage.registerDependentModel(schemaHandlingDtoModel);
initLayout();
setOutputMarkupId(true);
}
private SchemaHandlingDto loadSchemaHandlingDto() {
List<ResourceObjectTypeDefinitionTypeDto> objectTypeDefs = new ArrayList<>();
SchemaHandlingType schemaHandling = getOrCreateSchemaHandling();
for (ResourceObjectTypeDefinitionType objectType: schemaHandling.getObjectType()) {
objectTypeDefs.add(new ResourceObjectTypeDefinitionTypeDto(objectType));
}
List<QName> objectClasses = loadResourceObjectClassList(resourceModel, LOGGER,
getString("SchemaHandlingStep.message.errorLoadingObjectTypeList"));
return new SchemaHandlingDto(objectTypeDefs, objectClasses);
}
private boolean isAnySelected() {
return schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto() != null;
}
private void initLayout() {
final ListDataProvider<ResourceObjectTypeDefinitionTypeDto> objectTypeProvider = new ListDataProvider<>(this,
new PropertyModel<List<ResourceObjectTypeDefinitionTypeDto>>(schemaHandlingDtoModel, SchemaHandlingDto.F_OBJECT_TYPE_DTO_LIST));
// first row - object types table
WebMarkupContainer objectTypesTable = new WebMarkupContainer(ID_ROWS);
objectTypesTable.setOutputMarkupId(true);
add(objectTypesTable);
// second row - object type editor
WebMarkupContainer objectTypeEditor = new WebMarkupContainer(ID_OBJECT_TYPE_EDITOR);
objectTypeEditor.setOutputMarkupId(true);
objectTypeEditor.add(new VisibleEnableBehaviour(){
@Override
public boolean isVisible() {
return isAnySelected();
}
});
add(objectTypeEditor);
// third row container
WebMarkupContainer thirdRowContainer = new WebMarkupContainer(ID_THIRD_ROW_CONTAINER);
thirdRowContainer.setOutputMarkupId(true);
add(thirdRowContainer);
// ---------------------- details -----------------------
// Object type table (list)
DataView<ResourceObjectTypeDefinitionTypeDto> objectTypeDataView = new DataView<ResourceObjectTypeDefinitionTypeDto>(ID_ROW_OBJECT_TYPE,
objectTypeProvider, UserProfileStorage.DEFAULT_PAGING_SIZE) {
@Override
protected void populateItem(final Item<ResourceObjectTypeDefinitionTypeDto> item) {
final ResourceObjectTypeDefinitionTypeDto objectType = item.getModelObject();
AjaxSubmitLink link = new AjaxSubmitLink(ID_LINK_OBJECT_TYPE) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
editObjectTypePerformed(target, objectType);
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
target.add(parentPage.getFeedbackPanel());
}
};
item.add(link);
Label label = new Label(ID_NAME_OBJECT_TYPE, createObjectTypeDisplayModel(objectType));
label.setOutputMarkupId(true);
link.add(label);
AjaxLink delete = new AjaxLink(ID_BUTTON_DELETE_OBJECT_TYPE) {
@Override
public void onClick(AjaxRequestTarget target) {
deleteObjectTypePerformed(target, objectType);
}
};
parentPage.addEditingVisibleBehavior(delete);
link.add(delete);
item.add(AttributeModifier.replace("class", new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
return isSelected(item.getModelObject()) ? "success" : null;
}
}));
}
};
objectTypesTable.add(objectTypeDataView);
NavigatorPanel navigator = new NavigatorPanel(ID_PAGING_OBJECT_TYPE, objectTypeDataView, true);
navigator.setOutputMarkupPlaceholderTag(true);
navigator.setOutputMarkupId(true);
add(navigator);
AjaxSubmitLink add = new AjaxSubmitLink(ID_BUTTON_ADD_OBJECT_TYPE) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
addObjectTypePerformed(target);
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
target.add(parentPage.getFeedbackPanel());
}
};
parentPage.addEditingVisibleBehavior(add);
add(add);
initObjectTypeEditor(objectTypeEditor);
}
@Override
protected void onConfigure() {
super.onConfigure();
if (!isAnySelected()) {
insertEmptyThirdRow();
}
}
private IModel<String> createObjectTypeDisplayModel(final ResourceObjectTypeDefinitionTypeDto objectType){
return new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
StringBuilder sb = new StringBuilder();
if (objectType != null) {
ResourceObjectTypeDefinitionType object = objectType.getObjectType();
sb.append(object.getDisplayName() != null ? object.getDisplayName() + " " : "");
addKindAndIntent(sb, object.getKind(), object.getIntent());
sb.append(" -> ");
sb.append(object.getObjectClass() != null ? object.getObjectClass().getLocalPart() : "");
}
return sb.toString();
}
};
}
static void addKindAndIntent(StringBuilder sb, ShadowKindType kind, String intent) {
sb.append("(");
sb.append(ResourceTypeUtil.fillDefault(kind));
sb.append(", ");
sb.append(ResourceTypeUtil.fillDefault(intent));
sb.append(")");
}
private void initObjectTypeEditor(WebMarkupContainer editor){
Label editorLabel = new Label(ID_EDITOR_NAME, new AbstractReadOnlyModel<Object>() {
@Override
public String getObject() {
ResourceObjectTypeDefinitionTypeDto selected = schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto();
return selected != null ? selected.getObjectType().getDisplayName() : "";
}
});
editorLabel.setOutputMarkupId(true);
editor.add(editorLabel);
DropDownChoice editorKind = new DropDownChoice<>(ID_EDITOR_KIND,
new PropertyModel<ShadowKindType>(schemaHandlingDtoModel, getExpression(ResourceObjectTypeDefinitionType.F_KIND)),
WebComponentUtil.createReadonlyModelFromEnum(ShadowKindType.class),
new EnumChoiceRenderer<ShadowKindType>(this));
editorKind.add(new UpdateNamesBehaviour());
parentPage.addEditingEnabledBehavior(editorKind);
editor.add(editorKind);
TextField editorIntent = new TextField<>(ID_EDITOR_INTENT, new PropertyModel<String>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_INTENT)));
editorIntent.add(new UpdateNamesBehaviour());
parentPage.addEditingEnabledBehavior(editorIntent);
editor.add(editorIntent);
TextField editorDisplayName = new TextField<>(ID_EDITOR_DISPLAY_NAME, new PropertyModel<String>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_DISPLAY_NAME)));
editorDisplayName.add(new UpdateNamesBehaviour());
parentPage.addEditingEnabledBehavior(editorDisplayName);
editor.add(editorDisplayName);
TextArea editorDescription = new TextArea<>(ID_EDITOR_DESCRIPTION, new PropertyModel<String>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_DESCRIPTION)));
parentPage.addEditingEnabledBehavior(editorDescription);
editor.add(editorDescription);
final CheckBox editorDefault = new CheckBox(ID_EDITOR_DEFAULT, new PropertyModel<Boolean>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_DEFAULT)));
editorDefault.add(new EmptyOnChangeAjaxFormUpdatingBehavior() {
@Override
protected void onUpdate(AjaxRequestTarget target) {
Boolean newValue = editorDefault.getModelObject();
if (Boolean.TRUE.equals(newValue)) {
SchemaHandlingDto dto = schemaHandlingDtoModel.getObject();
ResourceObjectTypeDefinitionTypeDto selected = dto.getSelectedObjectTypeDto();
ShadowKindType selectedKind = fillDefault(selected.getObjectType().getKind());
for (ResourceObjectTypeDefinitionTypeDto currentObjectTypeDto : dto.getObjectTypeDtoList()) {
ShadowKindType currentKind = fillDefault(currentObjectTypeDto.getObjectType().getKind());
if (currentObjectTypeDto != selected && currentKind == selectedKind
&& Boolean.TRUE.equals(currentObjectTypeDto.getObjectType().isDefault())) {
currentObjectTypeDto.getObjectType().setDefault(false);
}
}
}
parentPage.refreshIssues(target);
}
});
parentPage.addEditingEnabledBehavior(editorDefault);
editor.add(editorDefault);
AjaxSubmitLink editorDependency = new AjaxSubmitLink(ID_EDITOR_BUTTON_DEPENDENCY) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
dependencyEditPerformed(target);
}
};
addDisabledClassModifier(editorDependency);
editor.add(editorDependency);
AutoCompleteSettings autoCompleteSettings = new AutoCompleteSettings();
autoCompleteSettings.setShowListOnEmptyInput(true);
autoCompleteSettings.setMaxHeightInPx(200);
AutoCompleteTextField<String> editorObjectClass = new AutoCompleteTextField<String>(ID_EDITOR_OBJECT_CLASS,
new PropertyModel<String>(schemaHandlingDtoModel, SchemaHandlingDto.F_OBJECT_CLASS_NAME), autoCompleteSettings) {
@Override
protected Iterator<String> getChoices(String input) {
return getObjectClassChoices(input);
}
};
editorObjectClass.add(new UpdateNamesBehaviour());
editorObjectClass.add(createObjectClassValidator(new AbstractReadOnlyModel<List<QName>>() {
@Override
public List<QName> getObject() {
return schemaHandlingDtoModel.getObject().getObjectClassList();
}
}));
parentPage.addEditingEnabledBehavior(editorObjectClass);
editorObjectClass.setConvertEmptyInputStringToNull(true);
editor.add(editorObjectClass);
MultiValueTextEditPanel editorAttributes = new MultiValueTextEditPanel<ResourceAttributeDefinitionType>(ID_EDITOR_ATTRIBUTES,
new PropertyModel<List<ResourceAttributeDefinitionType>>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_ATTRIBUTE)),
new PropertyModel<ResourceAttributeDefinitionType>(schemaHandlingDtoModel, SchemaHandlingDto.F_SELECTED_ATTRIBUTE), false, true,
parentPage.getReadOnlyModel()) {
@Override
protected IModel<String> createTextModel(final IModel<ResourceAttributeDefinitionType> model) {
return new Model<String>() {
@Override
public String getObject() {
if (model == null || model.getObject() == null) {
return null;
}
ResourceAttributeDefinitionType attribute = model.getObject();
return formatItemInfo(attribute, attribute.getRef(), attribute.getDisplayName(), attribute.getInbound(), attribute.getOutbound());
}
};
}
@Override
protected ResourceAttributeDefinitionType createNewEmptyItem(){
return createEmptyAttributeObject();
}
@Override
protected void performAddValueHook(AjaxRequestTarget target, ResourceAttributeDefinitionType added) {
parentPage.refreshIssues(target);
}
@Override
protected void editPerformed(AjaxRequestTarget target, ResourceAttributeDefinitionType object){
editAttributePerformed(target, object);
}
@Override
protected boolean buttonsDisabled(){
return !isAnySelected();
}
@Override
protected void performRemoveValueHook(AjaxRequestTarget target, ListItem<ResourceAttributeDefinitionType> item) {
resetThirdRowContainer(target);
parentPage.refreshIssues(target);
}
};
editorAttributes.setOutputMarkupId(true);
editor.add(editorAttributes);
MultiValueTextEditPanel editorAssociations = new MultiValueTextEditPanel<ResourceObjectAssociationType>(ID_EDITOR_ASSOCIATIONS,
new PropertyModel<List<ResourceObjectAssociationType>>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_ASSOCIATION)),
new PropertyModel<ResourceObjectAssociationType>(schemaHandlingDtoModel, SchemaHandlingDto.F_SELECTED_ASSOCIATION),
false, true, parentPage.getReadOnlyModel()) {
@Override
protected IModel<String> createTextModel(final IModel<ResourceObjectAssociationType> model) {
return new Model<String>() {
@Override
public String getObject() {
ResourceObjectAssociationType association = model.getObject();
if (association == null) {
return null;
}
return formatItemInfo(association, association.getRef(), association.getDisplayName(), association.getInbound(), association.getOutbound());
}
};
}
@Override
protected ResourceObjectAssociationType createNewEmptyItem() {
return createEmptyAssociationObject();
}
@Override
protected void performAddValueHook(AjaxRequestTarget target, ResourceObjectAssociationType added) {
parentPage.refreshIssues(target);
}
@Override
protected void editPerformed(AjaxRequestTarget target, ResourceObjectAssociationType object){
editAssociationPerformed(target, object);
}
@Override
protected boolean buttonsDisabled(){
return !isAnySelected();
}
@Override
protected void performRemoveValueHook(AjaxRequestTarget target, ListItem<ResourceObjectAssociationType> item) {
resetThirdRowContainer(target);
parentPage.refreshIssues(target);
}
};
editorAssociations.setOutputMarkupId(true);
editor.add(editorAssociations);
// DropDownChoice editorAssignmentPolicyRef = new DropDownChoice<>(ID_EDITOR_ASSIGNMENT_POLICY,
// new PropertyModel<AssignmentPolicyEnforcementType>(schemaHandlingDtoModel,
// getExpression(ResourceObjectTypeDefinitionType.F_ASSIGNMENT_POLICY_ENFORCEMENT)),
// WebComponentUtil.createReadonlyModelFromEnum(AssignmentPolicyEnforcementType.class),
// new EnumChoiceRenderer<AssignmentPolicyEnforcementType>(this));
// parentPage.addEditingEnabledBehavior(editorAssignmentPolicyRef);
// editor.add(editorAssignmentPolicyRef);
AjaxSubmitLink editorIteration = new AjaxSubmitLink(ID_EDITOR_BUTTON_ITERATION) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
iterationEditPerformed(target);
}
};
addDisabledClassModifier(editorIteration);
editor.add(editorIteration);
AjaxSubmitLink editorProtected = new AjaxSubmitLink(ID_EDITOR_BUTTON_PROTECTED) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
protectedEditPerformed(target);
}
};
addDisabledClassModifier(editorProtected);
editor.add(editorProtected);
AjaxSubmitLink editorActivation = new AjaxSubmitLink(ID_EDITOR_BUTTON_ACTIVATION) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
activationEditPerformed(target);
}
};
addDisabledClassModifier(editorActivation);
editor.add(editorActivation);
AjaxSubmitLink editorCredentials = new AjaxSubmitLink(ID_EDITOR_BUTTON_CREDENTIALS) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
credentialsEditPerformed(target);
}
};
addDisabledClassModifier(editorCredentials);
editor.add(editorCredentials);
Label kindTooltip = new Label(ID_T_KIND);
kindTooltip.add(new InfoTooltipBehavior());
editor.add(kindTooltip);
Label intentTooltip = new Label(ID_T_INTENT);
intentTooltip.add(new InfoTooltipBehavior());
editor.add(intentTooltip);
Label defaultTooltip = new Label(ID_T_DEFAULT);
defaultTooltip.add(new InfoTooltipBehavior());
editor.add(defaultTooltip);
Label dependencyTooltip = new Label(ID_T_DEPENDENCY);
dependencyTooltip.add(new InfoTooltipBehavior());
editor.add(dependencyTooltip);
Label objectClassTooltip = new Label(ID_T_OBJECT_CLASS);
objectClassTooltip.add(new InfoTooltipBehavior());
editor.add(objectClassTooltip);
Label attributesTooltip = new Label(ID_T_ATTRIBUTES);
attributesTooltip.add(new InfoTooltipBehavior());
editor.add(attributesTooltip);
Label associationsTooltip = new Label(ID_T_ASSOCIATIONS);
associationsTooltip.add(new InfoTooltipBehavior());
editor.add(associationsTooltip);
Label assignmentPolicyRefTooltip = new Label(ID_T_ASSIGNMENT_POLICY_REF);
assignmentPolicyRefTooltip.add(new InfoTooltipBehavior());
editor.add(assignmentPolicyRefTooltip);
Label iterationTooltip = new Label(ID_T_ITERATION);
iterationTooltip.add(new InfoTooltipBehavior());
editor.add(iterationTooltip);
Label protectedTooltip = new Label(ID_T_PROTECTED);
protectedTooltip.add(new InfoTooltipBehavior());
editor.add(protectedTooltip);
Label activationTooltip = new Label(ID_T_ACTIVATION);
activationTooltip.add(new InfoTooltipBehavior());
editor.add(activationTooltip);
Label credentialsTooltip = new Label(ID_T_CREDENTIALS);
credentialsTooltip.add(new InfoTooltipBehavior());
editor.add(credentialsTooltip);
}
private String formatItemInfo(ResourceItemDefinitionType item, ItemPathType ref, String displayName, List<MappingType> inbounds,
MappingType outbound) {
StringBuilder sb = new StringBuilder();
if (ref != null && !ref.getItemPath().isEmpty()) {
QName name = ItemPathUtil.getOnlySegmentQNameRobust(ref);
if (name != null) {
String prefix = SchemaConstants.NS_ICF_SCHEMA.equals(name.getNamespaceURI()) ? "icfs" : "ri";
sb.append(prefix);
sb.append(": ");
sb.append(name.getLocalPart());
}
} else {
sb.append("-");
}
String duplicateInfo = getDuplicateInfo(item);
if (duplicateInfo != null) {
sb.append(" (").append(duplicateInfo).append(")");
}
if (displayName != null) {
sb.append(" (").append(displayName).append(")");
}
if (!inbounds.isEmpty()) {
sb.append(" | ");
sb.append(getString("SchemaHandlingStep.in", ""));
boolean first = true;
for (MappingType inbound : inbounds) {
if (inbound != null && inbound.getTarget() != null) {
if (first) first = false; else sb.append(", ");
sb.append(formatPath(inbound.getTarget().getPath()));
}
}
}
if (outbound != null) {
sb.append(" | ").append(getString("SchemaHandlingStep.out")).append(": ");
boolean first = true;
for (VariableBindingDefinitionType source : outbound.getSource()) {
if (source != null) {
if (first) first = false; else sb.append(", ");
sb.append(formatPath(source.getPath()));
}
}
}
return sb.toString();
}
// FIXME brutally hacked for now
private String formatPath(ItemPathType path) {
String rv = String.valueOf(path);
rv = StringUtils.removeStart(rv, "$user/");
rv = StringUtils.removeStart(rv, "$c:user/");
rv = StringUtils.removeStart(rv, "$focus/");
rv = StringUtils.removeStart(rv, "$c:focus/");
rv = StringUtils.removeStart(rv, "extension/");
rv = StringUtils.removeStart(rv, "c:extension/");
return rv;
}
private String getDuplicateInfo(ResourceItemDefinitionType item) {
ResourceObjectTypeDefinitionTypeDto selectedObjectTypeDto = schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto();
if (selectedObjectTypeDto == null) {
return null; // shouldn't occur
}
ResourceObjectTypeDefinitionType selectedObjectType = selectedObjectTypeDto.getObjectType();
List<ItemRefinedDefinitionType> existingItems = new ArrayList<>();
existingItems.addAll(selectedObjectType.getAttribute());
existingItems.addAll(selectedObjectType.getAssociation());
QName name = ItemPathUtil.getOnlySegmentQNameRobust(item.getRef());
int count = 0, position = 0;
for (ItemRefinedDefinitionType existingItem : existingItems) {
QName existingName = ItemPathUtil.getOnlySegmentQNameRobust(existingItem.getRef());
if (QNameUtil.match(name, existingName)) {
count++;
}
if (item == existingItem) {
position = count;
}
}
if (count == 1) {
return null;
}
return getString("SchemaHandlingStep.dup", position);
}
@NotNull
private String getExpression(QName property) {
return SchemaHandlingDto.F_SELECTED_OBJECT_TYPE_DTO + ".objectType." + property.getLocalPart();
}
private Iterator<String> getObjectClassChoices(String input) {
List<QName> resourceObjectClassList = schemaHandlingDtoModel.getObject().getObjectClassList();
List<String> choices = new ArrayList<>(AUTO_COMPLETE_LIST_SIZE);
if(Strings.isEmpty(input)){
for(QName q: resourceObjectClassList){
choices.add(q.getLocalPart());
if(choices.size() == AUTO_COMPLETE_LIST_SIZE){
break;
}
}
return choices.iterator();
}
for(QName q: resourceObjectClassList){
if(q.getLocalPart().toLowerCase().startsWith(input.toLowerCase())){
choices.add(q.getLocalPart());
if(choices.size() == AUTO_COMPLETE_LIST_SIZE){
break;
}
}
}
return choices.iterator();
}
private void addDisabledClassModifier(Component component){
component.add(new AttributeAppender("class", new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
if(!isAnySelected()){
return " disabled";
}
return null;
}
}));
}
private Component getObjectListTable(){
return get(ID_ROWS);
}
private Component getObjectTypeEditor(){
return get(ID_OBJECT_TYPE_EDITOR);
}
public Component getAttributeList() {
return get(createComponentPath(ID_OBJECT_TYPE_EDITOR, ID_EDITOR_ATTRIBUTES));
}
public Component getAssociationList() {
return get(createComponentPath(ID_OBJECT_TYPE_EDITOR, ID_EDITOR_ASSOCIATIONS));
}
private Component getThirdRowContainer(){
return get(ID_THIRD_ROW_CONTAINER);
}
private Component getNavigator(){
return get(ID_PAGING_OBJECT_TYPE);
}
private void resetSelected(){
schemaHandlingDtoModel.getObject().setSelectedObjectTypeDto(null);
}
private void insertEmptyThirdRow(){
getThirdRowContainer().replaceWith(new WebMarkupContainer(ID_THIRD_ROW_CONTAINER));
}
private void dependencyEditPerformed(AjaxRequestTarget target){
WebMarkupContainer newContainer = new ResourceDependencyEditor(ID_THIRD_ROW_CONTAINER,
new PropertyModel<List<ResourceObjectTypeDependencyType>>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_DEPENDENCY)), parentPage);
getThirdRowContainer().replaceWith(newContainer);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR), parentPage.getFeedbackPanel());
resetSelections(target);
}
private void resetThirdRowContainer(AjaxRequestTarget target) {
insertEmptyThirdRow();
target.add(getThirdRowContainer());
resetSelections(target);
}
private void resetSelections(AjaxRequestTarget target) {
SchemaHandlingDto dto = schemaHandlingDtoModel.getObject();
if (dto.getSelectedAssociation() != null) {
dto.setSelectedAssociation(null);
target.add(getAssociationList());
}
if (dto.getSelectedAttribute() != null) {
dto.setSelectedAttribute(null);
target.add(getAttributeList());
}
}
private void iterationEditPerformed(AjaxRequestTarget target){
WebMarkupContainer newContainer = new ResourceIterationEditor(ID_THIRD_ROW_CONTAINER,
new PropertyModel<IterationSpecificationType>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_ITERATION)), parentPage);
getThirdRowContainer().replaceWith(newContainer);
resetSelections(target);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR), parentPage.getFeedbackPanel());
}
private void protectedEditPerformed(AjaxRequestTarget target) {
WebMarkupContainer newContainer = new ResourceProtectedEditor(ID_THIRD_ROW_CONTAINER,
new PropertyModel<List<ResourceObjectPatternType>>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_PROTECTED)), parentPage);
getThirdRowContainer().replaceWith(newContainer);
resetSelections(target);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR), parentPage.getFeedbackPanel());
}
private void activationEditPerformed(AjaxRequestTarget target){
WebMarkupContainer newContainer = new ResourceActivationEditor(ID_THIRD_ROW_CONTAINER,
new PropertyModel<ResourceActivationDefinitionType>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_ACTIVATION)), parentPage.getReadOnlyModel());
getThirdRowContainer().replaceWith(newContainer);
resetSelections(target);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR), parentPage.getFeedbackPanel());
}
private void credentialsEditPerformed(AjaxRequestTarget target){
WebMarkupContainer newContainer = new ResourceCredentialsEditor(ID_THIRD_ROW_CONTAINER,
new PropertyModel<ResourceCredentialsDefinitionType>(schemaHandlingDtoModel,
getExpression(ResourceObjectTypeDefinitionType.F_CREDENTIALS)), parentPage);
getThirdRowContainer().replaceWith(newContainer);
resetSelections(target);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR), parentPage.getFeedbackPanel());
}
private void editAttributePerformed(AjaxRequestTarget target, final ResourceAttributeDefinitionType object) {
resetSelections(target);
if (schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto() != null && schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto().getObjectType().getObjectClass() != null) {
schemaHandlingDtoModel.getObject().setSelectedAttribute(object);
WebMarkupContainer newContainer = new ResourceAttributeEditor(ID_THIRD_ROW_CONTAINER, new Model<>(object),
schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto().getObjectType(), resourceModel.getObject(), this, parentPage.getReadOnlyModel());
getThirdRowContainer().replaceWith(newContainer);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR));
} else {
warn(getString("SchemaHandlingStep.message.selectObjectClassAttr"));
getThirdRowContainer().replaceWith(new WebMarkupContainer(ID_THIRD_ROW_CONTAINER));
target.add(parentPage.getFeedbackPanel(), get(ID_OBJECT_TYPE_EDITOR), getThirdRowContainer());
}
}
private void editAssociationPerformed(AjaxRequestTarget target, ResourceObjectAssociationType object) {
resetSelections(target);
if (schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto() != null && schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto().getObjectType().getObjectClass() != null) {
schemaHandlingDtoModel.getObject().setSelectedAssociation(object);
WebMarkupContainer newContainer = new ResourceAssociationEditor(ID_THIRD_ROW_CONTAINER, new Model<>(object),
schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto().getObjectType(), resourceModel.getObject(), this, parentPage.getReadOnlyModel());
getThirdRowContainer().replaceWith(newContainer);
target.add(getThirdRowContainer(), get(ID_OBJECT_TYPE_EDITOR), parentPage.getFeedbackPanel());
} else {
warn(getString("SchemaHandlingStep.message.selectObjectClassAss"));
getThirdRowContainer().replaceWith(new WebMarkupContainer(ID_THIRD_ROW_CONTAINER));
target.add(parentPage.getFeedbackPanel(), get(ID_OBJECT_TYPE_EDITOR), getThirdRowContainer());
}
}
@Override
public void applyState() {
parentPage.refreshIssues(null);
if (parentPage.isReadOnly() || !isComplete()) {
return;
}
savePerformed();
insertEmptyThirdRow(); // otherwise the original 3rd column would be displayed after returning to the page
// (but without 2nd column)
}
private void savePerformed() {
PrismObject<ResourceType> oldResource;
@NotNull PrismObject<ResourceType> newResource = resourceModel.getObject();
Task task = parentPage.createSimpleTask(OPERATION_SAVE_SCHEMA_HANDLING);
OperationResult result = task.getResult();
ModelService modelService = parentPage.getModelService();
ObjectDelta delta;
boolean saved = false;
removeEmptyContainers(newResource);
try {
oldResource = WebModelServiceUtils.loadObject(ResourceType.class, newResource.getOid(), parentPage, task, result);
if (oldResource == null) {
throw new IllegalStateException("No resource to apply schema handling to");
}
delta = parentPage.computeDiff(oldResource, newResource);
if (!delta.isEmpty()) {
parentPage.logDelta(delta);
@SuppressWarnings("unchecked")
Collection<ObjectDelta<? extends ObjectType>> deltas = WebComponentUtil.createDeltaCollection(delta);
modelService.executeChanges(deltas, null, parentPage.createSimpleTask(OPERATION_SAVE_SCHEMA_HANDLING), result);
parentPage.resetModels();
saved = true;
}
} catch (RuntimeException|CommonException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't save schema handling", e);
result.recordFatalError(getString("SchemaHandlingStep.message.saveError", e));
} finally {
result.computeStatusIfUnknown();
}
setResult(result);
if (parentPage.showSaveResultInPage(saved, result)) {
parentPage.showResult(result);
}
}
private void editObjectTypePerformed(AjaxRequestTarget target, ResourceObjectTypeDefinitionTypeDto objectType){
boolean wasAnySelected = isAnySelected();
schemaHandlingDtoModel.getObject().setSelectedObjectTypeDto(objectType);
resetSelections(target);
insertEmptyThirdRow();
if (wasAnySelected) {
target.add(getObjectListTable(), getNavigator(), getObjectTypeEditor(), getThirdRowContainer());
} else {
target.add(this);
}
}
private void deleteObjectTypePerformed(AjaxRequestTarget target, ResourceObjectTypeDefinitionTypeDto objectType) {
ResourceObjectTypeDefinitionType realObjectType = objectType.getObjectType();
resourceModel.getObject().asObjectable().getSchemaHandling().getObjectType().remove(realObjectType);
if (isSelected(objectType)) {
resetSelected();
resetThirdRowContainer(target);
}
ArrayList<ResourceObjectTypeDefinitionTypeDto> list = (ArrayList<ResourceObjectTypeDefinitionTypeDto>) schemaHandlingDtoModel.getObject().getObjectTypeDtoList();
list.remove(objectType);
if (list.isEmpty()) {
resetThirdRowContainer(target);
}
target.add(getObjectTypeEditor(), getObjectListTable(), getNavigator());
parentPage.refreshIssues(target);
}
private boolean isSelected(@NotNull ResourceObjectTypeDefinitionTypeDto objectType) {
return schemaHandlingDtoModel.getObject().getSelectedObjectTypeDto() == objectType;
}
private void addObjectTypePerformed(AjaxRequestTarget target) {
ResourceObjectTypeDefinitionType objectType = new ResourceObjectTypeDefinitionType();
//objectType.setDisplayName(generateName(getString("SchemaHandlingStep.label.newObjectType")));
ResourceObjectTypeDefinitionTypeDto dto = new ResourceObjectTypeDefinitionTypeDto(objectType);
if (schemaHandlingDtoModel.getObject().getObjectTypeDtoList().isEmpty()) {
objectType.setDefault(true);
}
resetSelected();
schemaHandlingDtoModel.getObject().setSelectedObjectTypeDto(dto);
schemaHandlingDtoModel.getObject().getObjectTypeDtoList().add(dto);
getOrCreateSchemaHandling().getObjectType().add(objectType);
insertEmptyThirdRow();
resetSelections(target);
target.add(this);
parentPage.refreshIssues(target);
}
private String generateName(String prefix) {
List<String> existing = new ArrayList<>();
for (ResourceObjectTypeDefinitionTypeDto objectTypeDto : schemaHandlingDtoModel.getObject().getObjectTypeDtoList()) {
CollectionUtils.addIgnoreNull(existing, objectTypeDto.getObjectType().getDisplayName());
}
return generateName(existing, prefix);
}
static String generateName(List<String> existing, String prefix) {
for (int i = 1;; i++) {
String candidate = prefix + (i > 1 ? " "+i : "");
if (!existing.contains(candidate)) {
return candidate;
}
}
}
@NotNull
private SchemaHandlingType getOrCreateSchemaHandling() {
PrismObject<ResourceType> resource = resourceModel.getObject();
try {
resource.findOrCreateContainer(ResourceType.F_SCHEMA_HANDLING);
} catch (SchemaException e) {
throw new IllegalStateException("Couldn't find/create schemaHandling container: " + e.getMessage(), e);
}
return resource.asObjectable().getSchemaHandling();
}
private void removeEmptyContainers(@NotNull PrismObject<ResourceType> resourcePrism) {
ResourceType resource = resourcePrism.asObjectable();
if (resource.getSchemaHandling() != null) {
SchemaHandlingType schemaHandling = resource.getSchemaHandling();
for (ResourceObjectTypeDefinitionType objectType: schemaHandling.getObjectType()) {
//Clear empty/invalid containers from attributes
List<ResourceAttributeDefinitionType> newAttributeList = new ArrayList<>();
newAttributeList.addAll(objectType.getAttribute());
for (ResourceAttributeDefinitionType attribute : objectType.getAttribute()) {
if (attribute.getRef() == null) {
newAttributeList.remove(attribute);
}
}
objectType.getAttribute().clear();
objectType.getAttribute().addAll(newAttributeList);
for (ResourceAttributeDefinitionType attr : objectType.getAttribute()) {
List<MappingType> newInbounds = clearEmptyMappings(attr.getInbound());
attr.getInbound().clear();
attr.getInbound().addAll(newInbounds);
}
//Clear empty/invalid containers from associations
List<ResourceObjectAssociationType> newAssociationList = new ArrayList<>();
newAssociationList.addAll(objectType.getAssociation());
for (ResourceObjectAssociationType association : objectType.getAssociation()) {
if (association.getKind() == null) {
newAssociationList.remove(association);
}
}
objectType.getAssociation().clear();
objectType.getAssociation().addAll(newAssociationList);
for(ResourceObjectAssociationType association: objectType.getAssociation()){
List<MappingType> newInbounds = clearEmptyMappings(association.getInbound());
association.getInbound().clear();
association.getInbound().addAll(newInbounds);
}
prepareActivation(objectType.getActivation());
// protected accounts
List<ResourceObjectPatternType> newProtectedList = new ArrayList<>();
for (ResourceObjectPatternType protectedObject : objectType.getProtected()) {
if (protectedObject.getFilter() != null && !protectedObject.getFilter().containsFilterClause()) {
// we know that we lose description for empty filters ... but such filters (description + no clause) cause problems in prisms
protectedObject.setFilter(null);
}
if (protectedObject.getName() != null || protectedObject.getUid() != null || protectedObject.getFilter() != null) {
newProtectedList.add(protectedObject);
}
}
replace(objectType.getProtected(), newProtectedList);
// iterator expressions
if (objectType.getIteration() != null) {
IterationSpecificationType it = objectType.getIteration();
if (ExpressionUtil.isEmpty(it.getTokenExpression())) {
it.setTokenExpression(null);
}
if (ExpressionUtil.isEmpty(it.getPreIterationCondition())) {
it.setPreIterationCondition(null);
}
if (ExpressionUtil.isEmpty(it.getPostIterationCondition())) {
it.setPostIterationCondition(null);
}
}
}
}
}
private <T> void replace(List<T> list, List<T> newList) {
list.clear();
list.addAll(newList);
}
private List<MappingType> clearEmptyMappings(List<MappingType> list){
List<MappingType> newList = new ArrayList<>();
for(MappingType mapping: list){
if(!WizardUtil.isEmptyMapping(mapping)){
newList.add(mapping);
}
}
return newList;
}
private void prepareActivation(ResourceActivationDefinitionType activation){
if (activation == null) {
return;
}
if (activation.getAdministrativeStatus() != null) {
ResourceBidirectionalMappingType administrativeStatus = activation.getAdministrativeStatus();
List<MappingType> inbounds = administrativeStatus.getInbound();
List<MappingType> outbounds = administrativeStatus.getOutbound();
List<MappingType> newInbounds = prepareActivationMappings(inbounds,
ResourceActivationEditor.ADM_STATUS_IN_SOURCE_DEFAULT, ResourceActivationEditor.ADM_STATUS_IN_TARGET_DEFAULT);
administrativeStatus.getInbound().clear();
administrativeStatus.getInbound().addAll(newInbounds);
List<MappingType> newOutbounds = prepareActivationMappings(outbounds,
ResourceActivationEditor.ADM_STATUS_OUT_SOURCE_DEFAULT, ResourceActivationEditor.ADM_STATUS_OUT_TARGET_DEFAULT);
administrativeStatus.getOutbound().clear();
administrativeStatus.getOutbound().addAll(newOutbounds);
if(isBidirectionalMappingEmpty(administrativeStatus)){
activation.setAdministrativeStatus(null);
}
}
if (activation.getValidTo() != null) {
ResourceBidirectionalMappingType validTo = activation.getValidTo();
List<MappingType> inbounds = validTo.getInbound();
List<MappingType> outbounds = validTo.getOutbound();
List<MappingType> newInbounds = prepareActivationMappings(inbounds,
ResourceActivationEditor.VALID_TO_IN_SOURCE_DEFAULT, ResourceActivationEditor.VALID_TO_IN_TARGET_DEFAULT);
validTo.getInbound().clear();
validTo.getInbound().addAll(newInbounds);
List<MappingType> newOutbounds = prepareActivationMappings(outbounds,
ResourceActivationEditor.VALID_TO_OUT_SOURCE_DEFAULT, ResourceActivationEditor.VALID_TO_OUT_TARGET_DEFAULT);
validTo.getOutbound().clear();
validTo.getOutbound().addAll(newOutbounds);
if (isBidirectionalMappingEmpty(validTo)) {
activation.setValidTo(null);
}
}
if (activation.getValidFrom() != null) {
ResourceBidirectionalMappingType validFrom = activation.getValidFrom();
List<MappingType> inbounds = validFrom.getInbound();
List<MappingType> outbounds = validFrom.getOutbound();
List<MappingType> newInbounds = prepareActivationMappings(inbounds,
ResourceActivationEditor.VALID_FROM_IN_SOURCE_DEFAULT, ResourceActivationEditor.VALID_FROM_IN_TARGET_DEFAULT);
validFrom.getInbound().clear();
validFrom.getInbound().addAll(newInbounds);
List<MappingType> newOutbounds = prepareActivationMappings(outbounds,
ResourceActivationEditor.VALID_FROM_OUT_SOURCE_DEFAULT, ResourceActivationEditor.VALID_FROM_OUT_TARGET_DEFAULT);
validFrom.getOutbound().clear();
validFrom.getOutbound().addAll(newOutbounds);
if (isBidirectionalMappingEmpty(validFrom)) {
activation.setValidFrom(null);
}
}
if (activation.getExistence() != null) {
ResourceBidirectionalMappingType existence = activation.getExistence();
List<MappingType> inbounds = existence.getInbound();
List<MappingType> newInbounds = new ArrayList<>();
for(MappingType inbound: inbounds){
if(WizardUtil.isEmptyMapping(inbound)){
continue;
}
if(inbound.getSource().size() == 1 && compareItemPath(inbound.getSource().get(0).getPath(), ResourceActivationEditor.EXISTENCE_DEFAULT_SOURCE)){
newInbounds.add(new MappingType());
continue;
}
newInbounds.add(inbound);
}
existence.getInbound().clear();
existence.getInbound().addAll(newInbounds);
List<MappingType> outbounds = existence.getOutbound();
List<MappingType> newOutbounds = new ArrayList<>();
for(MappingType outbound: outbounds){
if(!WizardUtil.isEmptyMapping(outbound)){
newOutbounds.add(outbound);
}
}
existence.getOutbound().clear();
existence.getOutbound().addAll(newOutbounds);
if(isBidirectionalMappingEmpty(existence)){
activation.setExistence(null);
}
}
}
private boolean isBidirectionalMappingEmpty(ResourceBidirectionalMappingType mapping){
return mapping.getFetchStrategy() == null && mapping.getInbound().isEmpty() && mapping.getOutbound().isEmpty();
}
private List<MappingType> prepareActivationMappings(List<MappingType> list, String defaultSource, String defaultTarget){
List<MappingType> newMappings = new ArrayList<>();
for(MappingType mapping: list){
if(WizardUtil.isEmptyMapping(mapping)){
continue;
}
if(mapping.getTarget() != null){
if(compareItemPath(mapping.getTarget().getPath(), defaultTarget)){
mapping.setTarget(null);
}
}
if(mapping.getSource().size() == 1){
if(compareItemPath(mapping.getSource().get(0).getPath(), defaultSource)){
mapping.getSource().clear();
}
}
newMappings.add(mapping);
}
return newMappings;
}
private boolean compareItemPath(ItemPathType itemPath, String comparePath){
if(itemPath != null && itemPath.getItemPath() != null){
if(comparePath.equals(itemPath.getItemPath().toString())){
return true;
}
}
return false;
}
private ResourceObjectAssociationType createEmptyAssociationObject(){
ResourceObjectAssociationType association = new ResourceObjectAssociationType();
association.setTolerant(true);
return association;
}
private ResourceAttributeDefinitionType createEmptyAttributeObject(){
ResourceAttributeDefinitionType attribute = new ResourceAttributeDefinitionType();
attribute.setTolerant(true);
return attribute;
}
private class UpdateNamesBehaviour extends EmptyOnChangeAjaxFormUpdatingBehavior {
@Override
protected void onUpdate(AjaxRequestTarget target) {
target.add(getObjectListTable(), getObjectTypeEditor().get(ID_EDITOR_NAME));
parentPage.refreshIssues(target);
}
}
}