view flys-client/src/main/java/de/intevation/flys/client/client/FLYS.java @ 5818:a4ff4167be1e

Request feature info on all layers and show it as html if the server does not return valid gml. Non queryable layers produce an error message when the request fails. This is good enough
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 24 Apr 2013 17:33:27 +0200
parents b660090b417d
children
line wrap: on
line source
package de.intevation.flys.client.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.UmbrellaException;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.xml.client.XMLParser;

import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.CloseClickEvent;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;

import de.intevation.flys.client.client.event.CollectionChangeEvent;
import de.intevation.flys.client.client.event.CollectionChangeHandler;
import de.intevation.flys.client.client.services.ArtifactService;
import de.intevation.flys.client.client.services.ArtifactServiceAsync;
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;
import de.intevation.flys.client.client.services.GetArtifactService;
import de.intevation.flys.client.client.services.GetArtifactServiceAsync;
import de.intevation.flys.client.client.services.RiverService;
import de.intevation.flys.client.client.services.RiverServiceAsync;
import de.intevation.flys.client.client.services.UserService;
import de.intevation.flys.client.client.services.UserServiceAsync;
import de.intevation.flys.client.client.ui.CollectionView;
import de.intevation.flys.client.client.ui.FLYSHeader;
import de.intevation.flys.client.client.ui.FLYSView;
import de.intevation.flys.client.client.ui.FLYSWorkspace;
import de.intevation.flys.client.client.ui.ProjectList;
import de.intevation.flys.client.shared.model.Artifact;
import de.intevation.flys.client.shared.model.Collection;
import de.intevation.flys.client.shared.model.CollectionItem;
import de.intevation.flys.client.shared.model.GaugeInfo;
import de.intevation.flys.client.shared.model.River;
import de.intevation.flys.client.shared.model.User;

import de.intevation.flys.client.client.ui.wq.WQAutoTabSet;

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


/**
 * Entry point classes define <code>onModuleLoad()</code>.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class FLYS implements EntryPoint, CollectionChangeHandler {

    /** The message class that provides i18n strings.*/
    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);

    /** The UserService used to retrieve information about the current user. */
    protected UserServiceAsync userService = GWT.create(UserService.class);

    /** The RiverService used to retrieve the supported rivers of the server.*/
    protected RiverServiceAsync riverService = GWT.create(RiverService.class);

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

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

    /** The GetArtifactService used to open an existing collection. */
    protected GetArtifactServiceAsync getArtifactService =
        GWT.create(GetArtifactService.class);

    /** The CreateCollectionServiceAsync used to create a new collection */
    protected CreateCollectionServiceAsync collectionService =
        GWT.create(CreateCollectionService.class);

    /** The content window. It takes the whole space beneath the header. */
    protected FLYSView view;

    /** The project list that displays the projects of the user. */
    protected ProjectList projectList;

    /** The FLYSWorkspace. */
    protected FLYSWorkspace workspace;

    /** The user who is currently logged in. */
    protected User currentUser;

    /** The list of rivers supported by the server. */
    protected River[] rivers;

    /** This list is used to track the opened projects. */
    protected List<String> openProjects;

    private FLYSHeader header;


    public static String getExceptionString(FLYSConstants msg, Throwable caught) {
        try {
            return msg.getString(caught.getMessage());
        }
        catch(MissingResourceException ex) {
            // There are some server error exceptions with
            // varying text messages that cannot be localized
            // easily. In this rare cases, use the plain
            // exception message.
            GWT.log("Missing resource for: " + caught.getMessage());
            return caught.getLocalizedMessage();
        }
    }

    /**
     * This is the entry point method.
     */
    @Override
    public void onModuleLoad() {
        openProjects = new ArrayList<String>();

        //GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
        //    public void onUncaughtException(Throwable e) {
        //        showWarning(e);
        //    }
        //});

        VLayout vertical = new VLayout();
        vertical.setLayoutMargin(1);
        vertical.setWidth100();
        vertical.setHeight100();

        view = new FLYSView();
        header = new FLYSHeader(this);

        vertical.addMember(header);
        vertical.addMember(view);

        vertical.draw();

        initConfiguration();

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

        userService.getCurrentUser(locale, new AsyncCallback<User>() {
            @Override
            public void onFailure(Throwable caught) {
                GWT.log("Could not find a logged in user.");
                String msg = getExceptionString(MSG, caught);
                SC.warn(msg);
            }

            @Override
            public void onSuccess(User user) {
                GWT.log("Found a user. Set '"+ user.getName() + "'");
                setCurrentUser(user);

                header.setCurrentUser(user);

                projectList = new ProjectList(FLYS.this, user);
                workspace   = new FLYSWorkspace(FLYS.this);
                view.setProjectList(projectList);
                view.setFLYSWorkspace(workspace);

                readRivers();
            }
        });
    }


    public void showWarning(Throwable e) {
        StringBuilder sb = new StringBuilder();
        sb.append("<tt>");

        if (e instanceof UmbrellaException) {
            UmbrellaException u = (UmbrellaException) e;
            Set<Throwable> throwables = u.getCauses();

            for (Throwable t: throwables) {
                sb.append(t.getLocalizedMessage());
                sb.append("<br>");
            }
        }
        else {
            sb.append(e.getLocalizedMessage());
        }

        sb.append("</tt>");

        Window w = new Window();
        w.setTitle(MSG.unexpected_exception());
        w.setWidth(550);
        w.setHeight(300);
        w.centerInPage();
        w.setCanDragResize(true);

        HTMLPane p = new HTMLPane();
        p.setContents(sb.toString());

        w.addItem(p);
        w.show();
    }


    /**
     * This method should be called at system start. It initialzes the client
     * configuration.
     */
    protected void initConfiguration() {
        String xml = FLYSResources.INSTANCE.initialConfiguration().getText();
        Config.getInstance(XMLParser.parse(xml));
    }


    /**
     * Returns the user that is currently logged in.
     *
     * @return the current user.
     */
    public User getCurrentUser() {
        return currentUser;
    }


    /**
     * Sets the current user.
     */
    public void setCurrentUser(User user) {
        currentUser = user;
    }


    /**
     * Returns the project list.
     */
    public ProjectList getProjectList() {
        return projectList;
    }


    /**
     * Returns the projects workspace that contains all project windows.
     *
     * @return the FLYSWorkspace.
     */
    public FLYSWorkspace getWorkspace() {
        return workspace;
    }


    /**
     * Returns a list of rivers supported by the artifact server.
     *
     * @return a list of rivers supported by the artifact server.
     */
    public River[] getRivers() {
        return rivers;
    }


    protected void readRivers() {
        Config config = Config.getInstance();
        String locale = config.getLocale();

        riverService.list(locale, new AsyncCallback<River[]>() {
            @Override
            public void onFailure(Throwable caught) {
                GWT.log("Could not recieve a list of rivers.");
                SC.warn(getExceptionString(MSG, caught));
            }

            @Override
            public void onSuccess(River[] newRivers) {
                GWT.log("Retrieved " + newRivers.length + " new rivers.");
                rivers = newRivers;
            }
        });
    }


    /**
     * This method creates a new CollectionView and adds it to the workspace.
     * <b>NOTE</b>The user needs to be logged in and there need to at least one
     * river - otherwise a warning is displayed and no CollectionView is
     * created.
     */
    public void newProject() {
        if (getCurrentUser() == null) {
            SC.warn(MSG.error_not_logged_in());
            return;
        }

        if (getRivers() == null) {
            SC.warn(MSG.error_no_rivers_found());
            readRivers();

            return;
        }

        CollectionView view = new CollectionView(this);
        workspace.addView("new-project", view);

        view.addCollectionChangeHandler(getProjectList());
    }


    protected void lockProject(String uuid) {
        if (isProjectLocked(uuid)) {
            return;
        }

        openProjects.add(uuid);
    }


    protected void unlockProject(String uuid) {
        openProjects.remove(uuid);
    }


    /** Whether project uuid is currently opened. */
    protected boolean isProjectLocked(String uuid) {
        return openProjects.contains(uuid);
    }


    /** Opens (or bring into foreground) project with given id. */
    public void openProject(final String collectionID) {
        if (collectionID == null) {
            return;
        }

        if (isProjectLocked(collectionID)) {
            workspace.bringUp(collectionID);
            return;
        }

        lockProject(collectionID);

        GWT.log("Open existing project: " + collectionID);

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

        describeCollectionService.describe(collectionID, locale,
            new AsyncCallback<Collection>() {
                @Override
                public void onFailure(Throwable caught) {
                    SC.warn(getExceptionString(MSG, caught));
                }

                @Override
                public void onSuccess(Collection c) {
                    final Collection collection = c;

                    if (collection.getItemLength() == 0) {
                        CollectionView view = new CollectionView(
                            FLYS.this, collection, null);

                        view.addCollectionChangeHandler(
                            getProjectList());
                        view.addCloseClickHandler(
                            new CloseCollectionViewHandler(
                                FLYS.this, collectionID));

                        workspace.addView(collectionID, view);

                        return;
                    }

                    final CollectionItem item = c.getItem(0);

                    if (item == null) {
                        SC.warn(MSG.error_load_parameterization());
                        return;
                    }

                    getArtifactService.getArtifact(
                        locale,
                        item.identifier(),
                        item.hash(),
                        new AsyncCallback<Artifact>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                unlockProject(collectionID);
                                SC.warn(getExceptionString(MSG, caught));
                            }

                            @Override
                            public void onSuccess(Artifact artifact) {
                                CollectionView view = new CollectionView(
                                    FLYS.this, collection, artifact);

                                view.addCollectionChangeHandler(
                                    getProjectList());
                                view.addCloseClickHandler(
                                    new CloseCollectionViewHandler(
                                        FLYS.this, collectionID));

                                workspace.addView(collectionID, view);
                            }
                    });

                }
        });
    }


    public void closeProject(String uuid) {
        unlockProject(uuid);
        workspace.destroyProject(uuid);
    }


    /**
     * Create a new Artifact.
     */
    public void newArtifact(String factory) {
        Config config = Config.getInstance();
        String locale = config.getLocale();

        artifactService.create(locale, factory, null,
            new AsyncCallback<Artifact>() {
                @Override
                public void onFailure(Throwable caught) {
                    GWT.log("Could not create the new artifact.");
                    SC.warn(getExceptionString(MSG, caught));
                }

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


    /** Opens a window with Main Values from gauge. */
    public void newGaugeMainValueTable(GaugeInfo gauge) {
        Window mainValueView = new Window();

        // Take middle to avoid issues at borders.
        double km = (gauge.getKmEnd() + gauge.getKmStart())/2d;
        mainValueView.addItem(new WQAutoTabSet(gauge.getRiverName(),
            new double[] {km, km}));
        mainValueView.setWidth(450);
        mainValueView.setHeight(600);

        mainValueView.setMaximized(false);
        mainValueView.centerInPage();
        mainValueView.setCanDragReposition(true);
        mainValueView.setCanDragResize(true);
        mainValueView.setShowMaximizeButton(true);
        mainValueView.setKeepInParentRect(true);

        mainValueView.setTitle(MSG.mainvalues() + " " + gauge.getName() + " (" + gauge.getRiverName() + ")" );
        workspace.addChild(mainValueView);
    }

    public void newGaugeDischargeCurve(String river, Long gaugeref) {
        Config config = Config.getInstance();

        final String locale = config.getLocale();
        final String riv = river;
        final Long ref = gaugeref;
        final FLYS   flys = this;

        User user = getCurrentUser();

        if (user == null) {
            SC.warn(MSG.error_not_logged_in());
            return;
        }

        collectionService.create(locale, user.identifier(),
            new AsyncCallback<Collection>() {
                @Override
                public void onFailure(Throwable caught) {
                    GWT.log("Could not create new collection.");
                    SC.warn(getExceptionString(MSG, caught));
                }

                @Override
                public void onSuccess(Collection collection) {
                    GWT.log("Successfully created a new collection.");
                    final Collection col = collection;
                    artifactService.createGaugeDischargeCurveArtifact(
                        col, locale, riv, ref,
                        new AsyncCallback<Artifact>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                GWT.log("Could not create the new artifact.");
                                SC.warn(getExceptionString(MSG, caught));
                            }

                            @Override
                            public void onSuccess(Artifact artifact) {
                                GWT.log("Successfully created a new artifact.");
                                CollectionView view = new CollectionView(flys,
                                    col, artifact);
                                workspace.addView(col.identifier(), view);

                                view.addCollectionChangeHandler(getProjectList());
                                view.addCloseClickHandler(
                                    new CloseCollectionViewHandler(
                                        FLYS.this, col.identifier()));
                                projectList.updateUserCollections();
                            }
                    });
                }
            });
    }

    public void newSQRelation(String river, int measurementStation) {
        Config config = Config.getInstance();

        final String locale = config.getLocale();
        final String riv = river;
        final int mStation = measurementStation;
        final FLYS   flys = this;

        User user = getCurrentUser();

        if (user == null) {
            SC.warn(MSG.error_not_logged_in());
            return;
        }

        collectionService.create(locale, user.identifier(),
            new AsyncCallback<Collection>() {
                @Override
                public void onFailure(Throwable caught) {
                    GWT.log("Could not create new collection.");
                    SC.warn(getExceptionString(MSG, caught));
                }

                @Override
                public void onSuccess(Collection collection) {
                    GWT.log("Successfully created a new collection.");
                    final Collection col = collection;
                    artifactService.createSQRelationArtifact(
                        col, locale, riv, mStation,
                        new AsyncCallback<Artifact>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                GWT.log("Could not create the new artifact.");
                                SC.warn(getExceptionString(MSG, caught));
                            }

                            @Override
                            public void onSuccess(Artifact artifact) {
                                GWT.log("Successfully created a new artifact.");
                                CollectionView view = new CollectionView(flys,
                                    col, artifact);
                                workspace.addView(col.identifier(), view);

                                view.addCollectionChangeHandler(getProjectList());
                                view.addCloseClickHandler(
                                    new CloseCollectionViewHandler(
                                        FLYS.this, col.identifier()));
                                projectList.updateUserCollections();
                            }
                    });
                }
            });
    }

    @Override
    public void onCollectionChange(CollectionChangeEvent event) {
        Collection oldC = event.getOldValue();

        if (oldC == null) {
            Collection newC = event.getNewValue();
            lockProject(newC.identifier());
        }
    }



    /**
     * This CloseClickHandler is used to remove lock on a specific Collection so
     * that is might be opened again.
     */
    public class CloseCollectionViewHandler implements CloseClickHandler {
        protected FLYS   flys;
        protected String uuid;

        public CloseCollectionViewHandler(FLYS flys, String uuid) {
            this.flys = flys;
            this.uuid = uuid;
        }

        @Override
        public void onCloseClick(CloseClickEvent event) {
            flys.closeProject(uuid);
        }
    }

    public boolean isProjectListVisible() {
        if (this.projectList == null) {
            return true;
        }
        return this.projectList.isVisible();
    }

    public void hideProjectList() {
        if (this.projectList != null) {
            this.projectList.hide();
        }
    }

    public void openProjectList() {
        if (this.projectList != null) {
            this.projectList.show();
        }
    }

    public void hideHeaderProjectButton() {
        this.header.hideProjectButton();
    }

    public void shoHeaderProjectButton() {
        this.header.showProjectButton();
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org