view flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageTwinPanel.java @ 1304:18b0414bde44

Allow reparameterization of W-Diffs. flys-client/trunk@2938 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Tue, 11 Oct 2011 11:59:57 +0000
parents b0ed67cb5197
children 014fc183c640
line wrap: on
line source
package de.intevation.flys.client.client.ui;

import java.util.ArrayList;
import java.util.HashSet;
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.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.events.ClickEvent;

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

import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.client.event.StepForwardEvent;
import de.intevation.flys.client.shared.model.Recommendation;
import de.intevation.flys.client.shared.model.ToLoad;
import de.intevation.flys.client.shared.model.Recommendation.Facet;
import de.intevation.flys.client.shared.model.Recommendation.Filter;

import de.intevation.flys.client.client.services.LoadArtifactService;
import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
import de.intevation.flys.client.client.Config;

// 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 DatacageTwinPanel
extends      TextProvider {

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

    protected String dataName;

    protected User user;

    protected ToLoad toLoad1;

    protected ToLoad toLoad2;

    protected ListGrid differencesList;

    LoadArtifactServiceAsync loadArtifactService = GWT.create(
            de.intevation.flys.client.client.services.LoadArtifactService.class);


    public DatacageTwinPanel(User user) {
        super();
        this.user = user;
    }


    /**
     * Remove first occurrence of "[" and "]" (if both do occur).
     * @param value String to be stripped of [] (might be null).
     * @return input string but with [ and ] removed, or input string if no
     *         brackets were found.
     * @see StringUtil.unbracket
     */
    public static final String unbracket(String value) {
        // null- guard.
        if (value == null) return value;

        int start = value.indexOf("[");
        int end   = value.indexOf("]");

        if (start < 0 || end < 0) {
            return value;
        }

        value = value.substring(start + 1, end);

        return value;
    }


    /**
     * 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("waterlevel", parts[0],
            this.artifact.getUuid(), filter);
        return r; 
    }


    /**
     * Add RecomendationPairRecords from input String to the ListGrid.
     */
    public void populateGridFromString(String from){
        // Split this string.
        // Create according recommendations and display strings.
        String[] recs = from.split("#");
        // TODO real name
        if (recs.length % 2 != 0) return;
        for (int i = 0; i < recs.length; i+=2) {
            Recommendation minuend    = createRecommendationFromString(recs[i+0]);
            Recommendation subtrahend = createRecommendationFromString(recs[i+1]);
            RecommendationPairRecord pr = new RecommendationPairRecord(
               "A", minuend, "B", subtrahend);
            // This Recommendation Pair comes from the data string and was thus
            // already cloned.
            pr.setIsAlreadyLoaded(true);
            this.differencesList.addData(pr);
        }
    }


    @Override
    public Canvas create(DataList dataList) {
        GWT.log("createData()");

        // TODO use i18n of data.
        Canvas label  = new Label("Subtrahend/Minuend");//data.getDescription());
        Canvas widget = createWidget();
        Canvas submit = getNextButton();

        VLayout layout       = new VLayout();
        HLayout helperLayout = new HLayout();
        label.setHeight(50);
        helperLayout.addMember(new DatacagePairWidget(this.artifact,
            user, "longitudinal_section", differencesList));

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

        // Find old data, if any.
        Data   data   = dataList.get(0);
        // "diffids" data handling.
        this.dataName = data.getLabel();
        for (int i = 0; i < dataList.size(); i++) {
            if (dataList.get(i) != null) {
                if (dataList.get(i).getItems() != null) {
                    populateGridFromString(dataList.get(i).getItems()[0].getStringValue());
                }
                else{
                    System.out.println("DatacageTwinPanel: Datalist for item is null");
                }
            }
            else{
                System.out.println("DatacageTwinPanel: Data " + i + " is null (not displayable).");
            }
        }

        return layout;
    }


    @Override
    public List<String> validate() {
        List<String> errors = new ArrayList<String>();
        if (differencesList.getRecords().length == 0) {
            // TODO i18n of error message. (MSG.no_waterlevel_pair_selected())
            errors.add("No pair of waterlevel items selected");
        }

        return errors;
    }


    /**
     * Creates layout with grid that displays selection inside.
     */
    public Canvas createWidget() {
        VLayout layout  = new VLayout();
        differencesList = new ListGrid();

        differencesList.setHeight(150);
        differencesList.setShowAllRecords(true);
        differencesList.setCanEdit(false);
        differencesList.setCanRemoveRecords(true);

        ListGridField nameField    = new ListGridField("first",  "Minuend");
        ListGridField capitalField = new ListGridField("second", "Subtrahend");
        differencesList.setFields(new ListGridField[] {nameField,
           capitalField});

        layout.addMember(differencesList);

        return layout;
    }


    @Override
    public void onClick(ClickEvent e) {
        /*
        TODO: Validation/Error
        List<String> errors = validate();
        if (errors == null || errors.isEmpty()) {
        ...
        else {showErrors(errors);}

         * */
        GWT.log("DatacageTwinPanel.onClick");
        Config config = Config.getInstance();
        ListGridRecord[] records = differencesList.getRecords();

        Set<Recommendation> ar  = new HashSet<Recommendation>();
        Set<Recommendation> all = new HashSet<Recommendation>();
        for (ListGridRecord record : records) {
            RecommendationPairRecord r =
                (RecommendationPairRecord) record;
            // Do not add "old" recommendations.
            if (!r.isAlreadyLoaded()) {
                GWT.log("One not yet loaded.");
                ar.add(r.getFirst());
                ar.add(r.getSecond());
            }
            else {
                GWT.log("One already loaded.");
                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()]);
        loadArtifactService.loadMany(
              this.collection,
              toClone,
              "waterlevel",
              config.getServerUrl(),
              config.getLocale(),
              new AsyncCallback<Artifact[]>() {
                public void onFailure(Throwable caught) {
                    GWT.log("Failure of cloning with waterlevelfactory!");
                }
                public void onSuccess(Artifact[] artifacts) {
                    GWT.log("Success in cloning ("+toClone.length+") with watelevelfactory!");

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


    protected Data[] getData(
            Recommendation[] newRecommendations,
            Artifact[] newArtifacts,
            Recommendation[] oldRecommendations)
    {
        // Construct string with info about selections.
        String dataItemString = "";
        for (int i = 0; i < newRecommendations.length; i++) {
            Recommendation r = newRecommendations[i];
            Artifact newArtifact = newArtifacts[i];
            String uuid = newArtifact.getUuid();
            r.setMasterArtifact(uuid);
            if (i>0) dataItemString += "#";
    
            dataItemString += createDataString(uuid, r.getFilter());
        }

        for (int i = 0; i < oldRecommendations.length; i++) {
            Recommendation r = oldRecommendations[i];
            String uuid = r.getIDs();
            if (dataItemString.length() > 0) dataItemString += "#";
    
            dataItemString += createDataString(uuid, r.getFilter());
        }

        DataItem item = new DefaultDataItem(dataName, dataName, dataItemString);
        return new Data[] { new DefaultData(
            dataName, null, null, new DataItem[] {item}) };
    }


    protected String createDataString(String artifact, Filter filter) {
        Facet f = 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() + "]";
    }

    /*@Override
    protected Data[] getData() {
        // TODO ToLoadRecord ! 
        String value = "TODO:FIND VALUE";
        if (toLoad1 != null) {
            List<Recommendation> recommendations = toLoad1.toRecommendations();
            value = recommendations.get(0).getIDs();
        }
        DataItem item1 = new DefaultDataItem(dataName, dataName, value);
        DataItem item2 = new DefaultDataItem(dataName, dataName, value);
        return new Data[] { new DefaultData(
            dataName, null, null, new DataItem[] { item1, item2}) };
    }*/
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org