ingo@0: package de.intevation.flys.client.client; ingo@0: ingo@557: import java.util.ArrayList; ingo@557: import java.util.List; ingo@605: import java.util.Set; ingo@557: 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; ingo@1: ingo@217: import com.smartgwt.client.util.SC; ingo@605: import com.smartgwt.client.widgets.Window; ingo@605: import com.smartgwt.client.widgets.HTMLPane; ingo@1: import com.smartgwt.client.widgets.layout.VLayout; raimund@80: import com.smartgwt.client.widgets.layout.HLayout; ingo@557: import com.smartgwt.client.widgets.events.CloseClickHandler; ingo@557: import com.smartgwt.client.widgets.events.CloseClientEvent; ingo@1: ingo@9: import de.intevation.flys.client.shared.model.Artifact; ingo@225: import de.intevation.flys.client.shared.model.Collection; ingo@225: import de.intevation.flys.client.shared.model.CollectionItem; ingo@29: import de.intevation.flys.client.shared.model.River; ingo@25: import de.intevation.flys.client.shared.model.User; 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; 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@1: import de.intevation.flys.client.client.ui.MainMenu; ingo@4: import de.intevation.flys.client.client.ui.ProjectList; raimund@80: import de.intevation.flys.client.client.ui.FLYSFooter; 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: ingo@225: ingo@4: /** The menu bar at the top of the application.*/ ingo@2: protected MainMenu menu; ingo@4: ingo@4: /** The content window. It takes the whole space beneath the menu bar.*/ ingo@2: protected FLYSView view; ingo@2: ingo@4: /** The project list that displays the projects of the user.*/ ingo@4: protected ProjectList projectList; ingo@4: ingo@6: /** The FLYSWorkspace.*/ ingo@6: protected FLYSWorkspace workspace; ingo@6: raimund@80: /** The footer. */ raimund@80: protected FLYSFooter footer; raimund@80: ingo@25: /** The user who is currently logged in.*/ ingo@25: protected User currentUser; ingo@25: ingo@29: /** The list of rivers supported by the server.*/ ingo@29: protected River[] rivers; ingo@29: ingo@557: /** This list is used to track the opened projects.*/ ingo@557: protected List openProjects; ingo@557: ingo@2: ingo@1: /** ingo@1: * This is the entry point method. ingo@1: */ 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: raimund@80: HLayout spacerBar = new HLayout(); raimund@80: spacerBar.setWidth("100%"); raimund@80: spacerBar.setHeight("20px"); raimund@80: spacerBar.setStyleName("bgBlueLight"); raimund@80: ingo@6: menu = new MainMenu(this); ingo@2: view = new FLYSView(); raimund@80: footer = new FLYSFooter(this); ingo@1: ingo@27: vertical.addMember(new FLYSHeader()); ingo@1: vertical.addMember(menu); raimund@80: vertical.addMember(spacerBar); ingo@1: vertical.addMember(view); raimund@80: vertical.addMember(footer); ingo@1: ingo@797: vertical.draw(); ingo@2: ingo@9: initConfiguration(); ingo@229: ingo@229: Config config = Config.getInstance(); ingo@229: String url = config.getServerUrl(); ingo@229: String locale = config.getLocale(); ingo@9: ingo@29: getRivers(); ingo@29: ingo@229: userService.getCurrentUser(url, locale, new AsyncCallback() { ingo@2: public void onFailure(Throwable caught) { ingo@2: GWT.log("Could not find a logged in user."); ingo@217: SC.warn(MSG.getString(caught.getMessage())); ingo@2: } ingo@2: ingo@2: public void onSuccess(User user) { ingo@25: GWT.log("Found a user. Set '"+ user.getName() + "'"); ingo@25: setCurrentUser(user); ingo@25: ingo@2: menu.setCurrentUser(user); ingo@4: ingo@225: projectList = new ProjectList(FLYS.this, user); ingo@6: workspace = new FLYSWorkspace(); 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 url = config.getServerUrl(); ingo@229: String locale = config.getLocale(); ingo@229: ingo@217: GWT.log("Fetch rivers from server '" + url + "'"); ingo@29: ingo@229: riverService.list(url, locale, new AsyncCallback() { ingo@217: public void onFailure(Throwable caught) { ingo@217: GWT.log("Could not recieve a list of rivers."); ingo@217: SC.warn(MSG.getString(caught.getMessage())); ingo@217: } ingo@217: 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@557: protected boolean isProjectLocked(String uuid) { ingo@557: return openProjects.contains(uuid); ingo@557: } ingo@557: ingo@557: 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 url = config.getServerUrl(); ingo@229: final String locale = config.getLocale(); ingo@225: ingo@229: describeCollectionService.describe(collectionID, url, locale, ingo@225: new AsyncCallback() { ingo@225: public void onFailure(Throwable caught) { ingo@225: SC.warn(MSG.getString(caught.getMessage())); ingo@225: } ingo@225: ingo@225: public void onSuccess(Collection c) { ingo@225: final Collection collection = c; ingo@225: 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@225: url, ingo@229: locale, ingo@225: item.identifier(), ingo@225: item.hash(), ingo@225: new AsyncCallback() { ingo@225: public void onFailure(Throwable caught) { ingo@557: unlockProject(collectionID); ingo@225: SC.warn(MSG.getString(caught.getMessage())); ingo@225: } ingo@225: 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 url = config.getServerUrl(); ingo@229: String locale = config.getLocale(); ingo@14: ingo@803: artifactService.create(url, locale, factory, null, ingo@229: new AsyncCallback() { ingo@229: public void onFailure(Throwable caught) { ingo@229: GWT.log("Could not create the new artifact."); ingo@229: SC.warn(MSG.getString(caught.getMessage())); ingo@229: } ingo@9: ingo@229: public void onSuccess(Artifact artifact) { ingo@229: GWT.log("Successfully created a new artifact."); ingo@229: } ingo@9: }); ingo@6: } ingo@557: ingo@557: 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: ingo@557: public void onCloseClick(CloseClientEvent event) { ingo@611: flys.closeProject(uuid); ingo@557: } ingo@557: } ingo@0: } ingo@1: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :