view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java @ 8023:f7f86f4e4c8d

Removed obsolete imports.
author Sascha L. Teichmann <teichmann@intevation.de>
date Wed, 09 Jul 2014 17:10:18 +0200
parents 93da474506e7
children 5dfb3ff98bc6
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.client.client.ui.minfo;

import com.google.gwt.core.client.GWT;

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

import com.smartgwt.client.data.Record;

import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;

import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;

import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tree.TreeNode;

import org.dive4elements.river.client.client.Config;
import org.dive4elements.river.client.client.FLYSConstants;

import org.dive4elements.river.client.client.event.StepForwardEvent;

import org.dive4elements.river.client.client.services.LoadArtifactService;
import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
import org.dive4elements.river.client.client.services.RemoveArtifactService;
import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;

import org.dive4elements.river.client.client.ui.DatacageTwinPanel;
import org.dive4elements.river.client.client.ui.DatacageWidget;
import org.dive4elements.river.client.client.ui.RecommendationPairRecord;

import org.dive4elements.river.client.shared.model.Artifact;
import org.dive4elements.river.client.shared.model.Collection;
import org.dive4elements.river.client.shared.model.DataList;
import org.dive4elements.river.client.shared.model.ToLoad;

import org.dive4elements.river.client.shared.model.Recommendation.Facet;
import org.dive4elements.river.client.shared.model.Recommendation.Filter;

import org.dive4elements.river.client.shared.model.Recommendation;
import org.dive4elements.river.client.shared.model.User;

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

// TODO Probably better to branch off AbstractUIProvider.
// TODO Merge with other datacage-widget impls.
/**
 * Panel containing a Grid and a "next" button. The Grid is fed by a
 * DatacagePairWidget which is put in the input-helper area.
 */
public class BedHeightsDatacagePanel
extends      DatacageTwinPanel {

    protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);

    /**
     * List to track previously selected but now removed pairs. (Needed to
     * be able to identify artifacts that can be removed from the collection.
     */
    protected List<RecommendationPairRecord> removedPairs =
        new ArrayList<RecommendationPairRecord>();

    /** Service handle to clone and add artifacts to collection. */
    LoadArtifactServiceAsync loadArtifactService = GWT.create(
            org.dive4elements.river.client.client.services.LoadArtifactService.class);

    /** Service to remove artifacts from collection. */
    RemoveArtifactServiceAsync removeArtifactService = GWT.create(
            org.dive4elements.river.client.client.services.RemoveArtifactService.class);

    protected DatacageWidget datacage;

    public BedHeightsDatacagePanel(User user) {
        super(user);
    }


    /**
     * Create a recommendation from a string representation of it.
     * @TODO describe format of input string
     * @param from string in format as shown above.
     * @return recommendation from input string.
     */
    public Recommendation createRecommendationFromString(String from) {
        // TODO Construct "real" filter.
        String[] parts = unbracket(from).split(";");
        Recommendation.Filter filter = new Recommendation.Filter();
        Recommendation.Facet  facet  = new Recommendation.Facet(
                parts[1],
                parts[2]);

        List<Recommendation.Facet> facets = new ArrayList<Recommendation.Facet>
            ();
        facets.add(facet);
        filter.add("longitudinal_section", facets);
        Recommendation r = new Recommendation("bedheight", parts[0],
            this.artifact.getUuid(), filter);
        r.setDisplayName(parts[3]);
        return r;
    }


    /**
     * Creates the graphical representation and interaction widgets for the data.
     * @param dataList the data.
     * @return graphical representation and interaction widgets for data.
     */
    @Override
    public Canvas create(DataList dataList) {
        GWT.log("createData()");

        String filter = "minfo-heights-diff";
        Canvas widget = createWidget();
        Canvas submit = getNextButton();
        datacage = new DatacageWidget(
            this.artifact, user, filter, "load-system:true", false);

        Button plusBtn = new Button(MSG.datacage_add_pair());
        plusBtn.setAutoFit(true);
        plusBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                plusClicked();
            }
        });

        VLayout layout       = new VLayout();
        VLayout helperLayout = new VLayout();
        helperLayout.addMember(datacage);
        helperLayout.addMember(plusBtn);

        layout.addMember(widget);
        layout.addMember(submit);
        layout.setMembersMargin(10);
        this.helperContainer.addMember(helperLayout);

        this.dataName = "diffids";

        return layout;
    }


    /**
     * Add record to list of removed records.
     */
    public void trackRemoved(Record r) {
        RecommendationPairRecord pr = (RecommendationPairRecord) r;
        this.removedPairs.add(pr);
    }


    /**
     * Validates data, does nothing if invalid, otherwise clones new selected
     * waterlevels and add them to collection, forward the artifact.
     */
    @Override
    public void onClick(ClickEvent e) {
        GWT.log("DatacageTwinPanel.onClick");

        List<String> errors = validate();
        if (errors != null && !errors.isEmpty()) {
            showErrors(errors);
            return;
        }

        Config config = Config.getInstance();
        String locale = config.getLocale();

        ListGridRecord[] records = differencesList.getRecords();

        List<Recommendation> ar  = new ArrayList<Recommendation>();
        List<Recommendation> all = new ArrayList<Recommendation>();

        for (ListGridRecord record : records) {
            RecommendationPairRecord r =
                (RecommendationPairRecord) record;
            // Do not add "old" recommendations.
            if (!r.isAlreadyLoaded()) {
                // Check whether one of those is a dike or similar.
                // TODO differentiate and merge: new clones, new, old.
                Recommendation firstR = r.getFirst();
                if(firstR.getIDs() != null) {
                    GWT.log("First IDs: " + firstR.getIDs() + " factory: "
                            + firstR.getFactory());
                }
                firstR.setFactory("bedheight");
                Recommendation secondR = r.getSecond();
                if(secondR.getIDs() != null) {
                    GWT.log("Second IDs: " + secondR.getIDs() + " factory: "
                            + secondR.getFactory());
                }
                secondR.setFactory("bedheight");

                ar.add(firstR);
                ar.add(secondR);
            }
            else {
                all.add(r.getFirst());
                all.add(r.getSecond());
            }
        }

        final Recommendation[] toClone = ar.toArray(new Recommendation[ar.size()]);
        final Recommendation[] toUse   = all.toArray(new Recommendation[all.size()]);

        // Find out whether "old" artifacts have to be removed.
        List<String> artifactIdsToRemove = new ArrayList<String>();
        for (RecommendationPairRecord rp: this.removedPairs) {
            Recommendation first  = rp.getFirst();
            Recommendation second = rp.getSecond();

            for (Recommendation recommendation: toUse) {
                if (first != null && first.getIDs().equals(recommendation.getIDs())) {
                    first = null;
                }
                if (second != null && second.getIDs().equals(recommendation.getIDs())) {
                    second = null;
                }

                if (first == null && second == null) {
                    break;
                }
            }
            if (first != null) {
                artifactIdsToRemove.add(first.getIDs());
            }
            if (second != null) {
                artifactIdsToRemove.add(second.getIDs());
            }
        }

        // Remove old artifacts, if any. Do this asychronously without much
        // feedback.
        for(final String uuid: artifactIdsToRemove) {
            removeArtifactService.remove(this.collection,
                uuid,
                locale,
                new AsyncCallback<Collection>() {
                    public void onFailure(Throwable caught) {
                        GWT.log("RemoveArtifact (" + uuid + ") failed.");
                    }
                    public void onSuccess(Collection collection) {
                        GWT.log("RemoveArtifact succeeded");
                    }
                });
        }

        // Clone new ones (and spawn statics), go forward.
        loadArtifactService.loadMany(
            this.collection,
            toClone,
            //"staticwkms" and "waterlevel"
            null,
            locale,
            new AsyncCallback<Artifact[]>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Failure of cloning with factories!");
                }
                public void onSuccess(Artifact[] artifacts) {
                    GWT.log("Successfully cloned " + toClone.length +
                        " with factories.");

                    fireStepForwardEvent(new StepForwardEvent(
                        getData(toClone, artifacts, toUse)));
                }
            });
    }


    /**
     * Creates part of the String that encodes minuend or subtrahend.
     * @param artifact Artifacts UUID.
     * @param recommendation Recommendation to wrap in string.
     */
    protected String createDataString(
        String artifact,
        Recommendation recommendation)
    {
        Filter filter = recommendation.getFilter();
        Facet  f      = null;

        if(filter != null) {
            Map<String, List<Facet>>               outs = filter.getOuts();
            Set<Map.Entry<String, List<Facet>>> entries = outs.entrySet();

            for (Map.Entry<String, List<Facet>> entry: entries) {
                List<Facet> fs = entry.getValue();

                f = fs.get(0);
                if (f != null) {
                    break;
                }
            }

            return "[" + artifact + ";"
                + f.getName()
                + ";"
                + f.getIndex()
                + ";"
                + recommendation.getDisplayName() + "]";
        }
        else {
            return "["
                + artifact
                + ";bedheight;0;"
                + recommendation.getDisplayName() + "]";
        }
    }

    /**
     * Callback for add-button.
     * Fires to load for every selected element and handler.
     */
    public void plusClicked() {
        List<TreeNode> selection = datacage.getPlainSelection();

        if (selection == null || selection.isEmpty()) {
            SC.say(MSG.warning());
            return;
        }

        for (TreeNode node : selection) {
            ToLoad toLoad1 = new ToLoad();
            ToLoad toLoad2 = new ToLoad();

            String factory = node.getAttribute("factory");
            if (factory != null) { // we need at least a factory
                String artifact    = node.getAttribute("artifact-id");
                String out         = node.getAttribute("out");
                String name        = node.getAttribute("facet");
                String ids         = node.getAttribute("ids");
                String info        = node.getAttribute("info");
                String targetOut   = node.getAttribute("target_out");

                String[] splitIds = ids.split("#");
                String[] splitInfo = info.split("#");
                toLoad1.add(artifact,
                     factory,
                     out,
                     name,
                     splitIds[0],
                     splitInfo[0],
                     targetOut);
                toLoad2.add(artifact,
                     factory,
                     out,
                     name,
                     splitIds[1],
                     splitInfo[1],
                     targetOut);
            }
            differencesList.addData(new RecommendationPairRecord(
                toLoad1.toRecommendations().get(0),
                toLoad2.toRecommendations().get(0)));
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org