/** * Copyright (C) 2012 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.jbpm.formModeler.core.config; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.UUID; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.jbpm.formModeler.api.model.DataFieldHolder; import org.jbpm.formModeler.api.model.DataHolder; import org.jbpm.formModeler.api.model.Field; import org.jbpm.formModeler.api.model.FieldType; import org.jbpm.formModeler.api.model.Form; import org.jbpm.formModeler.api.model.wrappers.I18nSet; import org.jbpm.formModeler.core.config.builders.dataHolder.DataHolderBuildConfig; import org.jbpm.formModeler.service.LocaleManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped public class FormManagerImpl implements FormManager { private Logger log = LoggerFactory.getLogger(FormManager.class); @Inject private DataHolderManager dataHolderManager; @Inject protected FieldTypeManager fieldTypeManager; @Inject private LocaleManager localeManager; private HashSet<Form> forms = new HashSet<Form>(); /** * Get all forms by subject. */ public List<Form> getFormsBySubject(String subject) throws Exception { if (subject == null) subject = ""; List<Form> result = new ArrayList<Form>(); for (Form form : forms) { if (subject.equals(form.getSubject())) result.add(form); } return result; } /** * Get all forms by subject and name. */ public List<Form> getFormsBySubjectAndName(String subject, String name) { if (subject == null) subject = ""; if (name == null) name = ""; List<Form> result = new ArrayList<Form>(); for (Form form : forms) { if (subject.equals(form.getSubject()) && name.equals(form.getName())) result.add(form); } return result; } public Form[] getAllForms() { return forms.toArray(new Form[forms.size()]); } /** * Get the form to edit a form field depending on its type * * @param fieldType for which we want to edit * @return a form suitable for editing it, or null if none fits * @throws Exception in case of error */ public Form getFormForFieldEdition(FieldType fieldType) { String code = fieldType.getCode(); if (code == null) { logError("Found field type without code."); } else { // Literal search for(Form form : forms) { if (form.getName() != null && form.getName().equals(code)) return form; } // Pattern search for (Form form : forms) { if (form.getName() != null) { try { if (code.matches(form.getName())) { return form; } } catch (Exception pse) { //Ignore wrong patterns } } } } Form defaultForm = null; List<Form> defaultForms = getFormsBySubjectAndName(Field.class.getName(), "default"); if (!defaultForms.isEmpty()) defaultForm = defaultForms.get(0); return defaultForm; } /** * Get form by id * * @param id Form id * @return a form by id */ public Form getFormById(final Long id) { for (Form form : forms) { if (form.getId().equals(id)) return form; } return null; } public Form createForm(String name) { return createForm("", name, Form.DISPLAY_MODE_DEFAULT, new Long(FORMSTATUS_NORMAL)); } /** * Create an empty form with given parameters * * @param subject Form subject * @param name Form name * @param displayMode Form display mode * @param status Form status * @return The created form * @throws Exception in case of error */ public Form createForm(String subject, String name, String displayMode, Long status) { final Form pForm = new Form(); pForm.setId(generateUniqueId()); pForm.setSubject(subject); pForm.setDisplayMode(displayMode); pForm.setStatus(status); pForm.setName(name); pForm.setFormFields(new HashSet()); return pForm; } @Override public Field addFieldToForm(Form pForm, FieldType fieldType) throws Exception { return addFieldToForm(pForm, "", fieldType, new I18nSet()); } /** * Adds a field to a form. * * @param pForm Form to be modified * @param fieldName Field name to create * @param fieldType Field type * @throws Exception in case of error */ @Override public Field addFieldToForm(Form pForm, String fieldName, FieldType fieldType, I18nSet label) { return addFieldToForm(pForm, fieldName, fieldType,label, "", ""); } /** * Adds a field to a form. * * @param pForm Form to be modified * @param fieldName Field name to create * @param fieldType Field type * @throws Exception in case of error */ @Override public Field addFieldToForm(Form pForm, String fieldName, FieldType fieldType, I18nSet label, String inputBindingString, String outputBindingString) { return addFieldToForm(pForm, fieldName, fieldType, null, label, inputBindingString, outputBindingString); } @Override public Field addFieldToForm(Form form, String fieldName, FieldType fieldType, String fieldClass, I18nSet label, String inputBinding, String outputBinding) { synchronized (form.getSynchronizationObject()) { Set<Field> fields = form.getFormFields(); if (fieldName != null && !fieldName.isEmpty()) { for (Field field : fields) { if (fieldName.equals(field.getFieldName())) { logError("Cannot add field with name " + fieldName + " as it already exists."); return field; } } } Field field = new Field(); field.setId(generateUniqueId()); if (StringUtils.isEmpty(fieldName)) fieldName = field.getId().toString(); field.setFieldName(fieldName); field.setFieldRequired(Boolean.FALSE); field.setReadonly(Boolean.FALSE); field.setFieldType(fieldType); field.setInputBinding(inputBinding); field.setOutputBinding(outputBinding); field.setForm(form); field.setPosition(form.getFormFields().size()); if (label != null) field.setLabel(label); if (label != null && !"Separator".equals(fieldType.getCode()) && !"HTMLLabel".equals(fieldType.getCode())){ //default label String currentLang = localeManager.getDefaultLang(); if(label.getValue(currentLang)==null) { label.setValue(currentLang, fieldType.getCode()+field.getPosition()); } field.setLabel(label); } form.getFormFields().add(field); return field; } } protected static Long generateUniqueId() { UUID idOne = UUID.randomUUID(); String str = "" + idOne; int uid = str.hashCode(); String filterStr = "" + uid; str = filterStr.replaceAll("-", ""); return Long.decode(str); } public void promoteField(Form pForm, int fieldPos, int destPos, boolean groupWithPrevious, boolean nextFieldGrouped) throws Exception { synchronized (pForm.getSynchronizationObject()) { final List<Field> fields = new ArrayList(pForm.getFormFields()); Collections.sort(fields, new Field.Comparator()); boolean wasGrouped = false; for (Field formField : fields) { int position = formField.getPosition(); if (position == fieldPos) { formField.setPosition(destPos); wasGrouped = Boolean.TRUE.equals(formField.getGroupWithPrevious()); formField.setGroupWithPrevious(Boolean.valueOf(groupWithPrevious)); } else if (position >= destPos && position < fieldPos) { formField.setPosition(formField.getPosition() + 1); if (position == destPos && !Boolean.TRUE.equals(formField.getGroupWithPrevious())) formField.setGroupWithPrevious(Boolean.valueOf(nextFieldGrouped)); } else if (position == fieldPos + 1 && Boolean.TRUE.equals(formField.getGroupWithPrevious())) formField.setGroupWithPrevious(Boolean.valueOf(wasGrouped)); } } } public void degradeField(Form pForm, int fieldPos, int destPos, boolean groupWithPrevious, boolean nextFieldGrouped) throws Exception { synchronized (pForm.getSynchronizationObject()) { final List<Field> fields = new ArrayList(pForm.getFormFields()); Collections.sort(fields, new Field.Comparator()); boolean wasGrouped = false; for (Field formField : fields) { int position = formField.getPosition(); if (position == fieldPos) { formField.setPosition(destPos); wasGrouped = Boolean.TRUE.equals(formField.getGroupWithPrevious()); formField.setGroupWithPrevious(Boolean.valueOf(groupWithPrevious)); } else if (position <= destPos && position > fieldPos) { formField.setPosition(formField.getPosition() - 1); if (position == fieldPos + 1 && Boolean.TRUE.equals(formField.getGroupWithPrevious())) formField.setGroupWithPrevious(Boolean.valueOf(wasGrouped)); } else if (position == destPos + 1 && !Boolean.TRUE.equals(formField.getGroupWithPrevious())) formField.setGroupWithPrevious(Boolean.valueOf(nextFieldGrouped)); } } } /** * Moves a field to the specified position * * @param pForm form to modify * @param fieldPos original field position * @param destPos destination position * @param groupWithPrevious determines that the field must be grouped with the previous field * @param nextFieldGrouped determines that the next field must be grouped with the modified field * @throws Exception */ public void changeFieldPosition(Form pForm, int fieldPos, int destPos, boolean groupWithPrevious, boolean nextFieldGrouped) throws Exception { synchronized (pForm.getSynchronizationObject()) { final List<Field> fields = new ArrayList(pForm.getFormFields()); Collections.sort(fields, new Field.Comparator()); boolean promote = destPos < fieldPos; boolean checkGroup = false; Boolean wasGrouped = false; for (Field formField : fields) { int position = formField.getPosition(); if (position == fieldPos) { formField.setPosition(destPos); checkGroup = true; wasGrouped = formField.getGroupWithPrevious(); formField.setGroupWithPrevious(Boolean.valueOf(groupWithPrevious)); } else if (promote) { if (position >= destPos && position < fieldPos) { formField.setPosition(formField.getPosition() + 1); if (position == destPos) formField.setGroupWithPrevious(Boolean.valueOf(nextFieldGrouped)); if (checkGroup) { if (formField.getGroupWithPrevious()) { formField.setGroupWithPrevious(wasGrouped); } } } } else { if (position > fieldPos && position <= destPos) { formField.setPosition(formField.getPosition() - 1); if (position == destPos) formField.setGroupWithPrevious(Boolean.valueOf(nextFieldGrouped)); if (checkGroup) { if (formField.getGroupWithPrevious()) { formField.setGroupWithPrevious(wasGrouped); } } } } } } } /** * Moves a field top in a form * * @param pForm form to modify * @param fieldPos field position to move top * @throws Exception in case of error */ public void moveTop(Form pForm, int fieldPos) throws Exception { synchronized (pForm.getSynchronizationObject()) { Set<Field> fields = pForm.getFormFields(); for (Field formField : fields) { if (formField.getPosition() == fieldPos) { formField.setPosition(0); formField.setGroupWithPrevious(Boolean.FALSE); } else if (formField.getPosition() < fieldPos) { formField.setPosition(formField.getPosition() + 1); } } } } /** * Moves a field bottom in a form * * @param pForm form to modify * @param fieldPos field position to move down * @throws Exception in case of error */ public void moveBottom(Form pForm, int fieldPos) throws Exception { synchronized (pForm.getSynchronizationObject()) { Set<Field> fields = pForm.getFormFields(); for (Field formField : fields) { if (formField.getPosition() == fieldPos) { formField.setPosition(fields.size() - 1); formField.setGroupWithPrevious(Boolean.FALSE); } else if (formField.getPosition() > fieldPos) { formField.setPosition(formField.getPosition() - 1); } } } } /** * Moves a field up in a form * * @param pForm form to modify * @param fieldPos field position to move up * @throws Exception in case of error */ public boolean moveUp(Form pForm, int fieldPos) throws Exception { synchronized (pForm.getSynchronizationObject()) { Set<Field> fields = pForm.getFormFields(); if (fieldPos < 1 || fieldPos >= fields.size()) { logError("Cannot move up field in position " + fieldPos); return false; } else { for (Field formField : fields) { if (formField.getPosition() == fieldPos) { formField.setPosition(fieldPos - 1); } else if (formField.getPosition() == fieldPos - 1) { formField.setPosition(fieldPos); } } return true; } } } /** * Moves a field up in a form * * @param pForm form to modify * @param fieldPos field position to move up * @throws Exception in case of error */ public void groupWithPrevious(Form pForm, int fieldPos, boolean value) throws Exception { synchronized (pForm.getSynchronizationObject()) { Set<Field> fields = pForm.getFormFields(); if (fieldPos < 1 || fieldPos >= fields.size()) { logError("Cannot change field in position " + fieldPos); } else { for (Field formField : fields) { if (formField.getPosition() == fieldPos) { formField.setGroupWithPrevious(Boolean.valueOf(value)); } } } } } /** * Moves a field down in a form * * @param pForm form to modify * @param fieldPos field position to move down * @throws Exception in case of error */ public boolean moveDown(Form pForm, int fieldPos) throws Exception { synchronized (pForm.getSynchronizationObject()) { Set<Field> fields = pForm.getFormFields(); if (fieldPos < 0 || fieldPos >= fields.size() - 1) { logError("Cannot move down field in position " + fieldPos); return false; } else { for (Field formField : fields) { if (formField.getPosition() == fieldPos) { formField.setPosition(fieldPos + 1); } else if (formField.getPosition() == fieldPos + 1) { formField.setPosition(fieldPos); } } return true; } } } public void deleteField(Form pForm, int fieldPos) throws Exception { synchronized (pForm.getSynchronizationObject()) { Set fields = pForm.getFormFields(); if (fieldPos < 0 || fieldPos >= fields.size()) { logError("Cannot delete field in position " + fieldPos); } else { for (Iterator iterator = fields.iterator(); iterator.hasNext(); ) { Field formField = (Field) iterator.next(); if (formField.getPosition() == fieldPos) { iterator.remove(); } else if (formField.getPosition() > fieldPos) { formField.setPosition(formField.getPosition() - 1); } } } } } public void saveTemplateForForm(Long formId, String templateContent) throws Exception { Form form = getFormById(formId); form.setFormTemplate(templateContent); } /** * Determine if a form is deleteable, which means it is not in use in other core structures. * * @param form Form to check * @return true if the form is not deleteable. */ public boolean isDeleteable(Form form) { return true; } protected void logWarn(String message) { log.warn(message); } protected void logError(String message) { log.error(message); } @Override public void addDataHolderToForm(Form form, String holderType, String id,String inputId, String outId, String color, String value, String path) throws Exception { DataHolderBuildConfig config = new DataHolderBuildConfig(id, inputId, outId, color, value); config.addAttribute("path", path); addDataHolderToForm(form, dataHolderManager.createDataHolderByType(holderType, config)); } @Override public void addDataHolderToForm(Form form, DataHolder holder) { if (holder != null) form.setDataHolder(holder); } @Override public void removeDataHolderFromForm(Form form, String holderId) { if ((holderId != null)) { form.removeDataHolder(holderId); } } @Override public void addAllDataHolderFieldsToForm(Form form, String holderId) { if (holderId != null) { DataHolder holder = form.getDataHolderById(holderId); addDataHolderFields(form, holder, true); } } @Override public void addAllDataHolderFieldsToForm(Form form, DataHolder holder) { addDataHolderFields(form, holder, false); } protected void addDataHolderFields(Form form, DataHolder holder, boolean existing) { if (holder != null) { if (!existing) { if(form.containsHolder(holder)) return; else form.setDataHolder(holder); } if (!form.containsHolder(holder)) return; Set<DataFieldHolder> holderFields = holder.getFieldHolders(); for (DataFieldHolder dataFieldHolder : holderFields) { if (!form.isFieldBinded(holder, dataFieldHolder.getId())) addDataHolderField(form, dataFieldHolder); } } } @Override public void addDataHolderField(Form form, String holderId, String fieldName) throws Exception { DataHolder holder = form.getDataHolderById(holderId); if (holder != null) { DataFieldHolder field = holder.getDataFieldHolderById(fieldName); if (field != null) addDataHolderField(form, field); } } protected void addDataHolderField(Form form, DataFieldHolder holderField) { I18nSet label = new I18nSet(); String defaultLang = localeManager.getDefaultLang(); DataHolder holder = holderField.getHolder(); String fieldName = holderField.getId(); String dataHolderId = holder.getUniqeId(); label.setValue(defaultLang, fieldName + " (" + dataHolderId + ")"); String inputBinging = holder.getInputBinding(fieldName); String outputBinding = holder.getOuputBinding(fieldName); FieldType fieldType = fieldTypeManager.getTypeByClass(holderField.getClassName(), holderField.getBag()); String fName; if (!holder.canHaveChildren()){ fName = holder.getUniqeId(); }else{ fName = holder.getUniqeId() + "_" + fieldName; } int i = 0; String tmpFName = fName; while(form.getField(tmpFName)!=null){ tmpFName = fName + "_" + i; } fName=tmpFName; Field field = addFieldToForm(form, fName, fieldType, holderField.getClassName(), label, inputBinging, outputBinding); if (!StringUtils.isEmpty(holderField.getBag())) field.setBag(holderField.getBag()); } @Override public void addSystemForm(Form form) { forms.add(form); } }