org.sigmah.shared.dto.element.AbstractDefaultFlexibleElementDTO.java Source code

Java tutorial

Introduction

Here is the source code for org.sigmah.shared.dto.element.AbstractDefaultFlexibleElementDTO.java

Source

package org.sigmah.shared.dto.element;
/*
 * #%L
 * Sigmah
 * %%
 * Copyright (C) 2010 - 2016 URD
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */

import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.DatePickerEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.TextField;

import java.util.Date;
import java.util.List;

import org.sigmah.client.dispatch.CommandResultHandler;
import org.sigmah.client.i18n.I18N;
import org.sigmah.client.util.DateUtils;
import org.sigmah.shared.command.GetCountries;
import org.sigmah.shared.command.GetCountry;
import org.sigmah.shared.command.result.ListResult;
import org.sigmah.shared.dto.country.CountryDTO;
import org.sigmah.shared.dto.element.event.RequiredValueEvent;
import org.sigmah.shared.dto.element.event.ValueEvent;
import org.sigmah.shared.dto.orgunit.OrgUnitDTO;

import com.allen_sauer.gwt.log.client.Log;

public abstract class AbstractDefaultFlexibleElementDTO extends FlexibleElementDTO {
    protected static final String EMPTY_VALUE = "-";

    protected transient ListStore<CountryDTO> countriesStore;
    protected transient ListStore<OrgUnitDTO> orgUnitsStore;

    protected void fireEvents(String value, boolean isValueOn) {

        Log.debug("raw Value is : " + value + "  isValueOn is :" + isValueOn);

        handlerManager.fireEvent(new ValueEvent(this, value));

        // Required element ?
        if (getValidates()) {
            handlerManager.fireEvent(new RequiredValueEvent(isValueOn));
        }
    }

    /**
     * Create a text field to represent a default flexible element.
     *
     * @param length     The max length of the field.
     * @param allowBlank If the field allow blank value.
     * @return The text field.
     */
    protected TextField<String> createStringField(final int length, final boolean allowBlank) {

        final TextField<String> textField = new TextField<String>();
        textField.setAllowBlank(allowBlank);

        // Sets the max length.
        textField.setMaxLength(length);

        // Adds the listeners.
        textField.addListener(Events.OnKeyUp, new Listener<BaseEvent>() {

            @Override
            public void handleEvent(BaseEvent be) {

                String rawValue = textField.getValue();

                if (rawValue == null) {
                    rawValue = "";
                }

                // The value is valid if it contains at least one non-blank
                // character.
                final boolean isValueOn = !rawValue.trim().equals("") && !(rawValue.length() > length);

                if (!(!allowBlank && !isValueOn)) {
                    fireEvents(rawValue, isValueOn);
                }
            }
        });

        return textField;
    }

    /**
     * Create a date field to represent a default flexible element.
     *
     * @param allowBlank If the field allow blank value.
     * @return The date field.
     */
    protected DateField createDateField(final boolean allowBlank) {

        final DateTimeFormat dateFormat = DateUtils.DATE_SHORT;

        // Creates a date field which manages date picker selections and
        // manual selections.
        final DateField dateField = new DateField();
        dateField.getPropertyEditor().setFormat(dateFormat);
        dateField.setEditable(allowBlank);
        dateField.setAllowBlank(allowBlank);
        preferredWidth = FlexibleElementDTO.NUMBER_FIELD_WIDTH;

        // Adds the listeners.

        dateField.getDatePicker().addListener(Events.Select, new Listener<DatePickerEvent>() {

            @Override
            public void handleEvent(DatePickerEvent be) {

                // The date is saved as a timestamp.
                final String rawValue = String.valueOf(be.getDate().getTime());
                // The date picker always returns a valid date.
                final boolean isValueOn = true;

                fireEvents(rawValue, isValueOn);
            }
        });

        dateField.addListener(Events.OnKeyUp, new Listener<BaseEvent>() {

            @Override
            public void handleEvent(BaseEvent be) {

                final Date date = dateField.getValue();

                // The date is invalid, fires only a required event to
                // invalidate some previously valid date.
                if (date == null) {

                    // Required element ?
                    if (getValidates()) {
                        handlerManager.fireEvent(new RequiredValueEvent(false));
                    }

                    if (allowBlank) {
                        fireEvents("", false);
                    }

                    return;
                }

                // The date is saved as a timestamp.
                final String rawValue = String.valueOf(date.getTime());
                // The date is valid here.
                final boolean isValueOn = true;

                if (!(!allowBlank && !isValueOn)) {
                    fireEvents(rawValue, isValueOn);
                }
            }
        });

        return dateField;
    }

    /**
     * Create a number field to represent a default flexible element.
     *
     * @param allowBlank If the field allow blank value.
     * @return The number field.
     */
    protected NumberField createNumberField(final boolean allowBlank) {

        final NumberField numberField = new NumberField();
        numberField.setAllowDecimals(true);
        numberField.setAllowNegative(false);
        numberField.setAllowBlank(allowBlank);
        preferredWidth = FlexibleElementDTO.NUMBER_FIELD_WIDTH;

        // Decimal format
        final NumberFormat format = NumberFormat.getDecimalFormat();
        numberField.setFormat(format);

        // Sets the min value.
        final Number minValue = 0.0;
        numberField.setMinValue(minValue);

        return numberField;
    }

    /**
     * Create a label field to represent a default flexible element.
     *
     * @return The label field.
     */
    protected LabelField createLabelField() {

        final LabelField labelField = new LabelField();
        labelField.setLabelSeparator(":");

        return labelField;
    }

    /**
     * Create a label field and sets its value.
     *
     * @param value Value to set.
     * @return The label field.
     */
    protected LabelField createLabelField(String value) {
        final LabelField labelField = createLabelField();
        labelField.setValue(value);
        return labelField;
    }

    /**
     * Creates a text field. <br/>
     * This method is shared between the code and the title fields.
     *
     * @param label   Label of the field.
     * @param value   Current value.
     * @param size    Maximum number of characters allowed.
     * @param enabled <code>true</code> if the field must be editable, <code>false</code> otherwise.
     * @return A new text field.
     */
    protected Field<?> buildTextField(String label, String value, int size, boolean enabled, boolean allowBlank) {
        final Field<?> field;

        // Builds the field and sets its value.
        if (enabled) {
            final TextField<String> textField = createStringField(size, allowBlank);
            textField.setValue(value);
            field = textField;

        } else {
            field = createLabelField(value);
        }

        // Sets the field label.
        setLabel(label);
        field.setFieldLabel(getLabel());

        return field;
    }

    protected Field<?> buildParagraphField(final String label, final String value, final int size,
            final boolean enabled, boolean allowBlank) {

        // Builds the field and sets its value.
        final TextField<String> textArea = new TextArea();
        textArea.addStyleName("flexibility-textarea");
        textArea.setAllowBlank(allowBlank);

        // Sets the max length.
        textArea.setMaxLength(size);
        textArea.setToolTip(I18N.MESSAGES.flexibleElementTextAreaTextLength(String.valueOf(size)));

        // Adds the listeners.
        textArea.addListener(Events.OnKeyUp, new Listener<BaseEvent>() {

            @Override
            public void handleEvent(BaseEvent be) {

                String rawValue = textArea.getValue();

                if (rawValue == null) {
                    rawValue = "";
                }

                // The value is valid if it contains at least one
                // non-blank character.
                final boolean isValueOn = !rawValue.trim().equals("") && !(rawValue.length() > size);

                fireEvents(rawValue, isValueOn);
            }
        });

        // Sets the value to the field.
        if (value != null) {
            textArea.setValue(value);
        }

        setLabel(label);
        textArea.setFieldLabel(getLabel());
        textArea.setEnabled(enabled);

        return textArea;
    }

    /**
     * Creates a date field. <br/>
     * This method is shared between the start date and the end date fields.
     *
     * @param label   Label of the field.
     * @param value   Current value.
     * @param enabled <code>true</code> if the field must be editable, <code>false</code> otherwise.
     * @return A new date field.
     */
    protected Field<?> buildDateField(String label, Date value, boolean enabled) {
        final Field<?> field;

        // Builds the field and sets its value.
        if (enabled) {
            final DateField dateField = createDateField(true);
            dateField.setValue(value);
            field = dateField;

        } else {
            final LabelField labelField = createLabelField();
            if (value != null) {
                labelField.setValue(DateUtils.DATE_SHORT.format(value));
            } else {
                labelField.setValue(EMPTY_VALUE);
            }
            field = labelField;
        }

        // Sets the field label.
        setLabel(label);
        field.setFieldLabel(getLabel());

        return field;
    }

    protected Component buildCountryField(String country, boolean enabled) {
        final Field<?> field = buildCountryField((CountryDTO) null, enabled);

        final int countryId = Integer.parseInt(country);

        dispatch.execute(new GetCountry(countryId), new CommandResultHandler<CountryDTO>() {

            @Override
            public void onCommandFailure(final Throwable caught) {
            }

            @Override
            public void onCommandSuccess(final CountryDTO result) {
                // BUGFIX #694: Disable events on first set.
                field.enableEvents(false);

                if (field instanceof ComboBox) {
                    ((ComboBox<CountryDTO>) field).setValue(result);

                } else if (field instanceof LabelField) {
                    ((LabelField) field).setValue(result.getName());
                }

                field.enableEvents(true);
            }

        });

        return field;
    }

    protected Field<?> buildCountryField(CountryDTO country, boolean enabled) {
        final Field<?> field;

        if (enabled) {
            final ComboBox<CountryDTO> comboBox = new ComboBox<CountryDTO>();
            comboBox.setEmptyText(I18N.CONSTANTS.flexibleElementDefaultSelectCountry());

            ensureCountryStore();

            comboBox.setStore(countriesStore);
            comboBox.setDisplayField(CountryDTO.NAME);
            comboBox.setValueField(CountryDTO.ID);
            comboBox.setTriggerAction(ComboBox.TriggerAction.ALL);
            comboBox.setEditable(true);
            comboBox.setAllowBlank(true);

            // Listens to the selection changes.
            comboBox.addSelectionChangedListener(new SelectionChangedListener<CountryDTO>() {

                @Override
                public void selectionChanged(SelectionChangedEvent<CountryDTO> se) {

                    String value = null;
                    final boolean isValueOn;

                    // Gets the selected choice.
                    final CountryDTO choice = se.getSelectedItem();

                    // Checks if the choice isn't the default empty choice.
                    isValueOn = choice != null && choice.getId() != null && choice.getId() != -1;

                    if (choice != null) {
                        value = String.valueOf(choice.getId());
                    }

                    if (value != null) {
                        // Fires value change event.
                        handlerManager.fireEvent(new ValueEvent(AbstractDefaultFlexibleElementDTO.this, value));
                    }

                    // Required element ?
                    if (getValidates()) {
                        handlerManager.fireEvent(new RequiredValueEvent(isValueOn));
                    }
                }
            });

            if (country != null) {
                comboBox.setValue(country);
            }

            field = comboBox;

        } else /* not enabled */ {

            final LabelField labelField = createLabelField();

            if (country == null) {
                labelField.setValue(EMPTY_VALUE);
            } else {
                labelField.setValue(country.getName());
            }

            field = labelField;
        }

        // Sets the field label.
        setLabel(I18N.CONSTANTS.projectCountry());
        field.setFieldLabel(getLabel());

        return field;
    }

    /**
     * Creates the organization unit field.
     *
     * @param orgUnitId ID of the organization unit.
     * @param enabled <code>true</code> if the field must be editable, <code>false</code> otherwise.
     * @return The organization unit field.
     */
    protected Field<?> buildOrgUnitField(String label, String orgUnitId, boolean enabled) {
        return buildOrgUnitField(label, Integer.parseInt(orgUnitId), enabled);
    }

    /**
     * Creates the organization unit field.
     *
     * @param label Label of the field
     * @param orgUnitId ID of the organization unit.
     * @param enabled <code>true</code> if the field must be editable, <code>false</code> otherwise.
     * @return The organization unit field.
     */
    protected Field<?> buildOrgUnitField(String label, Integer orgUnitId, boolean enabled) {
        final Field<?> field;

        if (enabled) {

            final ComboBox<OrgUnitDTO> comboBox = new ComboBox<OrgUnitDTO>();

            ensureOrgUnitStore();

            comboBox.setStore(orgUnitsStore);
            comboBox.setDisplayField(OrgUnitDTO.COMPLETE_NAME);
            comboBox.setValueField(OrgUnitDTO.ID);
            comboBox.setTriggerAction(ComboBox.TriggerAction.ALL);
            comboBox.setEditable(true);
            comboBox.setAllowBlank(true);

            // BUGFIX #694 : SelectionChangedEvent listener is added AFTER
            // setting the initial value to avoid sending a
            // SelectionChangedEvent during view initialization.

            // Loading the current value from the cache.
            cache.getOrganizationCache().get(orgUnitId, new AsyncCallback<OrgUnitDTO>() {

                @Override
                public void onFailure(final Throwable caught) {
                    // Not found.

                    // Listens to the selection changes.
                    addOrgUnitSelectionChangedListener(comboBox);
                }

                @Override
                public void onSuccess(final OrgUnitDTO result) {
                    comboBox.setValue(result);

                    // Listens to the selection changes.
                    addOrgUnitSelectionChangedListener(comboBox);
                }

            });

            field = comboBox;

        } else {
            // Builds the field and sets its value.
            final LabelField labelField = createLabelField();

            cache.getOrganizationCache().get(orgUnitId, new AsyncCallback<OrgUnitDTO>() {

                @Override
                public void onSuccess(final OrgUnitDTO result) {
                    // BUGFIX: Issue #718
                    if (result != null) {
                        labelField.setValue(result.getName() + " - " + result.getFullName());
                    } else {
                        labelField.setValue(EMPTY_VALUE);
                    }
                }

                @Override
                public void onFailure(final Throwable caught) {
                    labelField.setValue(EMPTY_VALUE);
                }
            });

            field = labelField;
        }

        // Sets the field label.
        setLabel(label);
        field.setFieldLabel(getLabel());

        return field;
    }

    /**
     * Creates the organization unit field.
     *
     * @param orgUnit Organization unit.
     * @param enabled <code>true</code> if the field must be editable, <code>false</code> otherwise.
     * @return The organization unit field.
     */
    protected Field<?> buildOrgUnitField(String label, OrgUnitDTO orgUnit, boolean enabled) {
        final Field<?> field;

        if (enabled) {

            final ComboBox<OrgUnitDTO> comboBox = new ComboBox<OrgUnitDTO>();

            ensureOrgUnitStore();

            comboBox.setStore(orgUnitsStore);
            comboBox.setDisplayField(OrgUnitDTO.COMPLETE_NAME);
            comboBox.setValueField(OrgUnitDTO.ID);
            comboBox.setTriggerAction(ComboBox.TriggerAction.ALL);
            comboBox.setEditable(true);
            comboBox.setAllowBlank(true);

            // BUGFIX #694 : SelectionChangedEvent listener is added AFTER
            // setting the initial value to avoid sending a
            // SelectionChangedEvent during view initialization.
            comboBox.setValue(orgUnit);

            // Listens to the selection changes.
            addOrgUnitSelectionChangedListener(comboBox);

            field = comboBox;

        } else {
            // Builds the field and sets its value.
            final LabelField labelField = createLabelField();
            if (orgUnit != null) {
                labelField.setValue(orgUnit.getName() + " - " + orgUnit.getFullName());
            } else {
                labelField.setValue(EMPTY_VALUE);
            }

            field = labelField;
        }

        // Sets the field label.
        setLabel(label);
        field.setFieldLabel(getLabel());

        return field;
    }

    protected String formatCountry(String value) {
        if (cache != null) {
            try {
                final CountryDTO c = cache.getCountryCache().get(Integer.valueOf(value));
                if (c != null) {
                    return c.getName();
                } else {
                    return '#' + value;
                }
            } catch (NumberFormatException e) {
                return "";
            }
        } else {
            return '#' + value;
        }
    }

    protected String formatDate(String value) {
        try {
            final long time = Long.parseLong(value);
            final Date date = new Date(time);

            // Using a shared instance to allow parsing from client and server side.
            final com.google.gwt.i18n.shared.DateTimeFormat formatter = DateUtils.SHARED_DATE_SHORT;
            return formatter.format(date);

        } catch (NumberFormatException e) {
            return "";
        }
    }

    protected String formatText(String value) {
        return value.replace("\n", "<br>");
    }

    protected String formatOrgUnit(String value) {
        if (cache != null) {
            try {
                final OrgUnitDTO o = cache.getOrganizationCache().get(Integer.valueOf(value));
                if (o != null) {
                    return o.getName() + " - " + o.getFullName();
                } else {
                    return '#' + value;
                }
            } catch (NumberFormatException e) {
                return "";
            }
        } else {
            return '#' + value;
        }
    }

    /**
     * Creates and populates the shared country store if needed.
     */
    protected void ensureCountryStore() {
        if (countriesStore == null) {
            countriesStore = new ListStore<CountryDTO>();
        }

        // if country store is empty
        if (countriesStore.getCount() == 0) {

            if (cache != null) {
                cache.getCountryCache().get(new AsyncCallback<List<CountryDTO>>() {

                    @Override
                    public void onFailure(Throwable e) {
                        Log.error("[getComponent] Error while getting countries list.", e);
                    }

                    @Override
                    public void onSuccess(List<CountryDTO> result) {
                        // Fills the store.
                        countriesStore.add(result);
                    }
                });

            } else /* cache is null */ {
                dispatch.execute(new GetCountries(CountryDTO.Mode.BASE),
                        new CommandResultHandler<ListResult<CountryDTO>>() {

                            @Override
                            protected void onCommandSuccess(final ListResult<CountryDTO> result) {
                                // Fills the store.
                                countriesStore.add(result.getData());
                            }

                            @Override
                            protected void onCommandFailure(final Throwable caught) {
                                Log.error("[getComponent] Error while getting countries list.", caught);
                            }
                        });
            }
        }
    }

    /**
     * Creates and populates the shared org unit store if needed.
     */
    protected void ensureOrgUnitStore() {
        if (orgUnitsStore == null) {
            orgUnitsStore = new ListStore<OrgUnitDTO>();
        }

        if (orgUnitsStore.getCount() == 0) {
            cache.getOrganizationCache().get(new AsyncCallback<OrgUnitDTO>() {

                @Override
                public void onFailure(Throwable e) {
                    Log.error("[getComponent] Error while getting users info.", e);
                }

                @Override
                public void onSuccess(OrgUnitDTO result) {
                    // Fills the store.
                    recursiveFillOrgUnitsList(result);
                }
            });
        }
    }

    /**
     * Fills recursively the org unit store from the given root org unit.
     *
     * @param root
     *          The root org unit.
     */
    private void recursiveFillOrgUnitsList(OrgUnitDTO root) {

        if (root.isCanContainProjects()) {
            orgUnitsStore.add(root);
        }

        for (final OrgUnitDTO child : root.getChildrenOrgUnits()) {
            recursiveFillOrgUnitsList(child);
        }
    }

    /**
     * Adds the selection changed listener to the given orgunit combobox.
     *
     * @param comboBox Combo box to configure.
     */
    protected abstract void addOrgUnitSelectionChangedListener(final ComboBox<OrgUnitDTO> comboBox);
}