/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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 org.kie.workbench.common.forms.editor.client.editor; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.annotation.PreDestroy; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.kie.workbench.common.forms.editor.client.editor.events.FormEditorContextRequest; import org.kie.workbench.common.forms.editor.client.editor.events.FormEditorContextResponse; import org.kie.workbench.common.forms.editor.client.editor.rendering.EditorFieldLayoutComponent; import org.kie.workbench.common.forms.editor.model.FormModelerContent; import org.kie.workbench.common.forms.editor.service.shared.FormEditorRenderingContext; import org.kie.workbench.common.forms.fields.shared.fieldTypes.basic.HasPlaceHolder; import org.kie.workbench.common.forms.model.DynamicModel; import org.kie.workbench.common.forms.model.FieldDefinition; import org.kie.workbench.common.forms.model.FormDefinition; import org.kie.workbench.common.forms.service.FieldManager; @Dependent public class FormEditorHelper { public static final String UNBINDED_FIELD_NAME_PREFFIX = "__unbinded_field_"; private FieldManager fieldManager; private Event<FormEditorContextResponse> responseEvent; private ManagedInstance<EditorFieldLayoutComponent> editorFieldLayoutComponents; private FormModelerContent content; private Map<String, FieldDefinition> availableFields = new HashMap<String, FieldDefinition>(); private List<EditorFieldLayoutComponent> fieldLayoutComponents; @Inject public FormEditorHelper(FieldManager fieldManager, Event<FormEditorContextResponse> responseEvent, ManagedInstance<EditorFieldLayoutComponent> editorFieldLayoutComponents) { this.fieldManager = fieldManager; this.responseEvent = responseEvent; this.editorFieldLayoutComponents = editorFieldLayoutComponents; } public FormModelerContent getContent() { return content; } public void initHelper(FormModelerContent content) { this.content = content; if (fieldLayoutComponents != null && !fieldLayoutComponents.isEmpty()) { return; } fieldLayoutComponents = new ArrayList<>(); for (String baseType : fieldManager.getBaseFieldTypes()) { EditorFieldLayoutComponent layoutComponent = editorFieldLayoutComponents.get(); if (layoutComponent != null) { FieldDefinition field = fieldManager.getDefinitionByFieldTypeName(baseType); field.setId(baseType); layoutComponent.init(content.getRenderingContext(), field); layoutComponent.setDisabled(true); fieldLayoutComponents.add(layoutComponent); } } } public FormDefinition getFormDefinition() { return content.getDefinition(); } public void addAvailableFields(List<FieldDefinition> fields) { for (FieldDefinition field : fields) { addAvailableField(field); } } public void addAvailableField(FieldDefinition field) { availableFields.put(field.getId(), field); } public FieldDefinition getDroppedField(String fieldId) { FieldDefinition result = getFormField(fieldId); if (result != null) { responseEvent.fire(new FormEditorContextResponse(getFormDefinition().getId(), result.getId(), this)); } return result; } public FieldDefinition getFormField(String fieldId) { FieldDefinition result = content.getDefinition().getFieldById(fieldId); if (result == null) { result = availableFields.get(fieldId); if (result != null) { availableFields.remove(fieldId); } else { result = fieldManager.getDefinitionByFieldTypeName(fieldId); if (result != null) { result.setName(generateUnbindedFieldName(result)); result.setLabel(result.getFieldType().getTypeName()); if (result instanceof HasPlaceHolder) { ((HasPlaceHolder) result).setPlaceHolder(result.getFieldType().getTypeName()); } } } if (result != null) { content.getDefinition().getFields().add(result); } } return result; } public FieldDefinition removeField(String fieldId, boolean addToAvailables) { Iterator<FieldDefinition> it = content.getDefinition().getFields().iterator(); while (it.hasNext()) { FieldDefinition field = it.next(); if (field.getId().equals(fieldId)) { it.remove(); if (addToAvailables && content.getModelProperties().contains(field.getBinding())) { availableFields.put(field.getId(), field); } return field; } } return null; } public void onFieldRequest(@Observes FormEditorContextRequest request) { if (content == null) { return; } if (request.getFormId().equals(content.getDefinition().getId())) { responseEvent.fire(new FormEditorContextResponse(request.getFormId(), request.getFieldId(), this)); } } public List<String> getCompatibleModelFields(FieldDefinition field) { Collection<String> compatibles = fieldManager.getCompatibleFields(field); Set<String> result = new TreeSet<>(); if (field.getBinding() != null && !field.getBinding().isEmpty()) { result.add(field.getBinding()); } for (String compatibleType : compatibles) { for (FieldDefinition definition : availableFields.values()) { if (definition.getFieldType().getTypeName().equals(compatibleType) && definition.getBinding() != null) { result.add(definition.getBinding()); } } } return new ArrayList<>(result); } public Collection<String> getCompatibleFieldTypes(FieldDefinition field) { return fieldManager.getCompatibleFields(field); } public FieldDefinition switchToField(FieldDefinition originalField, String bindingExpression) { if (content.getDefinition().getFieldByBinding(bindingExpression) != null) { return null; } FieldDefinition resultField = fieldManager.getDefinitionByFieldTypeName(originalField.getFieldType().getTypeName()); if (bindingExpression == null || bindingExpression.equals("")) { resultField.setName(generateUnbindedFieldName(resultField)); } else { // Search if there's an available field with the specified binding for (Iterator<FieldDefinition> it = availableFields.values().iterator(); it.hasNext(); ) { FieldDefinition availableField = it.next(); if (availableField.getBinding().equals(bindingExpression)) { // Check types if we are binding a fields on dynamicModel && change field type if needed if (content.getDefinition().getModel() instanceof DynamicModel && !resultField.getFieldType().equals(availableField.getFieldType())) { resultField = fieldManager.getFieldFromProvider(availableField.getFieldType().getTypeName(), availableField.getFieldTypeInfo()); } resultField.setId(availableField.getId()); resultField.setName(availableField.getName()); resultField.copyFrom(availableField); content.getDefinition().getFields().add(resultField); it.remove(); return resultField; } } } // If we arrive here is because we have a dynamic binding or we are unbinding a field resultField.copyFrom(originalField); resultField.setBinding(bindingExpression); if(resultField.getName() == null) { String name = bindingExpression; if(name == null || name.isEmpty()) { name = generateUnbindedFieldName(resultField); } resultField.setName(name); } content.getDefinition().getFields().add(resultField); return resultField; } public FieldDefinition switchToFieldType(FieldDefinition field, String fieldCode) { FieldDefinition resultDefinition = fieldManager.getFieldFromProvider(fieldCode, field.getFieldTypeInfo()); resultDefinition.copyFrom(field); resultDefinition.setId(field.getId()); resultDefinition.setName(field.getName()); removeField(field.getId(), false); content.getDefinition().getFields().add(resultDefinition); return resultDefinition; } public String generateUnbindedFieldName(FieldDefinition field) { return UNBINDED_FIELD_NAME_PREFFIX + field.getId(); } public List<EditorFieldLayoutComponent> getBaseFieldsDraggables() { return fieldLayoutComponents; } public Map<String, FieldDefinition> getAvailableFields() { return availableFields; } public FormEditorRenderingContext getRenderingContext() { return content.getRenderingContext(); } @PreDestroy public void destroy() { editorFieldLayoutComponents.destroyAll(); } }