ingo@6: package de.intevation.flys.client.client.ui; ingo@6: ingo@19: import java.util.ArrayList; ingo@74: import java.util.HashMap; ingo@19: import java.util.List; ingo@74: import java.util.Map; ingo@74: import java.util.Set; ingo@809: import java.util.Stack; ingo@19: ingo@6: import com.google.gwt.core.client.GWT; ingo@13: import com.google.gwt.user.client.rpc.AsyncCallback; ingo@6: ingo@215: import com.smartgwt.client.util.SC; ingo@6: import com.smartgwt.client.widgets.Window; ingo@557: import com.smartgwt.client.widgets.events.CloseClientEvent; ingo@557: import com.smartgwt.client.widgets.events.CloseClickHandler; ingo@23: import com.smartgwt.client.widgets.layout.Layout; ingo@7: import com.smartgwt.client.widgets.layout.VLayout; ingo@23: import com.smartgwt.client.widgets.tab.TabSet; raimund@915: import com.smartgwt.client.widgets.tab.events.TabSelectedHandler; ingo@6: ingo@13: import de.intevation.flys.client.shared.model.Artifact; ingo@23: import de.intevation.flys.client.shared.model.ArtifactDescription; ingo@6: import de.intevation.flys.client.shared.model.Collection; ingo@270: import de.intevation.flys.client.shared.model.ExportMode; ingo@71: import de.intevation.flys.client.shared.model.OutputMode; ingo@807: import de.intevation.flys.client.shared.model.Recommendation; ingo@593: import de.intevation.flys.client.shared.model.ReportMode; ingo@71: import de.intevation.flys.client.shared.model.User; ingo@6: ingo@14: import de.intevation.flys.client.client.Config; ingo@13: import de.intevation.flys.client.client.FLYS; ingo@211: import de.intevation.flys.client.client.FLYSConstants; ingo@19: import de.intevation.flys.client.client.event.HasCollectionChangeHandlers; ingo@513: import de.intevation.flys.client.client.event.HasOutputModesChangeHandlers; ingo@19: import de.intevation.flys.client.client.event.CollectionChangeEvent; ingo@36: import de.intevation.flys.client.client.event.CollectionChangeHandler; ingo@513: import de.intevation.flys.client.client.event.OutputModesChangeEvent; ingo@513: import de.intevation.flys.client.client.event.OutputModesChangeHandler; ingo@36: import de.intevation.flys.client.client.event.ParameterChangeEvent; ingo@36: import de.intevation.flys.client.client.event.ParameterChangeHandler; ingo@803: import de.intevation.flys.client.client.services.ArtifactService; ingo@803: import de.intevation.flys.client.client.services.ArtifactServiceAsync; ingo@71: import de.intevation.flys.client.client.services.AddArtifactService; ingo@71: import de.intevation.flys.client.client.services.AddArtifactServiceAsync; ingo@809: import de.intevation.flys.client.client.services.CollectionAttributeService; ingo@809: import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync; ingo@26: import de.intevation.flys.client.client.services.CreateCollectionService; ingo@26: import de.intevation.flys.client.client.services.CreateCollectionServiceAsync; ingo@100: import de.intevation.flys.client.client.services.DescribeCollectionService; ingo@100: import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync; ingo@6: ingo@6: ingo@6: /** ingo@6: * @author Ingo Weinzierl ingo@6: */ ingo@19: public class CollectionView ingo@19: extends Window ingo@23: implements CollectionChangeHandler, HasCollectionChangeHandlers, ingo@513: OutputModesChangeHandler, HasOutputModesChangeHandlers, ingo@557: ParameterChangeHandler, CloseClickHandler ingo@23: { ingo@13: /** The ArtifactService used to communicate with the Artifact server. */ ingo@26: protected CreateCollectionServiceAsync createCollectionService = ingo@26: GWT.create(CreateCollectionService.class); ingo@26: ingo@803: /** The ArtifactService used to communicate with the Artifact server. */ ingo@803: protected ArtifactServiceAsync createArtifactService = ingo@803: GWT.create(ArtifactService.class); ingo@803: ingo@71: /** The AddArtifactService used to add an artifact to a collection. */ ingo@71: protected AddArtifactServiceAsync addArtifactService = ingo@71: GWT.create(AddArtifactService.class); ingo@71: ingo@100: /** The DescribeCollectionService used to update the existing collection. */ ingo@100: protected DescribeCollectionServiceAsync describeCollectionService = ingo@100: GWT.create(DescribeCollectionService.class); ingo@100: ingo@809: protected CollectionAttributeServiceAsync updater = ingo@809: GWT.create(CollectionAttributeService.class); ingo@809: felix@864: /** The message class that provides i18n strings. */ ingo@211: protected FLYSConstants messages = GWT.create(FLYSConstants.class); ingo@6: felix@864: /** The FLYS instance used to call services. */ ingo@13: protected FLYS flys; ingo@13: felix@864: /** The ParameterList. */ ingo@23: protected ParameterList parameterList; ingo@23: felix@864: /** The list of CollectionChangeHandlers. */ ingo@19: protected List handlers; ingo@19: felix@864: /** The list of OutputModesChangeHandlers. */ ingo@513: protected List outHandlers; ingo@513: felix@864: /** The collection to be displayed. */ ingo@6: protected Collection collection; ingo@6: felix@864: /** The artifact that handles the parameterization. */ ingo@30: protected Artifact artifact; ingo@30: ingo@23: protected TabSet tabs; ingo@23: felix@864: /** The output tab. */ ingo@74: protected Map outputTabs; ingo@7: felix@864: /** The layout. */ ingo@23: protected Layout layout; ingo@23: ingo@809: protected int artifactsQueue; ingo@809: protected Stack newRecommendations; ingo@809: ingo@6: ingo@6: /** ingo@6: * This constructor creates a new CollectionView that is used to display the ingo@6: * collection. ingo@6: * ingo@6: * @param collection The collection to be displayed. ingo@6: */ ingo@100: public CollectionView(FLYS flys) { ingo@908: // do this first because it takes longer than the other stuff in here. ingo@908: User user = flys.getCurrentUser(); ingo@908: createNewCollection(user.identifier()); ingo@908: ingo@100: this.flys = flys; ingo@100: this.tabs = new TabSet(); ingo@100: this.outputTabs = new HashMap(); ingo@100: this.handlers = new ArrayList(); ingo@513: this.outHandlers = new ArrayList(); ingo@100: this.layout = new VLayout(); ingo@100: this.parameterList = new ParameterList( raimund@92: flys, this, messages.new_project()); ingo@809: this.artifactsQueue = 0; ingo@809: this.newRecommendations = new Stack(); ingo@19: ingo@19: addCollectionChangeHandler(this); ingo@275: addCollectionChangeHandler(parameterList); ingo@611: addCollectionChangeHandler(flys); ingo@513: addOutputModesChangeHandler(this); ingo@513: addOutputModesChangeHandler(parameterList); ingo@557: addCloseClickHandler(this); ingo@73: ingo@73: parameterList.addParameterChangeHandler(this); ingo@19: ingo@6: init(); ingo@6: } ingo@6: ingo@6: ingo@224: public CollectionView(FLYS flys, Collection collection, Artifact artifact) { ingo@224: this.flys = flys; ingo@825: this.artifact = artifact; ingo@825: this.collection = collection; ingo@224: this.tabs = new TabSet(); ingo@224: this.outputTabs = new HashMap(); ingo@224: this.handlers = new ArrayList(); ingo@513: this.outHandlers = new ArrayList(); ingo@224: this.layout = new VLayout(); ingo@224: this.parameterList = new ParameterList( ingo@224: flys, ingo@224: this, ingo@228: messages.getString(artifact.getName()), ingo@224: artifact); ingo@809: this.artifactsQueue = 0; ingo@809: this.newRecommendations = new Stack(); ingo@224: ingo@224: addCollectionChangeHandler(this); ingo@275: addCollectionChangeHandler(parameterList); ingo@611: addCollectionChangeHandler(flys); ingo@513: addOutputModesChangeHandler(this); ingo@513: addOutputModesChangeHandler(parameterList); ingo@557: addCloseClickHandler(this); ingo@224: ingo@224: parameterList.addParameterChangeHandler(this); ingo@224: ingo@224: init(); ingo@224: ingo@224: setCollection(collection); ingo@224: setArtifact(artifact); ingo@224: } ingo@224: ingo@224: ingo@6: /** ingo@6: * This method handles the initial layout stuff. ingo@6: */ ingo@6: protected void init() { raimund@91: setWidth(750); ingo@39: setHeight(600); ingo@6: ingo@23: layout.setWidth100(); ingo@23: raimund@77: setCanDragReposition(true); ingo@6: setCanDragResize(true); ingo@437: setShowMaximizeButton(true); raimund@77: setKeepInParentRect(true); ingo@6: ingo@84: setTitle(""); ingo@7: ingo@7: addItem(layout); ingo@7: ingo@23: layout.addMember(tabs); ingo@90: tabs.addTab(parameterList); ingo@7: } ingo@7: ingo@7: ingo@7: /** ingo@26: * This method triggers the CreateCollectionService to create a new ingo@26: * collection in the artifact server. ingo@26: * ingo@26: * @param ownerId The uuid of the user that should own the new collection. ingo@26: */ ingo@26: protected void createNewCollection(String ownerId) { ingo@100: GWT.log("CollectionView.createNewCollection"); ingo@100: ingo@229: Config config = Config.getInstance(); ingo@229: final String url = config.getServerUrl(); ingo@229: final String locale = config.getLocale(); ingo@26: ingo@26: createCollectionService.create( ingo@229: url, locale, ownerId, ingo@71: new AsyncCallback() { ingo@26: public void onFailure(Throwable caught) { ingo@26: GWT.log("Could not create the new collection."); ingo@215: SC.warn(messages.getString(caught.getMessage())); ingo@26: } ingo@26: ingo@71: public void onSuccess(Collection collection) { ingo@26: GWT.log("Successfully created a new collection."); ingo@803: setCollection(collection); ingo@26: } ingo@26: }); ingo@26: } ingo@26: ingo@26: ingo@26: protected FLYS getFlys() { ingo@26: return flys; ingo@26: } ingo@26: ingo@26: ingo@26: /** felix@864: * This method registers a new CollectionChangeHandler. ingo@19: * felix@864: * @param handler The new CollectionChangeHandler. ingo@19: */ ingo@19: public void addCollectionChangeHandler(CollectionChangeHandler handler) { ingo@19: if (handler != null) { ingo@19: handlers.add(handler); ingo@19: } ingo@19: } ingo@19: ingo@19: ingo@513: /** ingo@513: * This method registers a new OutputModesChangeHandler. ingo@513: * ingo@513: * @param handler The new OutputModesChangeHandler. ingo@513: */ ingo@513: public void addOutputModesChangeHandler(OutputModesChangeHandler handler) { ingo@513: if (handler != null) { ingo@513: outHandlers.add(handler); ingo@513: } ingo@513: } ingo@513: ingo@513: ingo@36: /** ingo@19: * This method calls the onValueChange() method of all ingo@19: * registered ValueChangeHanders. ingo@19: */ ingo@19: protected void fireCollectionChangeEvent( ingo@19: Collection old, Collection newCol) ingo@19: { ingo@19: for (CollectionChangeHandler handler: handlers) { ingo@19: handler.onCollectionChange(new CollectionChangeEvent(old, newCol)); ingo@19: } ingo@19: } ingo@19: ingo@19: ingo@513: protected void fireOutputModesChangeEvent(OutputMode[] outputs) { ingo@513: if (collection == null) { ingo@513: return; ingo@513: } ingo@513: ingo@513: for (OutputModesChangeHandler handler: outHandlers) { ingo@513: handler.onOutputModesChange(new OutputModesChangeEvent(outputs)); ingo@513: } ingo@513: } ingo@513: ingo@513: ingo@19: /** ingo@7: * This method returns true, if the Collection is new and no plugins has ingo@7: * been chosen. ingo@7: * ingo@7: * @return true, if the Collection is new. ingo@7: */ ingo@7: public boolean isNew() { sascha@582: return collection.getItemLength() == 0; ingo@7: } ingo@7: ingo@7: ingo@7: /** ingo@71: * Returns the artifact that is used for the parameterization. ingo@71: * ingo@71: * @return the artifact that is used for the parameterization. ingo@71: */ ingo@521: public Artifact getArtifact() { ingo@71: return artifact; ingo@71: } ingo@71: felix@864: sascha@811: public User getUser() { sascha@811: return getFlys().getCurrentUser(); sascha@811: } sascha@811: ingo@71: ingo@71: /** ingo@30: * Set the current artifact that is the master of the parameterization. ingo@30: * ingo@30: * @param artifact The new artifact. ingo@30: */ ingo@521: public void setArtifact(Artifact artifact) { ingo@30: this.artifact = artifact; ingo@862: ingo@862: onArtifactChanged(artifact); ingo@862: } ingo@862: ingo@862: ingo@862: public void onArtifactChanged(Artifact artifact) { ingo@862: if (artifact.isInBackground()) { ingo@862: new LoadingPanel(this, artifact); ingo@862: } ingo@36: } ingo@36: ingo@36: ingo@36: /** ingo@36: * Implements the onCollectionChange() method to do update the GUI after the ingo@36: * parameterization has changed. ingo@36: * ingo@36: * @param event The ParameterChangeEvent. ingo@36: */ ingo@36: public void onParameterChange(ParameterChangeEvent event) { ingo@100: GWT.log("CollectionView.onParameterChange"); ingo@100: ingo@71: Artifact art = event.getNewValue(); ingo@71: ArtifactDescription desc = art.getArtifactDescription(); ingo@71: OutputMode[] outs = desc.getOutputModes(); ingo@807: Recommendation[] recom = desc.getRecommendations(); ingo@803: ingo@73: setArtifact(art); ingo@73: ingo@229: Collection c = getCollection(); ingo@100: felix@841: if (recom != null && collection != null) { felix@841: loadRecommendedArtifacts(recom); felix@841: } felix@841: ingo@908: if (c != null) { ingo@100: Config config = Config.getInstance(); ingo@100: String url = config.getServerUrl(); ingo@229: String locale = config.getLocale(); ingo@100: ingo@229: describeCollectionService.describe(c.identifier(), url, locale, ingo@100: new AsyncCallback() { ingo@100: public void onFailure(Throwable caught) { ingo@100: GWT.log("Could not DESCRIBE collection."); ingo@215: SC.warn(messages.getString(caught.getMessage())); ingo@100: } ingo@100: ingo@100: ingo@100: public void onSuccess(Collection newCollection) { ingo@100: GWT.log("Successfully DESCRIBED collection."); ingo@100: setCollection(newCollection); ingo@100: } ingo@100: } ingo@100: ); ingo@100: } ingo@71: else { ingo@71: updateView(); ingo@71: } ingo@6: } ingo@13: ingo@13: ingo@13: /** ingo@74: * Returns the collection of displayed by this view. ingo@74: * ingo@74: * @return the collection of this view. ingo@74: */ ingo@537: public Collection getCollection() { ingo@74: return collection; ingo@74: } ingo@74: ingo@74: ingo@908: protected void setCollection(Collection collection) { ingo@908: setCollection(collection, false); ingo@908: } ingo@908: ingo@908: ingo@74: /** ingo@19: * Set the current collection. ingo@13: * ingo@19: * @param collection The new collection. ingo@13: */ ingo@908: protected void setCollection(Collection collection, boolean suppress) { ingo@601: if (collection != null && this.collection == null) { ingo@601: flys.getWorkspace().addView(collection.identifier(), this); ingo@601: } ingo@601: ingo@19: Collection tmp = this.collection; ingo@19: this.collection = collection; ingo@13: felix@820: setTitle(collection.getName() + " (UUID: " + collection.identifier() + ")"); ingo@908: ingo@908: if (!suppress) { ingo@908: fireCollectionChangeEvent(tmp, this.collection); ingo@908: } ingo@19: } ingo@19: ingo@19: ingo@19: public void onCollectionChange(CollectionChangeEvent event) { ingo@809: if (artifactsQueue > 0) { ingo@809: GWT.log("Do not update UI because we are still loading Artifacts."); ingo@809: return; ingo@809: } ingo@809: ingo@74: Collection newCol = event.getNewValue(); ingo@74: ingo@74: Map outs = newCol.getOutputModes(); ingo@74: ingo@513: Set keys = outs.keySet(); ingo@513: OutputMode[] prepared = new OutputMode[outs.size()]; ingo@513: ingo@513: int idx = 0; ingo@74: for (String outname: keys) { ingo@513: prepared[idx++] = outs.get(outname); ingo@74: } ingo@74: ingo@513: fireOutputModesChangeEvent(prepared); ingo@513: ingo@13: updateView(); ingo@13: } ingo@13: ingo@13: ingo@513: public void onOutputModesChange(OutputModesChangeEvent event) { ingo@788: clearOutputTabs(); ingo@513: OutputMode[] outs = event.getOutputModes(); ingo@513: ingo@513: if (outs == null) { ingo@513: return; ingo@513: } ingo@513: ingo@788: boolean hasCSV = false; ingo@788: ingo@513: for (OutputMode out: outs) { ingo@513: addOutputTab(out.getName(), out); ingo@788: ingo@788: if (out instanceof ExportMode) { ingo@788: ExportMode export = (ExportMode) out; ingo@788: ingo@788: if (export.getFacet("csv") != null) { ingo@788: hasCSV = true; ingo@788: } ingo@788: } ingo@788: } ingo@788: ingo@788: if (!hasCSV) { ingo@788: parameterList.removeTable(); ingo@513: } ingo@513: } ingo@513: ingo@513: ingo@36: /** ingo@74: * Adds a new tab for the OutputMode out. ingo@74: * ingo@74: * @param name The name and title of the output. ingo@74: */ ingo@74: protected void addOutputTab(String name, OutputMode out) { ingo@270: if (out instanceof ExportMode) { ingo@270: ExportMode export = (ExportMode) out; raimund@256: ingo@788: if (export.getFacet("csv") != null && !parameterList.hasTable()) { ingo@270: TableDataPanel p = new TableDataPanel(); ingo@270: p.setUuid(collection.identifier()); ingo@270: p.setName(out.getName()); ingo@788: parameterList.setTable(p); ingo@270: } ingo@270: ingo@239: return; ingo@239: } ingo@239: ingo@593: if (out instanceof ReportMode) { ingo@593: // we don't want to display report modes at all ingo@593: return; ingo@593: } ingo@593: ingo@74: GWT.log("Add new output tab for '" + name + "'"); ingo@75: ingo@796: String title = messages.getString(name); ingo@796: OutputTab tab = out.createOutputTab(title, getCollection(), this); ingo@796: ingo@796: if (tab != null) { ingo@796: outputTabs.put(name, tab); ingo@796: } ingo@74: } ingo@74: ingo@74: ingo@74: /** ingo@74: * Removes all output mode tabs from tab bar. ingo@74: */ ingo@74: protected void clearOutputTabs() { ingo@74: GWT.log("Clear OutputTabs."); ingo@74: ingo@74: int num = tabs.getNumTabs(); ingo@74: ingo@74: for (int i = num-1; i >= 1; i--) { ingo@74: tabs.removeTab(i); ingo@74: } ingo@74: ingo@74: outputTabs.clear(); ingo@74: } ingo@74: ingo@74: ingo@74: /** ingo@23: * Update the view (refresh the list of old and current data). ingo@23: */ ingo@13: protected void updateView() { ingo@36: GWT.log("CollectionView.updateView()"); ingo@74: updateOutputTabs(); ingo@74: } ingo@23: ingo@74: ingo@74: /** ingo@74: * This method is used to update the tabs to show specific output modes. ingo@74: */ ingo@74: protected void updateOutputTabs() { ingo@74: GWT.log("Update output tabs."); ingo@74: if (outputTabs != null) { ingo@74: Set keys = outputTabs.keySet(); ingo@74: ingo@74: for (String key: keys) { ingo@74: tabs.addTab(outputTabs.get(key)); ingo@74: } ingo@74: } ingo@13: } ingo@557: ingo@557: ingo@557: public void onCloseClick(CloseClientEvent event) { ingo@611: if (collection != null) { ingo@611: flys.closeProject(collection.identifier()); ingo@611: } ingo@611: else { ingo@611: hide(); ingo@611: destroy(); ingo@611: } ingo@557: } ingo@803: ingo@803: ingo@908: public void addArtifactToCollection(final Artifact artifact) { ingo@803: Config config = Config.getInstance(); ingo@803: final String url = config.getServerUrl(); ingo@803: final String locale = config.getLocale(); ingo@803: final Collection collection = getCollection(); ingo@803: ingo@809: artifactsQueue++; ingo@809: ingo@803: addArtifactService.add( ingo@803: collection, artifact, url, locale, ingo@803: new AsyncCallback() { ingo@803: public void onFailure(Throwable caught) { ingo@803: GWT.log("An error occured while adding artifact."); ingo@809: artifactsQueue--; ingo@803: SC.warn(messages.getString(caught.getMessage())); ingo@803: } ingo@803: ingo@803: public void onSuccess(Collection newCollection) { ingo@803: GWT.log("Successfully added artifact."); ingo@803: setCollection(newCollection); ingo@809: ingo@809: artifactsQueue--; ingo@809: addRecommendationsToCollection(); ingo@809: } ingo@809: } ingo@809: ); ingo@809: } ingo@809: ingo@809: ingo@809: protected void addRecommendationsToCollection() { ingo@809: Config config = Config.getInstance(); ingo@809: final String url = config.getServerUrl(); ingo@809: final String locale = config.getLocale(); ingo@809: final Collection collection = getCollection(); ingo@809: ingo@809: collection.addRecommendations(newRecommendations); ingo@809: ingo@809: updater.update(collection, url, locale, ingo@809: new AsyncCallback() { ingo@809: public void onFailure(Throwable caught) { ingo@809: newRecommendations.removeAllElements(); ingo@809: setCollection(collection); ingo@809: ingo@809: GWT.log("An error occured while saving recommendations."); ingo@809: // TODO POPUP WARNING ingo@809: } ingo@809: ingo@809: public void onSuccess(Collection newCol) { ingo@809: GWT.log("Successfully saved recommendations."); ingo@809: newRecommendations.removeAllElements(); ingo@809: setCollection(newCol); ingo@803: } ingo@803: } ingo@803: ); ingo@803: } ingo@803: ingo@803: ingo@807: protected void loadRecommendedArtifacts(Recommendation[] recommendations) { ingo@803: Config config = Config.getInstance(); ingo@803: final String url = config.getServerUrl(); ingo@803: final String locale = config.getLocale(); ingo@803: final Collection collection = getCollection(); ingo@803: sascha@847: sascha@847: Artifact masterArtifact = getArtifact(); sascha@847: sascha@847: felix@819: if (recommendations == null) { felix@819: GWT.log("WARNING: Currently no recommendations."); felix@819: return; felix@819: } felix@819: ingo@809: for (final Recommendation recommendation: recommendations) { ingo@809: if (collection.loadedRecommendation(recommendation)) { ingo@809: continue; ingo@809: } ingo@809: sascha@847: // XXX: UGLY! If no reference artifact given use uuid of sascha@847: // current artifact as reference. sascha@847: if (recommendation.getMasterArtifact() == null) { sascha@847: recommendation.setMasterArtifact(masterArtifact.getUuid()); sascha@847: } sascha@847: ingo@807: final String factory = recommendation.getFactory(); ingo@809: ingo@807: GWT.log("Load recommended artifact with factory: " + factory); ingo@807: ingo@807: createArtifactService.create( sascha@845: url, locale, factory, recommendation, ingo@803: new AsyncCallback() { ingo@803: public void onFailure(Throwable caught) { ingo@803: GWT.log("Error loading recommendations: " + ingo@803: caught.getMessage()); ingo@803: } ingo@803: ingo@803: public void onSuccess(Artifact artifact) { ingo@803: GWT.log("Created new artifact: " + artifact.getUuid()); ingo@803: addArtifactToCollection(artifact); ingo@809: newRecommendations.push(recommendation); ingo@803: } ingo@803: }); ingo@803: } ingo@803: } raimund@915: raimund@915: raimund@915: public void registerTabHandler(TabSelectedHandler tse) { raimund@915: tabs.addTabSelectedHandler(tse); raimund@915: } ingo@6: } ingo@6: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :