view flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java @ 803:653ae84533e7

Read/create recommended Artifacts and add them to the current Collection. flys-client/trunk@2350 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 18 Jul 2011 09:52:16 +0000
parents cd8603aaa730
children 6f65e70fa11d
line wrap: on
line source
package de.intevation.flys.client.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.CloseClientEvent;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;
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.ExportMode;
import de.intevation.flys.client.shared.model.OutputMode;
import de.intevation.flys.client.shared.model.ReportMode;
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.FLYSConstants;
import de.intevation.flys.client.client.event.HasCollectionChangeHandlers;
import de.intevation.flys.client.client.event.HasOutputModesChangeHandlers;
import de.intevation.flys.client.client.event.CollectionChangeEvent;
import de.intevation.flys.client.client.event.CollectionChangeHandler;
import de.intevation.flys.client.client.event.OutputModesChangeEvent;
import de.intevation.flys.client.client.event.OutputModesChangeHandler;
import de.intevation.flys.client.client.event.ParameterChangeEvent;
import de.intevation.flys.client.client.event.ParameterChangeHandler;
import de.intevation.flys.client.client.services.ArtifactService;
import de.intevation.flys.client.client.services.ArtifactServiceAsync;
import de.intevation.flys.client.client.services.AddArtifactService;
import de.intevation.flys.client.client.services.AddArtifactServiceAsync;
import de.intevation.flys.client.client.services.CreateCollectionService;
import de.intevation.flys.client.client.services.CreateCollectionServiceAsync;
import de.intevation.flys.client.client.services.DescribeCollectionService;
import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync;


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

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

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

    /** The DescribeCollectionService used to update the existing collection. */
    protected DescribeCollectionServiceAsync describeCollectionService =
        GWT.create(DescribeCollectionService.class);

    /** The message class that provides i18n strings.*/
    protected FLYSConstants messages = GWT.create(FLYSConstants.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 ValueChangeHandlers.*/
    protected List<OutputModesChangeHandler> outHandlers;

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

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

    protected TabSet tabs;

    /** The output tab.*/
    protected Map<String, OutputTab> outputTabs;

    /** 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) {
        this.flys          = flys;
        this.tabs          = new TabSet();
        this.outputTabs    = new HashMap<String, OutputTab>();
        this.handlers      = new ArrayList<CollectionChangeHandler>();
        this.outHandlers   = new ArrayList<OutputModesChangeHandler>();
        this.layout        = new VLayout();
        this.parameterList = new ParameterList(
            flys, this, messages.new_project());

        addCollectionChangeHandler(this);
        addCollectionChangeHandler(parameterList);
        addCollectionChangeHandler(flys);
        addOutputModesChangeHandler(this);
        addOutputModesChangeHandler(parameterList);
        addCloseClickHandler(this);

        parameterList.addParameterChangeHandler(this);

        init();
    }


    public CollectionView(FLYS flys, Collection collection, Artifact artifact) {
        this.flys          = flys;
        this.tabs          = new TabSet();
        this.outputTabs    = new HashMap<String, OutputTab>();
        this.handlers      = new ArrayList<CollectionChangeHandler>();
        this.outHandlers   = new ArrayList<OutputModesChangeHandler>();
        this.layout        = new VLayout();
        this.parameterList = new ParameterList(
            flys,
            this,
            messages.getString(artifact.getName()),
            artifact);

        addCollectionChangeHandler(this);
        addCollectionChangeHandler(parameterList);
        addCollectionChangeHandler(flys);
        addOutputModesChangeHandler(this);
        addOutputModesChangeHandler(parameterList);
        addCloseClickHandler(this);

        parameterList.addParameterChangeHandler(this);

        init();

        setCollection(collection);
        setArtifact(artifact);
    }


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

        layout.setWidth100();

        setCanDragReposition(true);
        setCanDragResize(true);
        setShowMaximizeButton(true);
        setKeepInParentRect(true);

        setTitle("");

        addItem(layout);

        layout.addMember(tabs);
        tabs.addTab(parameterList);
    }


    /**
     * 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) {
        GWT.log("CollectionView.createNewCollection");

        Config config       = Config.getInstance();
        final String url    = config.getServerUrl();
        final String locale = config.getLocale();

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

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

                    setCollection(collection);

                    Artifact artifact = getArtifact();
                    addArtifactToCollection(artifact);
                }
            });
    }


    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 OutputModesChangeHandler.
     *
     * @param handler The new OutputModesChangeHandler.
     */
    public void addOutputModesChangeHandler(OutputModesChangeHandler handler) {
        if (handler != null) {
            outHandlers.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));
        }
    }


    protected void fireOutputModesChangeEvent(OutputMode[] outputs) {
        if (collection == null) {
            return;
        }

        for (OutputModesChangeHandler handler: outHandlers) {
            handler.onOutputModesChange(new OutputModesChangeEvent(outputs));
        }
    }


    /**
     * 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;
    }


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


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


    /**
     * Implements the onCollectionChange() method to do update the GUI after the
     * parameterization has changed.
     *
     * @param event The ParameterChangeEvent.
     */
    public void onParameterChange(ParameterChangeEvent event) {
        GWT.log("CollectionView.onParameterChange");

        Artifact art             = event.getNewValue();
        ArtifactDescription desc = art.getArtifactDescription();
        OutputMode[] outs        = desc.getOutputModes();
        String[] recommended     = desc.getRecommendedArtifacts();

        if (recommended != null) {
            loadRecommendedArtifacts(recommended);
        }

        setArtifact(art);

        Collection c = getCollection();

        if (outs != null && c == null) {
            User user = getFlys().getCurrentUser();
            createNewCollection(user.identifier());
        }
        else if (c != null) {
            Config config = Config.getInstance();
            String url    = config.getServerUrl();
            String locale = config.getLocale();

            describeCollectionService.describe(c.identifier(), url, locale,
                new AsyncCallback<Collection>() {
                    public void onFailure(Throwable caught) {
                        GWT.log("Could not DESCRIBE collection.");
                        SC.warn(messages.getString(caught.getMessage()));
                    }


                    public void onSuccess(Collection newCollection) {
                        GWT.log("Successfully DESCRIBED collection.");
                        setCollection(newCollection);
                    }
                }
            );
        }
        else {
            updateView();
        }
    }


    /**
     * Returns the collection of displayed by this view.
     *
     * @return the collection of this view.
     */
    public Collection getCollection() {
        return collection;
    }


    /**
     * Set the current collection.
     *
     * @param collection The new collection.
     */
    protected void setCollection(Collection collection) {
        if (collection != null && this.collection == null) {
            flys.getWorkspace().addView(collection.identifier(), this);
        }

        Collection tmp  = this.collection;
        this.collection = collection;

        fireCollectionChangeEvent(tmp, this.collection);
    }


    public void onCollectionChange(CollectionChangeEvent event) {
        Collection newCol = event.getNewValue();

        Map<String, OutputMode> outs = newCol.getOutputModes();

        Set<String>  keys     = outs.keySet();
        OutputMode[] prepared = new OutputMode[outs.size()];

        int idx = 0;
        for (String outname: keys) {
            prepared[idx++] = outs.get(outname);
        }

        fireOutputModesChangeEvent(prepared);

        updateView();
    }


    public void onOutputModesChange(OutputModesChangeEvent event) {
        clearOutputTabs();
        OutputMode[] outs = event.getOutputModes();

        if (outs == null) {
            return;
        }

        boolean hasCSV = false;

        for (OutputMode out: outs) {
            addOutputTab(out.getName(), out);

            if (out instanceof ExportMode) {
                ExportMode export = (ExportMode) out;

                if (export.getFacet("csv") != null) {
                    hasCSV = true;
                }
            }
        }

        if (!hasCSV) {
            parameterList.removeTable();
        }
    }


    /**
     * Adds a new tab for the OutputMode <i>out</i>.
     *
     * @param name The name and title of the output.
     */
    protected void addOutputTab(String name, OutputMode out) {
        if (out instanceof ExportMode) {
            ExportMode export = (ExportMode) out;

            if (export.getFacet("csv") != null && !parameterList.hasTable()) {
                TableDataPanel p = new TableDataPanel();
                p.setUuid(collection.identifier());
                p.setName(out.getName());
                parameterList.setTable(p);
            }

            return;
        }

        if (out instanceof ReportMode) {
            // we don't want to display report modes at all
            return;
        }

        GWT.log("Add new output tab for '" + name + "'");

        String title  = messages.getString(name);
        OutputTab tab = out.createOutputTab(title, getCollection(), this);

        if (tab != null) {
            outputTabs.put(name, tab);
        }
    }


    /**
     * Removes all output mode tabs from tab bar.
     */
    protected void clearOutputTabs() {
        GWT.log("Clear OutputTabs.");

        int num = tabs.getNumTabs();

        for (int i = num-1; i >= 1; i--) {
            tabs.removeTab(i);
        }

        outputTabs.clear();
    }


    /**
     * Update the view (refresh the list of old and current data).
     */
    protected void updateView() {
        GWT.log("CollectionView.updateView()");
        updateOutputTabs();
    }


    /**
     * This method is used to update the tabs to show specific output modes.
     */
    protected void updateOutputTabs() {
        GWT.log("Update output tabs.");
        if (outputTabs != null) {
            Set<String> keys = outputTabs.keySet();

            for (String key: keys) {
                tabs.addTab(outputTabs.get(key));
            }
        }
    }


    public void onCloseClick(CloseClientEvent event) {
        if (collection != null) {
            flys.closeProject(collection.identifier());
        }
        else {
            hide();
            destroy();
        }
    }


    protected void addArtifactToCollection(final Artifact artifact) {
        Config config               = Config.getInstance();
        final String url            = config.getServerUrl();
        final String locale         = config.getLocale();
        final Collection collection = getCollection();

        addArtifactService.add(
            collection, artifact, url, locale,
            new AsyncCallback<Collection>() {
                public void onFailure(Throwable caught) {
                    GWT.log("An error occured while adding artifact.");
                    SC.warn(messages.getString(caught.getMessage()));
                }

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


    protected void loadRecommendedArtifacts(String[] factories) {
        Config config               = Config.getInstance();
        final String url            = config.getServerUrl();
        final String locale         = config.getLocale();
        final Collection collection = getCollection();
        final Artifact master       = getArtifact();

        for (String factory: factories) {
            GWT.log("Load recommended artifact: " + factory);

            createArtifactService.create(url, locale, factory, master.getUuid(),
                new AsyncCallback<Artifact>() {

                    public void onFailure(Throwable caught) {
                        GWT.log("Error loading recommendations: " +
                            caught.getMessage());
                    }

                    public void onSuccess(Artifact artifact) {
                        GWT.log("Created new artifact: " + artifact.getUuid());
                        addArtifactToCollection(artifact);
                    }
            });
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org