ingo@0: package de.intevation.flys.client.client; ingo@0: ingo@0: import com.google.gwt.core.client.EntryPoint; ingo@2: import com.google.gwt.core.client.GWT; ingo@605: import com.google.gwt.event.shared.UmbrellaException; ingo@2: import com.google.gwt.user.client.rpc.AsyncCallback; ingo@9: import com.google.gwt.xml.client.XMLParser; christian@3989: ingo@217: import com.smartgwt.client.util.SC; christian@3501: import com.smartgwt.client.widgets.HTMLPane; ingo@605: import com.smartgwt.client.widgets.Window; christian@3501: import com.smartgwt.client.widgets.events.CloseClickEvent; ingo@557: import com.smartgwt.client.widgets.events.CloseClickHandler; christian@3501: import com.smartgwt.client.widgets.layout.VLayout; ingo@6: ingo@611: import de.intevation.flys.client.client.event.CollectionChangeEvent; ingo@611: import de.intevation.flys.client.client.event.CollectionChangeHandler; ingo@9: import de.intevation.flys.client.client.services.ArtifactService; ingo@9: import de.intevation.flys.client.client.services.ArtifactServiceAsync; bjoern@3865: import de.intevation.flys.client.client.services.CreateCollectionService; bjoern@3865: import de.intevation.flys.client.client.services.CreateCollectionServiceAsync; ingo@225: import de.intevation.flys.client.client.services.DescribeCollectionService; ingo@225: import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync; ingo@225: import de.intevation.flys.client.client.services.GetArtifactService; ingo@225: import de.intevation.flys.client.client.services.GetArtifactServiceAsync; ingo@29: import de.intevation.flys.client.client.services.RiverService; ingo@29: import de.intevation.flys.client.client.services.RiverServiceAsync; ingo@2: import de.intevation.flys.client.client.services.UserService; ingo@2: import de.intevation.flys.client.client.services.UserServiceAsync; ingo@6: import de.intevation.flys.client.client.ui.CollectionView; ingo@27: import de.intevation.flys.client.client.ui.FLYSHeader; ingo@1: import de.intevation.flys.client.client.ui.FLYSView; ingo@6: import de.intevation.flys.client.client.ui.FLYSWorkspace; ingo@4: import de.intevation.flys.client.client.ui.ProjectList; christian@3501: import de.intevation.flys.client.shared.model.Artifact; christian@3501: import de.intevation.flys.client.shared.model.Collection; christian@3501: import de.intevation.flys.client.shared.model.CollectionItem; felix@4981: import de.intevation.flys.client.shared.model.GaugeInfo; christian@3501: import de.intevation.flys.client.shared.model.River; christian@3501: import de.intevation.flys.client.shared.model.User; christian@3501: felix@4985: import de.intevation.flys.client.client.ui.wq.WQAutoTabSet; felix@4981: christian@3501: import java.util.ArrayList; christian@3501: import java.util.List; christian@3698: import java.util.MissingResourceException; christian@3501: import java.util.Set; ingo@1: ingo@0: ingo@0: /** ingo@0: * Entry point classes define onModuleLoad(). ingo@1: * ingo@1: * @author Ingo Weinzierl ingo@0: */ ingo@611: public class FLYS implements EntryPoint, CollectionChangeHandler { ingo@0: ingo@217: /** The message class that provides i18n strings.*/ ingo@217: protected FLYSConstants MSG = GWT.create(FLYSConstants.class); ingo@217: ingo@2: /** The UserService used to retrieve information about the current user. */ ingo@2: protected UserServiceAsync userService = GWT.create(UserService.class); ingo@2: ingo@29: /** The RiverService used to retrieve the supported rivers of the server.*/ ingo@29: protected RiverServiceAsync riverService = GWT.create(RiverService.class); ingo@29: ingo@9: /** The ArtifactService used to communicate with the Artifact server. */ ingo@9: protected ArtifactServiceAsync artifactService = ingo@9: GWT.create(ArtifactService.class); ingo@9: ingo@225: /** The ArtifactService used to communicate with the Artifact server. */ ingo@225: protected DescribeCollectionServiceAsync describeCollectionService = ingo@225: GWT.create(DescribeCollectionService.class); ingo@225: ingo@225: /** The GetArtifactService used to open an existing collection. */ ingo@225: protected GetArtifactServiceAsync getArtifactService = ingo@225: GWT.create(GetArtifactService.class); ingo@225: bjoern@3865: /** The CreateCollectionServiceAsync used to create a new collection */ bjoern@3865: protected CreateCollectionServiceAsync collectionService = bjoern@3865: GWT.create(CreateCollectionService.class); ingo@225: bjoern@4603: /** The content window. It takes the whole space beneath the header. */ ingo@2: protected FLYSView view; ingo@2: felix@864: /** The project list that displays the projects of the user. */ ingo@4: protected ProjectList projectList; ingo@4: felix@864: /** The FLYSWorkspace. */ ingo@6: protected FLYSWorkspace workspace; ingo@6: felix@864: /** The user who is currently logged in. */ ingo@25: protected User currentUser; ingo@25: felix@864: /** The list of rivers supported by the server. */ ingo@29: protected River[] rivers; ingo@29: felix@864: /** This list is used to track the opened projects. */ ingo@557: protected List openProjects; ingo@557: bjoern@4603: private FLYSHeader header; bjoern@4603: ingo@2: christian@4062: public static String getExceptionString(FLYSConstants msg, Throwable caught) { christian@3989: try { christian@4062: return msg.getString(caught.getMessage()); christian@3989: } christian@3989: catch(MissingResourceException ex) { christian@3989: // There are some server error exceptions with christian@3989: // varying text messages that cannot be localized christian@3989: // easily. In this rare cases, use the plain christian@3989: // exception message. christian@3989: GWT.log("Missing resource for: " + caught.getMessage()); christian@3989: return caught.getLocalizedMessage(); christian@3989: } christian@3989: } christian@3989: ingo@1: /** ingo@1: * This is the entry point method. ingo@1: */ christian@3501: @Override ingo@1: public void onModuleLoad() { ingo@557: openProjects = new ArrayList(); ingo@0: ingo@787: //GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() { ingo@787: // public void onUncaughtException(Throwable e) { ingo@787: // showWarning(e); ingo@787: // } ingo@787: //}); ingo@605: ingo@1: VLayout vertical = new VLayout(); ingo@1: vertical.setLayoutMargin(1); ingo@1: vertical.setWidth100(); ingo@1: vertical.setHeight100(); ingo@0: ingo@2: view = new FLYSView(); bjoern@4603: header = new FLYSHeader(this); ingo@1: bjoern@4603: vertical.addMember(header); ingo@1: vertical.addMember(view); ingo@1: ingo@797: vertical.draw(); ingo@2: ingo@9: initConfiguration(); ingo@229: ingo@229: Config config = Config.getInstance(); ingo@229: String locale = config.getLocale(); ingo@9: raimund@1425: userService.getCurrentUser(locale, new AsyncCallback() { christian@3501: @Override ingo@2: public void onFailure(Throwable caught) { ingo@2: GWT.log("Could not find a logged in user."); christian@4062: String msg = getExceptionString(MSG, caught); christian@3698: SC.warn(msg); ingo@2: } ingo@2: christian@3501: @Override ingo@2: public void onSuccess(User user) { ingo@25: GWT.log("Found a user. Set '"+ user.getName() + "'"); ingo@25: setCurrentUser(user); ingo@25: bjoern@4603: header.setCurrentUser(user); ingo@4: ingo@225: projectList = new ProjectList(FLYS.this, user); bjoern@4607: workspace = new FLYSWorkspace(FLYS.this); ingo@4: view.setProjectList(projectList); ingo@6: view.setFLYSWorkspace(workspace); ingo@217: ingo@217: readRivers(); ingo@2: } ingo@2: }); ingo@0: } ingo@6: ingo@6: ingo@605: public void showWarning(Throwable e) { ingo@605: StringBuilder sb = new StringBuilder(); ingo@605: sb.append(""); ingo@605: ingo@605: if (e instanceof UmbrellaException) { ingo@605: UmbrellaException u = (UmbrellaException) e; ingo@605: Set throwables = u.getCauses(); ingo@605: ingo@605: for (Throwable t: throwables) { ingo@605: sb.append(t.getLocalizedMessage()); ingo@605: sb.append("
"); ingo@605: } ingo@605: } ingo@605: else { ingo@605: sb.append(e.getLocalizedMessage()); ingo@605: } ingo@605: ingo@605: sb.append("
"); ingo@605: ingo@605: Window w = new Window(); ingo@605: w.setTitle(MSG.unexpected_exception()); ingo@605: w.setWidth(550); ingo@605: w.setHeight(300); ingo@605: w.centerInPage(); ingo@605: w.setCanDragResize(true); ingo@605: ingo@605: HTMLPane p = new HTMLPane(); ingo@605: p.setContents(sb.toString()); ingo@605: ingo@605: w.addItem(p); ingo@605: w.show(); ingo@605: } ingo@605: ingo@605: ingo@6: /** ingo@9: * This method should be called at system start. It initialzes the client ingo@9: * configuration. ingo@9: */ ingo@9: protected void initConfiguration() { ingo@9: String xml = FLYSResources.INSTANCE.initialConfiguration().getText(); ingo@9: Config.getInstance(XMLParser.parse(xml)); ingo@9: } ingo@9: ingo@9: ingo@9: /** ingo@25: * Returns the user that is currently logged in. ingo@25: * ingo@25: * @return the current user. ingo@25: */ ingo@25: public User getCurrentUser() { ingo@25: return currentUser; ingo@25: } ingo@25: ingo@25: ingo@25: /** ingo@25: * Sets the current user. ingo@25: */ ingo@25: public void setCurrentUser(User user) { ingo@25: currentUser = user; ingo@25: } ingo@25: ingo@25: ingo@25: /** ingo@28: * Returns the project list. ingo@28: */ ingo@28: public ProjectList getProjectList() { ingo@28: return projectList; ingo@28: } ingo@28: ingo@28: ingo@28: /** ingo@600: * Returns the projects workspace that contains all project windows. ingo@600: * ingo@600: * @return the FLYSWorkspace. ingo@600: */ ingo@600: public FLYSWorkspace getWorkspace() { ingo@600: return workspace; ingo@600: } ingo@600: ingo@600: ingo@600: /** ingo@29: * Returns a list of rivers supported by the artifact server. ingo@29: * ingo@29: * @return a list of rivers supported by the artifact server. ingo@29: */ ingo@29: public River[] getRivers() { ingo@217: return rivers; ingo@217: } ingo@29: ingo@29: ingo@217: protected void readRivers() { ingo@229: Config config = Config.getInstance(); ingo@229: String locale = config.getLocale(); ingo@229: raimund@1425: riverService.list(locale, new AsyncCallback() { christian@3501: @Override ingo@217: public void onFailure(Throwable caught) { ingo@217: GWT.log("Could not recieve a list of rivers."); christian@4062: SC.warn(getExceptionString(MSG, caught)); ingo@217: } ingo@217: christian@3501: @Override ingo@217: public void onSuccess(River[] newRivers) { ingo@217: GWT.log("Retrieved " + newRivers.length + " new rivers."); ingo@217: rivers = newRivers; ingo@217: } ingo@217: }); ingo@29: } ingo@29: ingo@29: ingo@29: /** ingo@6: * This method creates a new CollectionView and adds it to the workspace. ingo@217: * NOTEThe user needs to be logged in and there need to at least one ingo@217: * river - otherwise a warning is displayed and no CollectionView is ingo@217: * created. ingo@6: */ ingo@6: public void newProject() { ingo@217: if (getCurrentUser() == null) { ingo@217: SC.warn(MSG.error_not_logged_in()); ingo@217: return; ingo@217: } ingo@217: ingo@217: if (getRivers() == null) { ingo@217: SC.warn(MSG.error_no_rivers_found()); ingo@217: readRivers(); ingo@217: ingo@217: return; ingo@217: } ingo@217: ingo@100: CollectionView view = new CollectionView(this); ingo@557: workspace.addView("new-project", view); ingo@97: ingo@97: view.addCollectionChangeHandler(getProjectList()); ingo@9: } ingo@9: ingo@9: ingo@557: protected void lockProject(String uuid) { ingo@557: if (isProjectLocked(uuid)) { ingo@557: return; ingo@557: } ingo@557: ingo@557: openProjects.add(uuid); ingo@557: } ingo@557: ingo@557: ingo@557: protected void unlockProject(String uuid) { ingo@557: openProjects.remove(uuid); ingo@557: } ingo@557: ingo@557: ingo@3549: /** Whether project uuid is currently opened. */ ingo@557: protected boolean isProjectLocked(String uuid) { ingo@557: return openProjects.contains(uuid); ingo@557: } ingo@557: ingo@557: ingo@3549: /** Opens (or bring into foreground) project with given id. */ ingo@557: public void openProject(final String collectionID) { ingo@225: if (collectionID == null) { ingo@225: return; ingo@225: } ingo@225: ingo@557: if (isProjectLocked(collectionID)) { ingo@557: workspace.bringUp(collectionID); ingo@557: return; ingo@557: } ingo@557: ingo@557: lockProject(collectionID); ingo@557: ingo@225: GWT.log("Open existing project: " + collectionID); ingo@225: ingo@229: Config config = Config.getInstance(); ingo@229: final String locale = config.getLocale(); ingo@225: raimund@1425: describeCollectionService.describe(collectionID, locale, ingo@225: new AsyncCallback() { christian@3501: @Override ingo@225: public void onFailure(Throwable caught) { christian@4062: SC.warn(getExceptionString(MSG, caught)); ingo@225: } ingo@225: christian@3501: @Override ingo@225: public void onSuccess(Collection c) { ingo@225: final Collection collection = c; ingo@1294: ingo@1294: if (collection.getItemLength() == 0) { ingo@1294: CollectionView view = new CollectionView( ingo@1294: FLYS.this, collection, null); ingo@1294: ingo@1294: view.addCollectionChangeHandler( ingo@1294: getProjectList()); ingo@1294: view.addCloseClickHandler( ingo@1294: new CloseCollectionViewHandler( ingo@1294: FLYS.this, collectionID)); ingo@1294: ingo@1294: workspace.addView(collectionID, view); ingo@1294: ingo@1294: return; ingo@1294: } ingo@1294: felix@3381: final CollectionItem item = c.getItem(0); ingo@225: ingo@225: if (item == null) { ingo@225: SC.warn(MSG.error_load_parameterization()); ingo@225: return; ingo@225: } ingo@225: ingo@225: getArtifactService.getArtifact( ingo@229: locale, ingo@225: item.identifier(), ingo@225: item.hash(), ingo@225: new AsyncCallback() { christian@3501: @Override ingo@225: public void onFailure(Throwable caught) { ingo@557: unlockProject(collectionID); christian@4062: SC.warn(getExceptionString(MSG, caught)); ingo@225: } ingo@225: christian@3501: @Override ingo@225: public void onSuccess(Artifact artifact) { ingo@225: CollectionView view = new CollectionView( ingo@225: FLYS.this, collection, artifact); ingo@225: ingo@225: view.addCollectionChangeHandler( ingo@225: getProjectList()); ingo@557: view.addCloseClickHandler( ingo@557: new CloseCollectionViewHandler( ingo@557: FLYS.this, collectionID)); ingo@225: ingo@557: workspace.addView(collectionID, view); ingo@225: } ingo@225: }); ingo@225: ingo@225: } ingo@225: }); ingo@225: } ingo@225: ingo@225: ingo@611: public void closeProject(String uuid) { ingo@611: unlockProject(uuid); ingo@611: workspace.destroyProject(uuid); ingo@611: } ingo@611: ingo@611: ingo@9: /** ingo@9: * Create a new Artifact. ingo@9: */ ingo@9: public void newArtifact(String factory) { ingo@229: Config config = Config.getInstance(); ingo@229: String locale = config.getLocale(); ingo@14: raimund@1425: artifactService.create(locale, factory, null, ingo@229: new AsyncCallback() { christian@3501: @Override ingo@229: public void onFailure(Throwable caught) { ingo@229: GWT.log("Could not create the new artifact."); christian@4062: SC.warn(getExceptionString(MSG, caught)); ingo@229: } ingo@9: christian@3501: @Override ingo@229: public void onSuccess(Artifact artifact) { ingo@229: GWT.log("Successfully created a new artifact."); ingo@229: } ingo@9: }); ingo@6: } ingo@557: felix@4981: felix@4981: /** Opens a window with Main Values from gauge. */ felix@4981: public void newGaugeMainValueTable(GaugeInfo gauge) { felix@4981: Window mainValueView = new Window(); felix@4990: felix@4990: // Take middle to avoid issues at borders. felix@4990: double km = (gauge.getKmEnd() + gauge.getKmStart())/2d; felix@4985: mainValueView.addItem(new WQAutoTabSet(gauge.getRiverName(), felix@4990: new double[] {km, km})); rrenkert@5033: mainValueView.setWidth(450); rrenkert@5033: mainValueView.setHeight(600); felix@4981: rrenkert@5033: mainValueView.setMaximized(false); rrenkert@5033: mainValueView.centerInPage(); felix@4981: mainValueView.setCanDragReposition(true); felix@4981: mainValueView.setCanDragResize(true); felix@4981: mainValueView.setShowMaximizeButton(true); felix@4981: mainValueView.setKeepInParentRect(true); felix@4981: felix@4985: mainValueView.setTitle(MSG.mainvalues() + " " + gauge.getName() + " (" + gauge.getRiverName() + ")" ); felix@4981: workspace.addChild(mainValueView); felix@4981: } felix@4981: bjoern@3865: public void newGaugeDischargeCurve(String river, Long gaugeref) { bjoern@3865: Config config = Config.getInstance(); bjoern@3865: bjoern@3865: final String locale = config.getLocale(); bjoern@3865: final String riv = river; bjoern@3865: final Long ref = gaugeref; bjoern@3865: final FLYS flys = this; bjoern@3865: bjoern@3865: User user = getCurrentUser(); bjoern@3865: bjoern@3865: if (user == null) { bjoern@3865: SC.warn(MSG.error_not_logged_in()); bjoern@3865: return; bjoern@3865: } bjoern@3865: bjoern@3865: collectionService.create(locale, user.identifier(), bjoern@3865: new AsyncCallback() { bjoern@3865: @Override bjoern@3865: public void onFailure(Throwable caught) { bjoern@3865: GWT.log("Could not create new collection."); christian@4062: SC.warn(getExceptionString(MSG, caught)); bjoern@3865: } bjoern@3865: bjoern@3865: @Override bjoern@3865: public void onSuccess(Collection collection) { bjoern@3865: GWT.log("Successfully created a new collection."); bjoern@3865: final Collection col = collection; bjoern@3980: artifactService.createGaugeDischargeCurveArtifact( bjoern@3865: col, locale, riv, ref, bjoern@3865: new AsyncCallback() { bjoern@3865: @Override bjoern@3865: public void onFailure(Throwable caught) { bjoern@3865: GWT.log("Could not create the new artifact."); christian@4062: SC.warn(getExceptionString(MSG, caught)); bjoern@3865: } bjoern@3865: bjoern@3865: @Override bjoern@3865: public void onSuccess(Artifact artifact) { bjoern@3865: GWT.log("Successfully created a new artifact."); bjoern@3865: CollectionView view = new CollectionView(flys, bjoern@3865: col, artifact); bjoern@4141: workspace.addView(col.identifier(), view); bjoern@3865: bjoern@3865: view.addCollectionChangeHandler(getProjectList()); bjoern@4141: view.addCloseClickHandler( bjoern@4141: new CloseCollectionViewHandler( bjoern@4141: FLYS.this, col.identifier())); bjoern@4141: projectList.updateUserCollections(); bjoern@3865: } bjoern@3865: }); bjoern@3865: } bjoern@3865: }); bjoern@3865: } ingo@557: rrenkert@5503: public void newSQRelation(String river, int measurementStation) { rrenkert@5503: Config config = Config.getInstance(); rrenkert@5503: rrenkert@5503: final String locale = config.getLocale(); rrenkert@5503: final String riv = river; rrenkert@5503: final int mStation = measurementStation; rrenkert@5503: final FLYS flys = this; rrenkert@5503: rrenkert@5503: User user = getCurrentUser(); rrenkert@5503: rrenkert@5503: if (user == null) { rrenkert@5503: SC.warn(MSG.error_not_logged_in()); rrenkert@5503: return; rrenkert@5503: } rrenkert@5503: rrenkert@5503: collectionService.create(locale, user.identifier(), rrenkert@5503: new AsyncCallback() { rrenkert@5503: @Override rrenkert@5503: public void onFailure(Throwable caught) { rrenkert@5503: GWT.log("Could not create new collection."); rrenkert@5503: SC.warn(getExceptionString(MSG, caught)); rrenkert@5503: } rrenkert@5503: rrenkert@5503: @Override rrenkert@5503: public void onSuccess(Collection collection) { rrenkert@5503: GWT.log("Successfully created a new collection."); rrenkert@5503: final Collection col = collection; rrenkert@5503: artifactService.createSQRelationArtifact( rrenkert@5503: col, locale, riv, mStation, rrenkert@5503: new AsyncCallback() { rrenkert@5503: @Override rrenkert@5503: public void onFailure(Throwable caught) { rrenkert@5503: GWT.log("Could not create the new artifact."); rrenkert@5503: SC.warn(getExceptionString(MSG, caught)); rrenkert@5503: } rrenkert@5503: rrenkert@5503: @Override rrenkert@5503: public void onSuccess(Artifact artifact) { rrenkert@5503: GWT.log("Successfully created a new artifact."); rrenkert@5503: CollectionView view = new CollectionView(flys, rrenkert@5503: col, artifact); rrenkert@5503: workspace.addView(col.identifier(), view); rrenkert@5503: rrenkert@5503: view.addCollectionChangeHandler(getProjectList()); rrenkert@5503: view.addCloseClickHandler( rrenkert@5503: new CloseCollectionViewHandler( rrenkert@5503: FLYS.this, col.identifier())); rrenkert@5503: projectList.updateUserCollections(); rrenkert@5503: } rrenkert@5503: }); rrenkert@5503: } rrenkert@5503: }); rrenkert@5503: } rrenkert@5503: christian@3501: @Override ingo@611: public void onCollectionChange(CollectionChangeEvent event) { ingo@611: Collection oldC = event.getOldValue(); ingo@611: ingo@611: if (oldC == null) { ingo@611: Collection newC = event.getNewValue(); ingo@611: lockProject(newC.identifier()); ingo@611: } ingo@611: } ingo@611: ingo@611: ingo@557: ingo@557: /** ingo@557: * This CloseClickHandler is used to remove lock on a specific Collection so ingo@557: * that is might be opened again. ingo@557: */ ingo@611: public class CloseCollectionViewHandler implements CloseClickHandler { ingo@557: protected FLYS flys; ingo@557: protected String uuid; ingo@557: ingo@557: public CloseCollectionViewHandler(FLYS flys, String uuid) { ingo@557: this.flys = flys; ingo@557: this.uuid = uuid; ingo@557: } ingo@557: christian@3501: @Override raimund@1619: public void onCloseClick(CloseClickEvent event) { ingo@611: flys.closeProject(uuid); ingo@557: } ingo@557: } bjoern@4601: bjoern@4601: public boolean isProjectListVisible() { bjoern@4601: if (this.projectList == null) { bjoern@4601: return true; bjoern@4601: } bjoern@4601: return this.projectList.isVisible(); bjoern@4601: } bjoern@4601: bjoern@4601: public void hideProjectList() { bjoern@4601: if (this.projectList != null) { bjoern@4601: this.projectList.hide(); bjoern@4601: } bjoern@4601: } bjoern@4601: bjoern@4601: public void openProjectList() { bjoern@4601: if (this.projectList != null) { bjoern@4601: this.projectList.show(); bjoern@4601: } bjoern@4601: } bjoern@4604: bjoern@4604: public void hideHeaderProjectButton() { bjoern@4604: this.header.hideProjectButton(); bjoern@4604: } bjoern@4604: bjoern@4604: public void shoHeaderProjectButton() { bjoern@4604: this.header.showProjectButton(); bjoern@4604: } ingo@0: } ingo@1: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :