view flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java @ 71:987567f31200

Adjusted the return type of the CreateCollectionService and added code to react on Collection changes (like output modes). flys-client/trunk@1573 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 25 Mar 2011 11:51:54 +0000
parents f793d35bfb08
children 9b726350ab07
line wrap: on
line source
package de.intevation.flys.client.client.ui;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;

import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;

import de.intevation.flys.client.shared.model.Artifact;
import de.intevation.flys.client.shared.model.ArtifactDescription;
import de.intevation.flys.client.shared.model.Collection;
import de.intevation.flys.client.shared.model.Data;
import de.intevation.flys.client.shared.model.DataItem;
import de.intevation.flys.client.shared.model.DataList;
import de.intevation.flys.client.shared.model.DefaultData;
import de.intevation.flys.client.shared.model.DefaultDataItem;
import de.intevation.flys.client.shared.model.OutputMode;
import de.intevation.flys.client.shared.model.River;
import de.intevation.flys.client.shared.model.User;

import de.intevation.flys.client.client.Config;
import de.intevation.flys.client.client.FLYS;
import de.intevation.flys.client.client.FLYSMessages;
import de.intevation.flys.client.client.event.HasCollectionChangeHandlers;
import de.intevation.flys.client.client.event.HasParameterChangeHandler;
import de.intevation.flys.client.client.event.HasStepBackHandlers;
import de.intevation.flys.client.client.event.HasStepForwardHandlers;
import de.intevation.flys.client.client.event.CollectionChangeEvent;
import de.intevation.flys.client.client.event.CollectionChangeHandler;
import de.intevation.flys.client.client.event.ParameterChangeEvent;
import de.intevation.flys.client.client.event.ParameterChangeHandler;
import de.intevation.flys.client.client.event.StepBackEvent;
import de.intevation.flys.client.client.event.StepBackHandler;
import de.intevation.flys.client.client.event.StepForwardEvent;
import de.intevation.flys.client.client.event.StepForwardHandler;
import de.intevation.flys.client.client.services.AddArtifactService;
import de.intevation.flys.client.client.services.AddArtifactServiceAsync;
import de.intevation.flys.client.client.services.AdvanceService;
import de.intevation.flys.client.client.services.AdvanceServiceAsync;
import de.intevation.flys.client.client.services.ArtifactService;
import de.intevation.flys.client.client.services.ArtifactServiceAsync;
import de.intevation.flys.client.client.services.StepForwardService;
import de.intevation.flys.client.client.services.StepForwardServiceAsync;
import de.intevation.flys.client.client.services.CreateCollectionService;
import de.intevation.flys.client.client.services.CreateCollectionServiceAsync;
import de.intevation.flys.client.client.ui.ModuleSelection;


/**
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class CollectionView
extends      Window
implements   CollectionChangeHandler, HasCollectionChangeHandlers,
             HasParameterChangeHandler, ParameterChangeHandler,
             StepForwardHandler, StepBackHandler
{
    /** The ArtifactService used to communicate with the Artifact server. */
    protected ArtifactServiceAsync artifactService =
        GWT.create(ArtifactService.class);

    /** The StepForwardService used to put data into an existing artifact. */
    protected StepForwardServiceAsync forwardService =
        GWT.create(StepForwardService.class);

    /** The StepForwardService used to put data into an existing artifact. */
    protected AdvanceServiceAsync advanceService =
        GWT.create(AdvanceService.class);

    /** The ArtifactService used to communicate with the Artifact server. */
    protected CreateCollectionServiceAsync createCollectionService =
        GWT.create(CreateCollectionService.class);

    /** The AddArtifactService used to add an artifact to a collection. */
    protected AddArtifactServiceAsync addArtifactService =
        GWT.create(AddArtifactService.class);

    /** The message class that provides i18n strings.*/
    FLYSMessages messages = GWT.create(FLYSMessages.class);

    /** The FLYS instance used to call services.*/
    protected FLYS flys;

    /** The ParameterList.*/
    protected ParameterList parameterList;

    /** The list of ValueChangeHandlers.*/
    protected List<CollectionChangeHandler> handlers;

    /** The list of ParameterizationChangeHandler.*/
    protected List<ParameterChangeHandler> parameterHandlers;

    /** The collection to be displayed.*/
    protected Collection collection;

    /** The artifact that handles the parameterization.*/
    protected Artifact artifact;

    protected TabSet tabs;

    /** The parameter tab.*/
    protected Tab parameterTab;

    /** The output tab.*/
    protected Tab outputTab;

    /** The layout.*/
    protected Layout layout;


    /**
     * This constructor creates a new CollectionView that is used to display the
     * <i>collection</i>.
     *
     * @param collection The collection to be displayed.
     */
    public CollectionView(FLYS flys, Collection collection) {
        this.flys       = flys;
        this.collection = collection;

        this.tabs              = new TabSet();
        this.parameterTab      = new Tab(messages.winfo());
        this.parameterList     = new ParameterList(this);
        this.handlers          = new ArrayList<CollectionChangeHandler>();
        this.parameterHandlers = new ArrayList<ParameterChangeHandler>();
        this.layout            = new VLayout();

        addCollectionChangeHandler(this);
        addParameterChangeHandler(this);

        init();
    }


    /**
     * This method handles the initial layout stuff.
     */
    protected void init() {
        setWidth(700);
        setHeight(600);

        layout.setWidth100();

        setCanDragResize(true);

        DateTimeFormat dtf = DateTimeFormat.getFormat(messages.date_format());
        String lastAccess  = dtf.format(collection.getLastAccess());
        setTitle(lastAccess + " - " + collection.getName());

        addItem(layout);

        layout.addMember(tabs);
        tabs.addTab(parameterTab);

        if (isNew()) {
            tabs.setTabTitle(0, messages.new_calculation());
            tabs.updateTab(0, renderNew());
        }
    }


    /**
     * This method triggers the CreateCollectionService to create a new
     * collection in the artifact server.
     *
     * @param ownerId The uuid of the user that should own the new collection.
     */
    protected void createNewCollection(String ownerId) {
        Config config          = Config.getInstance();
        final String serverUrl = config.getServerUrl();

        createCollectionService.create(
            serverUrl, ownerId,
            new AsyncCallback<Collection>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Could not create the new collection.");
                    GWT.log(caught.getMessage());
                }

                public void onSuccess(Collection collection) {
                    GWT.log("Successfully created a new collection.");

                    Artifact artifact = getArtifact();
                    addArtifactService.add(collection, artifact, serverUrl,
                        new AsyncCallback<Collection>() {

                            public void onFailure(Throwable caught) {
                                GWT.log("An error occured while adding artifact.");
                            }

                            public void onSuccess(Collection newCollection) {
                                GWT.log("Successfully added artifact.");
                                setCollection(newCollection);
                            }
                        }
                    );
                }
            });
    }


    protected FLYS getFlys() {
        return flys;
    }



    /**
     * This method registers a new ValueChangeHandler.
     *
     * @param handler The new ValueChangeHandler.
     */
    public void addCollectionChangeHandler(CollectionChangeHandler handler) {
        if (handler != null) {
            handlers.add(handler);
        }
    }


    /**
     * This method registers a new ParameterChangeHandler.
     *
     * @param handler The new ParameterChangeHandler.
     */
    public void addParameterChangeHandler(ParameterChangeHandler handler) {
        if (handler != null) {
            parameterHandlers.add(handler);
        }
    }


    /**
     * This method calls the <code>onValueChange()</code> method of all
     * registered ValueChangeHanders.
     */
    protected void fireCollectionChangeEvent(
        Collection old, Collection newCol)
    {
        for (CollectionChangeHandler handler: handlers) {
            handler.onCollectionChange(new CollectionChangeEvent(old, newCol));
        }
    }


    /**
     * This method calls the <code>onParameterChange()</code> method of all
     * registered ParameterChangeHandler.
     */
    protected void fireParameterChangeEvent(Artifact old, Artifact newArt) {
        for (ParameterChangeHandler handler: parameterHandlers) {
            handler.onParameterChange(new ParameterChangeEvent(old, newArt));
        }
    }


    /**
     * This method returns true, if the Collection is new and no plugins has
     * been chosen.
     *
     * @return true, if the Collection is new.
     */
    public boolean isNew() {
        return collection.getItemLength() == 0 ? true : false;
    }


    /**
     * This method creates a Canvas displaying the plugins of FLYS combined with
     * a widget to select a river.
     *
     * @return a Canvas that displays the supported plugins and rivers of FLYS.
     */
    protected Canvas renderNew() {
        River[] rivers   = flys.getRivers();
        DataItem[] items = new DataItem[rivers.length];

        int i = 0;
        for (River river: rivers) {
            String name = river.getName();
            items[i++]  = new DefaultDataItem(name, null, name);
        }

        Data data = new DefaultData(
            "river",
            messages.river_selection(),
            null,
            items);

        ModuleSelection widget         = new ModuleSelection();
        HasStepForwardHandlers handler = (HasStepForwardHandlers) widget;

        handler.addStepForwardHandler(new StepForwardHandler() {
            public void onStepForward(StepForwardEvent event) {
                Data[] data = event.getData();

                DataItem[] moduleItems = data[0].getItems();
                DataItem[] riversItems = data[1].getItems();

                String module = moduleItems[0].getStringValue();
                String river  = riversItems[0].getStringValue();

                final String serverUrl = Config.getInstance().getServerUrl();
                final Data[] feedData  = new Data[] { data[1] };
                artifactService.create(
                    serverUrl, module.toLowerCase(),
                    new AsyncCallback<Artifact>() {
                        public void onFailure(Throwable caught) {
                            GWT.log("Could not create the new artifact.");
                            GWT.log(caught.getMessage());
                        }

                        public void onSuccess(Artifact artifact) {
                            GWT.log("Successfully created a new artifact.");

                            forwardService.go(serverUrl, artifact, feedData,
                            new AsyncCallback<Artifact>() {
                                public void onFailure(Throwable caught) {
                                    GWT.log("Could not feed the artifact.");
                                    GWT.log(caught.getMessage());
                                }

                                public void onSuccess(Artifact artifact) {
                                    GWT.log("Successfully feed the artifact.");
                                    setArtifact(artifact);
                                }
                            });
                        }
                });
            }
        });

        DataList list = new DataList();
        list.add(data);

        return widget.create(list);
    }


    /**
     * Returns the artifact that is used for the parameterization.
     *
     * @return the artifact that is used for the parameterization.
     */
    protected Artifact getArtifact() {
        return artifact;
    }


    /**
     * Set the current artifact that is the master of the parameterization.
     *
     * @param artifact The new artifact.
     */
    protected void setArtifact(Artifact artifact) {
        Artifact tmp  = this.artifact;
        this.artifact = artifact;

        fireParameterChangeEvent(tmp, this.artifact);
    }


    /**
     * Implements the onCollectionChange() method to do update the GUI after the
     * parameterization has changed.
     *
     * @param event The ParameterChangeEvent.
     */
    public void onParameterChange(ParameterChangeEvent event) {
        Artifact art             = event.getNewValue();
        ArtifactDescription desc = art.getArtifactDescription();
        OutputMode[] outs        = desc.getOutputModes();

        if (outs != null) {
            User user = getFlys().getCurrentUser();
            createNewCollection(user.identifier());
        }
        else {
            updateView();
        }
    }


    /**
     * Set the current collection.
     *
     * @param collection The new collection.
     */
    protected void setCollection(Collection collection) {
        Collection tmp  = this.collection;
        this.collection = collection;

        fireCollectionChangeEvent(tmp, this.collection);
    }


    public void onCollectionChange(CollectionChangeEvent event) {
        updateView();
    }


    /**
     * This method is used to call the ADVANCE service to go back to a previous
     * state.
     *
     * @param e The StepBackEvent that holds the identifier of the target state.
     */
    public void onStepBack(StepBackEvent e) {
        final String target    = e.getTarget();
        final String serverUrl = Config.getInstance().getServerUrl();

        advanceService.advance(serverUrl, artifact, target,
            new AsyncCallback<Artifact>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Could not go back to '" + target + "'");
                    GWT.log(caught.getMessage());
                }

                public void onSuccess(Artifact artifact) {
                    GWT.log("Successfully step back to '" + target + "'");
                    setArtifact(artifact);
                }
            }
        );
    }


    /**
     * This method is called if the user clicks on the 'next' button to advance
     * to the next state.
     *
     * @param event The StepForwardEvent.
     */
    public void onStepForward(StepForwardEvent event) {
        GWT.log("CollectionView - onStepForward()");
        String serverUrl = Config.getInstance().getServerUrl();

        forwardService.go(serverUrl, artifact, event.getData(),
            new AsyncCallback<Artifact>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Could not feed the artifact.");
                    GWT.log(caught.getMessage());
                }

                public void onSuccess(Artifact artifact) {
                    GWT.log("Successfully feed the artifact.");
                    setArtifact(artifact);
                }
        });
    }


    /**
     * Update the view (refresh the list of old and current data).
     */
    protected void updateView() {
        GWT.log("CollectionView.updateView()");
        ArtifactDescription desc = artifact.getArtifactDescription();

        DataList currentData = desc.getCurrentData();
        if (currentData != null) {
            // the user has to enter some attributes
            String uiProvider   = currentData.getUIProvider();
            UIProvider provider = UIProviderFactory.getProvider(uiProvider);

            ((HasStepForwardHandlers) provider).addStepForwardHandler(this);
            ((HasStepBackHandlers) provider).addStepBackHandler(this);

            parameterList.setCurrentData(currentData, provider);
        }
        else {
            // we have reached a final state with no more user input
            parameterList.setCurrentData(null, null);
        }

        parameterList.addOldDatas(desc.getOldData());

        tabs.setTabTitle(0, messages.winfo());
        tabs.updateTab(0, parameterList);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org