changeset 809:e9337488bac3

The Collection now knows its already loaded recommendations - the CollectionView will not load recommendations that have already been loaded before. flys-client/trunk@2397 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 22 Jul 2011 12:23:36 +0000
parents 3187b268b311
children a443dd6566b8
files flys-client/ChangeLog flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java flys-client/src/main/java/de/intevation/flys/client/shared/model/Collection.java flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java
diffstat 6 files changed, 244 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/flys-client/ChangeLog	Thu Jul 21 16:06:29 2011 +0000
+++ b/flys-client/ChangeLog	Fri Jul 22 12:23:36 2011 +0000
@@ -1,3 +1,23 @@
+2011-07-22  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java,
+	  src/main/java/de/intevation/flys/client/shared/model/Collection.java:
+	  Collections are able to store the recommendations they have already
+	  loaded. Therefore, new methods have been added to add recommendations
+	  and to determine, if a recommendation has already been loaded.
+
+	* src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java:
+	  Read the already loaded recommendations from Collection's DESCRIBE
+	  document.
+
+	* src/main/java/de/intevation/flys/client/server/CollectionHelper.java:
+	  Write the Collection's recommendations into its attribute document.
+
+	* src/main/java/de/intevation/flys/client/client/ui/CollectionView.java:
+	  Two things:
+	   1) Do no load recommendations that have already been loaded before.
+	   2) Update UI when there are no more artifacts to load (recommendations).
+
 2011-07-21  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/client/server/ArtifactDescriptionFactory.java:
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java	Thu Jul 21 16:06:29 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/CollectionView.java	Fri Jul 22 12:23:36 2011 +0000
@@ -5,6 +5,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Stack;
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -41,6 +42,8 @@
 import de.intevation.flys.client.client.services.ArtifactServiceAsync;
 import de.intevation.flys.client.client.services.AddArtifactService;
 import de.intevation.flys.client.client.services.AddArtifactServiceAsync;
+import de.intevation.flys.client.client.services.CollectionAttributeService;
+import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync;
 import de.intevation.flys.client.client.services.CreateCollectionService;
 import de.intevation.flys.client.client.services.CreateCollectionServiceAsync;
 import de.intevation.flys.client.client.services.DescribeCollectionService;
@@ -72,6 +75,9 @@
     protected DescribeCollectionServiceAsync describeCollectionService =
         GWT.create(DescribeCollectionService.class);
 
+    protected CollectionAttributeServiceAsync updater =
+        GWT.create(CollectionAttributeService.class);
+
     /** The message class that provides i18n strings.*/
     protected FLYSConstants messages = GWT.create(FLYSConstants.class);
 
@@ -101,6 +107,9 @@
     /** The layout.*/
     protected Layout layout;
 
+    protected int artifactsQueue;
+    protected Stack<Recommendation> newRecommendations;
+
 
     /**
      * This constructor creates a new CollectionView that is used to display the
@@ -117,6 +126,8 @@
         this.layout        = new VLayout();
         this.parameterList = new ParameterList(
             flys, this, messages.new_project());
+        this.artifactsQueue     = 0;
+        this.newRecommendations = new Stack<Recommendation>();
 
         addCollectionChangeHandler(this);
         addCollectionChangeHandler(parameterList);
@@ -143,6 +154,8 @@
             this,
             messages.getString(artifact.getName()),
             artifact);
+        this.artifactsQueue     = 0;
+        this.newRecommendations = new Stack<Recommendation>();
 
         addCollectionChangeHandler(this);
         addCollectionChangeHandler(parameterList);
@@ -382,6 +395,11 @@
 
 
     public void onCollectionChange(CollectionChangeEvent event) {
+        if (artifactsQueue > 0) {
+            GWT.log("Do not update UI because we are still loading Artifacts.");
+            return;
+        }
+
         Collection newCol = event.getNewValue();
 
         Map<String, OutputMode> outs = newCol.getOutputModes();
@@ -520,17 +538,51 @@
         final String locale         = config.getLocale();
         final Collection collection = getCollection();
 
+        artifactsQueue++;
+
         addArtifactService.add(
             collection, artifact, url, locale,
             new AsyncCallback<Collection>() {
                 public void onFailure(Throwable caught) {
                     GWT.log("An error occured while adding artifact.");
+                    artifactsQueue--;
                     SC.warn(messages.getString(caught.getMessage()));
                 }
 
                 public void onSuccess(Collection newCollection) {
                     GWT.log("Successfully added artifact.");
                     setCollection(newCollection);
+
+                    artifactsQueue--;
+                    addRecommendationsToCollection();
+                }
+            }
+        );
+    }
+
+
+    protected void addRecommendationsToCollection() {
+        Config config               = Config.getInstance();
+        final String url            = config.getServerUrl();
+        final String locale         = config.getLocale();
+        final Collection collection = getCollection();
+
+        collection.addRecommendations(newRecommendations);
+
+        updater.update(collection, url, locale,
+            new AsyncCallback<Collection>() {
+                public void onFailure(Throwable caught) {
+                    newRecommendations.removeAllElements();
+                    setCollection(collection);
+
+                    GWT.log("An error occured while saving recommendations.");
+                    // TODO POPUP WARNING
+                }
+
+                public void onSuccess(Collection newCol) {
+                    GWT.log("Successfully saved recommendations.");
+                    newRecommendations.removeAllElements();
+                    setCollection(newCol);
                 }
             }
         );
@@ -549,16 +601,20 @@
             return;
         }
 
-        for (Recommendation recommendation: recommendations) {
+        for (final Recommendation recommendation: recommendations) {
+            if (collection.loadedRecommendation(recommendation)) {
+                continue;
+            }
+
             final String factory = recommendation.getFactory();
             final String ids     = recommendation.getIDs();
 
+
             GWT.log("Load recommended artifact with factory: " + factory);
 
             createArtifactService.create(
                 url, locale, factory, master.getUuid(), ids,
                 new AsyncCallback<Artifact>() {
-
                     public void onFailure(Throwable caught) {
                         GWT.log("Error loading recommendations: " +
                             caught.getMessage());
@@ -567,6 +623,7 @@
                     public void onSuccess(Artifact artifact) {
                         GWT.log("Created new artifact: " + artifact.getUuid());
                         addArtifactToCollection(artifact);
+                        newRecommendations.push(recommendation);
                     }
             });
         }
--- a/flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java	Thu Jul 21 16:06:29 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java	Fri Jul 22 12:23:36 2011 +0000
@@ -14,6 +14,7 @@
 import de.intevation.flys.client.shared.model.AttributedTheme;
 import de.intevation.flys.client.shared.model.Collection;
 import de.intevation.flys.client.shared.model.OutputMode;
+import de.intevation.flys.client.shared.model.Recommendation;
 import de.intevation.flys.client.shared.model.Theme;
 import de.intevation.flys.client.shared.model.ThemeList;
 
@@ -40,11 +41,16 @@
         Map<String, OutputMode> tmpOuts = collection.getOutputModes();
 
         Element outs = createOutputElements(cr, collection, tmpOuts);
+        Element recs = createRecommendationsElements(cr, collection);
 
         if (outs != null) {
             attr.appendChild(outs);
         }
 
+        if (recs != null) {
+            attr.appendChild(recs);
+        }
+
         return doc;
     }
 
@@ -166,5 +172,65 @@
 
         return t;
     }
+
+
+    /**
+     * Creates a whole block with art:loaded-recommendations nodes.
+     *
+     * @param cr The ElementCreator used to create new elements.
+     * @param c  The collection.
+     *
+     * @return an element with loaded recommendations.
+     */
+    protected static Element createRecommendationsElements(
+        ElementCreator cr,
+        Collection     c)
+    {
+        System.out.println("CollectionHelper.createRecommendationsElements");
+
+        List<Recommendation> rs = c.getRecommendations();
+
+        if (rs == null || rs.size() == 0) {
+            System.err.println("Collection did not load recommendations: " +
+                c.identifier());
+            return null;
+        }
+
+        Element loaded = cr.create("loaded-recommendations");
+
+        for (Recommendation r: rs) {
+            Element recommendation = createRecommendationElement(cr, c, r);
+
+            if (recommendation != null) {
+                loaded.appendChild(recommendation);
+            }
+        }
+
+        return loaded;
+    }
+
+
+    /**
+     * Create a node art:recommended.
+     *
+     * @param cr The ElementCreator used to create new elements.
+     * @param c  The collection.
+     * @param r  The Recommendation.
+     *
+     * @return an element that represents an output mode with its themes.
+     */
+    protected static Element createRecommendationElement(
+        ElementCreator cr,
+        Collection     c,
+        Recommendation r)
+    {
+        System.out.println("CollectionHelper.createRecommendationElement");
+
+        Element recommendation = cr.create("recommendation");
+        cr.addAttr(recommendation, "factory", r.getFactory(), true);
+        cr.addAttr(recommendation, "db-ids", r.getIDs(), true);
+
+        return recommendation;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java	Thu Jul 21 16:06:29 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java	Fri Jul 22 12:23:36 2011 +0000
@@ -31,6 +31,7 @@
 import de.intevation.flys.client.shared.model.DefaultCollection;
 import de.intevation.flys.client.shared.model.DefaultCollectionItem;
 import de.intevation.flys.client.shared.model.DefaultFacet;
+import de.intevation.flys.client.shared.model.DefaultRecommendation;
 import de.intevation.flys.client.shared.model.DefaultTheme;
 import de.intevation.flys.client.shared.model.ChartMode;
 import de.intevation.flys.client.shared.model.ExportMode;
@@ -38,6 +39,7 @@
 import de.intevation.flys.client.shared.model.ReportMode;
 import de.intevation.flys.client.shared.model.Facet;
 import de.intevation.flys.client.shared.model.OutputMode;
+import de.intevation.flys.client.shared.model.Recommendation;
 import de.intevation.flys.client.shared.model.Theme;
 import de.intevation.flys.client.shared.model.ThemeList;
 import de.intevation.flys.client.client.services.DescribeCollectionService;
@@ -61,6 +63,9 @@
 
     public static final String XPATH_FACETS = "art:facets/art:facet";
 
+    public static final String XPATH_LOADED_RECOMMENDATIONS =
+        "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation";
+
 
     public Collection describe(String uuid, String serverUrl, String locale)
     throws ServerException
@@ -137,10 +142,11 @@
         }
 
         Map<String, ThemeList> themeList = parseThemeLists(description);
+        List<Recommendation> recommended = parseRecommendations(description);
 
         Collection c = !themeList.isEmpty()
-            ? new DefaultCollection(uuid, ttl, themeList)
-            : new DefaultCollection(uuid, ttl);
+            ? new DefaultCollection(uuid, ttl, recommended, themeList)
+            : new DefaultCollection(uuid, ttl, recommended);
 
         NodeList items = (NodeList) XMLUtils.xpath(
             description,
@@ -361,7 +367,7 @@
 
 
     protected static List<Facet> extractFacets(Element outmode) {
-        System.out.println("ArtifactDescriptionFactory - extractFacets()");
+        System.out.println("DescribeCollectionServiceImpl - extractFacets()");
 
         NodeList facetList = (NodeList) XMLUtils.xpath(
             outmode,
@@ -389,5 +395,35 @@
 
         return facets;
     }
+
+
+    public static List<Recommendation> parseRecommendations(Document doc) {
+        System.out.println("DescribeCollectionServiceImpl.parseRecommendations");
+
+        NodeList list = (NodeList) XMLUtils.xpath(
+            doc,
+            XPATH_LOADED_RECOMMENDATIONS,
+            XPathConstants.NODESET,
+            ArtifactNamespaceContext.INSTANCE);
+
+        int num = list != null ? list.getLength() : 0;
+
+        List<Recommendation> recs = new ArrayList<Recommendation>(num);
+
+        String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+        for (int i = 0; i < num; i++) {
+            Element rec = (Element) list.item(i);
+
+            String factory = rec.getAttributeNS(uri, "factory");
+            String dbids   = rec.getAttributeNS(uri, "db-ids");
+
+            if (factory != null && factory.length() > 0) {
+                recs.add(new DefaultRecommendation(factory, dbids));
+            }
+        }
+
+        return recs;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/Collection.java	Thu Jul 21 16:06:29 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Collection.java	Fri Jul 22 12:23:36 2011 +0000
@@ -2,6 +2,7 @@
 
 import java.io.Serializable;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 
@@ -35,5 +36,13 @@
     public Map<String, OutputMode> getOutputModes();
 
     public ThemeList getThemeList(String outName);
+
+    public List<Recommendation> getRecommendations();
+
+    public void addRecommendation(Recommendation recommendation);
+
+    public void addRecommendations(List<Recommendation> recommendations);
+
+    public boolean loadedRecommendation(Recommendation recommendation);
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java	Thu Jul 21 16:06:29 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/DefaultCollection.java	Fri Jul 22 12:23:36 2011 +0000
@@ -30,6 +30,8 @@
     /** The list of artifacts that are managed by this Collection.*/
     protected List<CollectionItem> items;
 
+    protected List<Recommendation> recommendations;
+
     protected Map<String, ThemeList> themeLists;
 
 
@@ -40,11 +42,6 @@
     }
 
 
-    /**
-     * Creates a new DefaultCollection with a UUID.
-     *
-     * @param uuid The UUID.
-     */
     public DefaultCollection(String uuid, long ttl) {
         this.uuid       = uuid;
         this.ttl        = ttl;
@@ -53,13 +50,27 @@
     }
 
 
+    /**
+     * Creates a new DefaultCollection with a UUID.
+     *
+     * @param uuid The UUID.
+     */
+    public DefaultCollection(String uuid, long ttl, List<Recommendation> recs) {
+        this(uuid, ttl);
+
+        this.recommendations = recs;
+    }
+
+
     public DefaultCollection(
         String uuid,
         long   ttl,
+        List<Recommendation> recommendations,
         Map<String, ThemeList> themeLists)
     {
-        this(uuid, ttl);
-        this.themeLists = themeLists;
+        this(uuid, ttl, new ArrayList<Recommendation>());
+        this.recommendations = recommendations;
+        this.themeLists      = themeLists;
     }
 
 
@@ -70,7 +81,7 @@
      * @param name The name of this collection.
      */
     public DefaultCollection(String uuid, long ttl, String name) {
-        this(uuid, ttl);
+        this(uuid, ttl, new ArrayList<Recommendation>());
 
         this.name = name;
     }
@@ -174,5 +185,37 @@
 
         return null;
     }
+
+
+    public List<Recommendation> getRecommendations() {
+        return recommendations;
+    }
+
+
+    public void addRecommendation(Recommendation recommendation) {
+        recommendations.add(recommendation);
+    }
+
+
+    public void addRecommendations(List<Recommendation> recommendations) {
+        this.recommendations.addAll(recommendations);
+    }
+
+
+    public boolean loadedRecommendation(Recommendation recommendation) {
+        String factory = recommendation.getFactory();
+        String dbids   = recommendation.getIDs();
+
+        for (Recommendation in: recommendations) {
+            String inFactory = in.getFactory();
+            String inDbids   = in.getIDs();
+
+            if (factory.equals(inFactory) && dbids.equals(inDbids)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org