de.decidr.ui.view.windows.FieldBuilder.java Source code

Java tutorial

Introduction

Here is the source code for de.decidr.ui.view.windows.FieldBuilder.java

Source

/*
 * The DecidR Development Team licenses this file to you 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 de.decidr.ui.view.windows;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import com.vaadin.data.validator.IntegerValidator;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;

import de.decidr.model.schema.decidrtypes.ContentType;
import de.decidr.model.schema.decidrtypes.TBoolean;
import de.decidr.model.schema.decidrtypes.TInformation;
import de.decidr.model.schema.decidrtypes.TTaskItem;
import de.decidr.model.schema.dwdl.DWDLSimpleVariableType;
import de.decidr.ui.controller.UploadAction;
import de.decidr.ui.data.FloatValidator;
import de.decidr.ui.main.DecidrUI;
import de.decidr.ui.view.UploadComponent;

/**
 * Private interface used by {@link WorkItemWindowBuilder}.<br>
 * Each DWDL variable type is mapped to a class building UI controls for that
 * specific type.
 * 
 * XXX styleguide - perhaps we should name the builder classes XXXBuilder? ~dh
 * 
 * @author wf
 */
interface FieldBuilder {
    /**
     * Create an editor component for the given taskItem.<br>
     * 
     * @param taskItem that the control should edit.
     * @param value that the control should initially display.<br>Should correspond
     *              to the according value in taskItem, but is given for convenience.
     * @return Implementations must return an instance of either {@link Field}
     *         or {@link AbstractComponent}.
     */
    public Object createControl(TTaskItem taskItem, String value);
}

class StringField implements FieldBuilder {
    @Override
    public Field createControl(TTaskItem taskItem, String value) {
        TextField field = new TextField(taskItem.getLabel());
        field.setImmediate(true);
        field.setValue(value);
        return field;
    }
}

class BooleanField implements FieldBuilder {
    @Override
    public Field createControl(TTaskItem taskItem, String value) {
        CheckBox field = new CheckBox(taskItem.getLabel());
        field.setValue(value.equals(TBoolean.YES.value()));
        return field;
    }
}

class DateField implements FieldBuilder {
    @Override
    public Field createControl(TTaskItem taskItem, String value) {
        com.vaadin.ui.DateField field = new com.vaadin.ui.DateField(taskItem.getLabel());
        Date date = new Date();
        /*
         * FIXME magic string ~dh
         */
        SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd");
        dfs.setTimeZone(TimeZone.getTimeZone("UTC"));
        if (!value.isEmpty()) {
            try {
                date = dfs.parse(value);
            } catch (ParseException e) {
                /*
                 * TODO Better error handling
                 */
                DecidrUI.getCurrent().getMainWindow().addWindow(new TransactionErrorDialogComponent(e));
            }
        }
        field.setValue(date);
        return field;
    }
}

class FloatField implements FieldBuilder {
    @Override
    public Field createControl(TTaskItem taskItem, String value) {
        TextField field = new TextField(taskItem.getLabel());
        field.addValidator(new FloatValidator("Please enter a valid float"));
        field.setImmediate(true);
        field.setValue(value);
        return field;
    }
}

class IntegerField implements FieldBuilder {
    @Override
    public Field createControl(TTaskItem taskItem, String value) {
        TextField field = new TextField(taskItem.getLabel());
        field.addValidator(new IntegerValidator("Please enter an Integer!"));
        field.setImmediate(true);

        field.setValue(value);
        return field;
    }
}

class TimeField implements FieldBuilder {
    @Override
    public Field createControl(TTaskItem taskItem, String value) {
        /*
         * FIXME implement
         */
        TextField field = new TextField("Das ist fr Decidr+");
        field.setReadOnly(true);
        return field;
    }
}

class FileUploadComponent implements FieldBuilder {
    @Override
    public Component createControl(TTaskItem taskItem, String value) {

        String fileId = value;
        Long id;
        if (fileId.equals("")) {
            id = null;
        } else {
            id = Long.valueOf(fileId);
        }
        UploadComponent upload = new UploadComponent(id, new UploadAction());
        return upload;
    }
}

/**
 * Used by {@link WorkItemWindow} to build form controls from WorkItems.<br>
 * Actual instantiation is passed down to a private class, based on the
 * WorkItem's type.
 * 
 * @author wf
 */
public class WorkItemWindowBuilder {
    private Map<DWDLSimpleVariableType, FieldBuilder> fieldBuilders;

    public WorkItemWindowBuilder() {
        fieldBuilders = new HashMap<DWDLSimpleVariableType, FieldBuilder>();
        fieldBuilders.put(DWDLSimpleVariableType.STRING, new StringField());
        fieldBuilders.put(DWDLSimpleVariableType.BOOLEAN, new BooleanField());
        fieldBuilders.put(DWDLSimpleVariableType.DATE, new DateField());
        fieldBuilders.put(DWDLSimpleVariableType.FLOAT, new FloatField());
        fieldBuilders.put(DWDLSimpleVariableType.INTEGER, new IntegerField());
        fieldBuilders.put(DWDLSimpleVariableType.TIME, new TimeField());
        fieldBuilders.put(DWDLSimpleVariableType.ANY_URI, new FileUploadComponent());
    }

    /**
     * Create and add a Vaadin control to edit the given {@link TTaskItem}.<br>
     * 
     * @param form to manipulate (most not be <code>null</code>).<br>
     *        In particular, this method may call either addField, or
     *        addComponent of the form's corresponding Layout.
     * @param taskItem that the new control should edit.
     *        (must not be <code>null</code>.
     */
    public void addControl(Form form, TTaskItem taskItem) {
        /*
         * FIXME are you sure this is really a W3C DOM String? Since JAXB maps
         * xsd:anySimpleType to "Object", I'd expect this to be an instance of
         * String, Boolean, Integer, etc. Please beat me to death with a pointy
         * burning stick if I broke the class with my changes ~dh
         */
        String value = taskItem.getValue() == null ? "" : taskItem.getValue().toString();
        FieldBuilder fieldBuilder = fieldBuilders.get(taskItem.getType());
        if (fieldBuilder != null) {
            Object control = fieldBuilder.createControl(taskItem, value);
            if (control instanceof Field) {
                ((Field) control).setDescription(taskItem.getHint());
                form.addField(taskItem.getName(), (Field) control);
            } else {
                ((AbstractComponent) control).setDescription(taskItem.getHint());
                form.getLayout().addComponent((Component) control);
            }
        } else {
            // TODO Better error handling
            form.addField("error", new TextField("Unknown field type: " + taskItem.getType()));
        }
    }

    /**
     * Adds a pretty label for a read-only information item to the given form.
     * 
     * @param form
     *            form to manipulate (must not be <code>null</code>)
     * @param information
     *            read-only information item to turn into a control (must not be
     *            <code>null</code>)
     */
    public void addControl(Form form, TInformation information) {
        if (form == null) {
            throw new IllegalArgumentException("Form is null");
        }
        if (information == null) {
            throw new IllegalArgumentException("Information is null");
        }

        Label label = new Label();
        /*
         * An information item may contain plain text or XHTML, we change the
         * content mode of our label accordingly.
         */
        label.setContentMode(information.getContent().getType().equals(ContentType.XHTML) ? Label.CONTENT_XHTML
                : Label.CONTENT_TEXT);
        label.setValue(information.getContent().getValue());
        /*
         * TODO there's a high chance that this label will look like crap when
         * slapped into the default layout. Remove this marker if it looks
         * pretty ~dh
         */
        form.getLayout().addComponent(label);
    }

}