ru.codeinside.gses.webui.form.EForm.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.gses.webui.form.EForm.java

Source

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2013, MPL CodeInside http://codeinside.ru
 */

package ru.codeinside.gses.webui.form;

import com.vaadin.data.Validator;
import com.vaadin.terminal.StreamResource;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;
import org.apache.commons.lang.StringUtils;
import ru.codeinside.gses.activiti.forms.api.values.FormValue;
import ru.codeinside.gses.activiti.forms.api.values.PropertyValue;
import ru.codeinside.gses.activiti.forms.values.Block;
import ru.codeinside.gses.vaadin.JsonFormIntegration;
import ru.codeinside.gses.webui.ActivitiApp;
import ru.codeinside.gses.webui.form.api.FieldValuesSource;
import ru.codeinside.gses.webui.wizard.ExpandRequired;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

// :
// string
// multiline
// long
// date (+format)
// masked (+format)
// boolean
// enum (+map)
// directory (+service)
// attachment
// - signature
// - smevRequest
// enclosure == attachment
// - smevRequestEnclosure
// - smevResponseEnclosure
// json
final public class EForm extends Form implements AsyncCompletable, ExpandRequired, FieldValuesSource {

    final eform.Form form;
    final Map<String, EField> fields = new LinkedHashMap<String, EField>();

    AsyncCompleter asyncCompleter;
    boolean hasAnyResult;
    JsonFormIntegration integration;
    String lastError;
    Long serial;
    FormValue formValue;

    public EForm(eform.Form form, FormValue formValue) {
        super(new VerticalLayout());
        this.form = form;
        this.formValue = formValue;
        setSizeFull();
        setImmediate(true);
    }

    @Override
    public Field getField(Object propertyId) {
        return fields.get(propertyId);
    }

    @Override
    public void attach() {
        ActivitiApp app = (ActivitiApp) getApplication();
        hasAnyResult = false;

        if (serial == null) {
            serial = app.nextId();
            putFields(formValue.getPropertyValues());
        }

        app.getForms().put(serial, form);

        VerticalLayout layout = (VerticalLayout) getLayout();
        try {
            integration = createIntegration();
            integration.setSizeFull();
            integration.setImmediate(true);
            layout.setSizeFull();
            layout.addComponent(integration);
            layout.setExpandRatio(integration, 1f);
            layout.setImmediate(true);
            integration.setErrorReceiver(new ErrorReceiver());
            integration.setValueReceiver(new ValueReceiver());
        } catch (RuntimeException e) {
            Logger.getLogger(getClass().getName()).log(Level.WARNING,
                    "  ", e);
            layout.addComponent(new Label(
                    "     " + e.getLocalizedMessage()));
        }
        super.attach();
    }

    private void putFields(List<PropertyValue<?>> propertyValues) {
        for (PropertyValue propertyValue : propertyValues) {
            fields.put(propertyValue.getId(), new EField(propertyValue.getId(),
                    form.getProperty(propertyValue.getId()), propertyValue.getNode()));
            if (propertyValue instanceof Block) {
                for (List<PropertyValue<?>> clones : ((Block) propertyValue).getClones()) {
                    putFields(clones);
                }
            }
        }
    }

    @Override
    public void detach() {
        VerticalLayout layout = (VerticalLayout) getLayout();
        if (integration != null) {
            layout.removeAllComponents();
            integration = null;
        }
        if (serial != null) {
            ActivitiApp app = (ActivitiApp) getApplication();
            app.getForms().remove(serial);
        }
        super.detach();
    }

    public List<FormField> getFormFields() {
        return new ArrayList<FormField>(fields.values());
    }

    @Override
    public void commit() throws SourceException, Validator.InvalidValueException {
        if (lastError != null) {
            String msg = " " + lastError;
            lastError = null;
            hasAnyResult = false;
            throw new Validator.InvalidValueException(msg);
        }
        if (!hasAnyResult) {
            throw new Validator.InvalidValueException("  !");
        }
    }

    @Override
    public boolean isAsyncRequiredForComplete(AsyncCompleter asyncCompleter) {
        if (hasAnyResult) {
            return false;
        }
        if (asyncCompleter != null) {
            this.asyncCompleter = asyncCompleter;
        }
        if (integration != null) {
            integration.fireJson();
        }
        return true;
    }

    JsonFormIntegration createIntegration() {
        ActivitiApp app = (ActivitiApp) getApplication();
        String template = JsonForm.loadTemplate(app, formValue.getFormDefinition().getFormKey());
        StreamResource.StreamSource htmlStreamSource = new JsonForm.InMemoryResource(template);
        StreamResource resource = new StreamResource(htmlStreamSource,
                "form-" + serial + "-" + System.currentTimeMillis() + ".html", app);
        resource.setCacheTime(0);
        JsonFormIntegration integration = new JsonFormIntegration();
        integration.setSource(resource);
        integration.setSizeFull();
        integration.setImmediate(true);
        integration.setValidationMode(true);
        return integration;
    }

    @Override
    public Map<String, Object> getFieldValues() {
        Map<String, Object> values = new LinkedHashMap<String, Object>();
        for (EField eField : fields.values()) {
            if (eField.node.isFieldWritable()) {
                values.put(eField.id, eField.getValue());
            }
        }
        return values;
    }

    final class ErrorReceiver implements JsonFormIntegration.Receiver, Serializable {
        @Override
        public void onReceive(String value) {
            hasAnyResult = true;
            lastError = JsonForm.simplifyErrorStack(value);
            asyncCompleter.onComplete(false);
        }
    }

    final class ValueReceiver implements JsonFormIntegration.Receiver, Serializable {
        @Override
        public void onReceive(String value) {
            value = StringUtils.trimToEmpty(value);
            hasAnyResult = Boolean.valueOf(value);
            lastError = null;
            if (hasAnyResult) {
                asyncCompleter.onComplete(true);
            }
        }
    }

}