Revision: 1175
          http://stripes.svn.sourceforge.net/stripes/?rev=1175&view=rev
Author:   bengunter
Date:     2009-10-20 14:55:30 +0000 (Tue, 20 Oct 2009)

Log Message:
-----------
Applied fix for STS-665 from 1.5.x branch.

Modified Paths:
--------------
    trunk/stripes/src/net/sourceforge/stripes/controller/UrlBinding.java
    trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingFactory.java
    
trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingParameter.java
    
trunk/tests/src/net/sourceforge/stripes/controller/UrlBindingFactoryTests.java

Modified: trunk/stripes/src/net/sourceforge/stripes/controller/UrlBinding.java
===================================================================
--- trunk/stripes/src/net/sourceforge/stripes/controller/UrlBinding.java        
2009-10-20 14:42:33 UTC (rev 1174)
+++ trunk/stripes/src/net/sourceforge/stripes/controller/UrlBinding.java        
2009-10-20 14:55:30 UTC (rev 1175)
@@ -113,6 +113,21 @@
     }
 
     @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof UrlBinding))
+            return false;
+
+        UrlBinding that = (UrlBinding) obj;
+        return this.getBeanType() == that.getBeanType()
+                && this.getComponents().equals(that.getComponents());
+    }
+
+    @Override
+    public int hashCode() {
+        return getPath() == null ? 0 : getPath().hashCode();
+    }
+
+    @Override
     public String toString() {
         StringBuilder buf = new StringBuilder(64).append(getPath());
         for (Object component : getComponents()) {

Modified: 
trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingFactory.java
===================================================================
--- trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingFactory.java 
2009-10-20 14:42:33 UTC (rev 1174)
+++ trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingFactory.java 
2009-10-20 14:55:30 UTC (rev 1175)
@@ -65,7 +65,7 @@
     private final Map<String, UrlBinding> pathCache = new HashMap<String, 
UrlBinding>();
 
     /** Keeps a list of all the paths that could not be cached due to 
conflicts between URL bindings */
-    private final Map<String, List<String>> pathConflicts = new 
HashMap<String, List<String>>();
+    private final Map<String, List<UrlBinding>> pathConflicts = new 
HashMap<String, List<UrlBinding>>();
 
     /** Holds the set of paths that are cached, sorted from longest to 
shortest */
     private final Map<String, Set<UrlBinding>> prefixCache = new 
TreeMap<String, Set<UrlBinding>>(
@@ -118,7 +118,10 @@
             return prototype;
         }
         else if (pathConflicts.containsKey(uri)) {
-            throw new UrlBindingConflictException(uri, pathConflicts.get(uri));
+            List<String> strings = new ArrayList<String>();
+            for (UrlBinding conflict : pathConflicts.get(uri))
+                strings.add(conflict.toString());
+            throw new UrlBindingConflictException(uri, strings);
         }
 
         // Get all the bindings whose prefix matches the URI
@@ -372,10 +375,10 @@
             log.debug("Clearing cached path ", path, " for ", binding);
             pathCache.remove(path);
 
-            List<String> conflicts = pathConflicts.get(path);
+            List<UrlBinding> conflicts = pathConflicts.get(path);
             if (conflicts != null) {
                 log.debug("Removing ", binding, " from conflicts list ", 
conflicts);
-                conflicts.remove(binding.toString());
+                conflicts.remove(binding);
 
                 if (conflicts.size() == 1) {
                     if (resolvedConflicts == null) {
@@ -469,34 +472,39 @@
             UrlBinding conflict = pathCache.put(path, null);
 
             // Construct a list of conflicting bindings
-            List<String> list = pathConflicts.get(path);
-            if (list == null) {
-                list = new ArrayList<String>();
-                list.add(conflict.toString());
-                pathConflicts.put(path, list);
+            List<UrlBinding> conflicts = pathConflicts.get(path);
+            if (conflicts == null) {
+                conflicts = new ArrayList<UrlBinding>();
+                conflicts.add(conflict);
+                pathConflicts.put(path, conflicts);
             }
-            list.add(binding.toString());
+            conflicts.add(binding);
 
-            // If either the existing binding or the new binding (but not 
both) declares no
-            // parameters, then it is a static binding and should take 
precedence over dynamic ones.
+            // If there is exactly one binding for this path that declares no 
parameters, then it is
+            // a static binding and should take precedence over dynamic ones.
             UrlBinding statik = null;
-            if (conflict != null) {
-                if (conflict.getParameters().isEmpty() && 
!binding.getParameters().isEmpty()) {
-                    statik = conflict;
+            if (conflicts.size() > 1) {
+                for (UrlBinding ub : conflicts) {
+                    if (ub.getParameters().isEmpty()) {
+                        if (statik == null) {
+                            statik = ub;
+                        }
+                        else {
+                            statik = null;
+                            break;
+                        }
+                    }
                 }
-                else if (!conflict.getParameters().isEmpty() && 
binding.getParameters().isEmpty()) {
-                    statik = binding;
-                }
             }
 
             // Replace the path cache entry if necessary and log a warning
             if (statik == null) {
                 log.debug("The path ", path, " for ", 
binding.getBeanType().getName(), " @ ",
-                        binding, " conflicts with ", list);
+                        binding, " conflicts with ", conflicts);
             }
             else {
                 log.debug("For path ", path, ", static binding ", statik,
-                        " supersedes conflicting bindings ", list);
+                        " supersedes conflicting bindings ", conflicts);
                 pathCache.put(path, statik);
             }
         }

Modified: 
trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingParameter.java
===================================================================
--- 
trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingParameter.java   
    2009-10-20 14:42:33 UTC (rev 1174)
+++ 
trunk/stripes/src/net/sourceforge/stripes/controller/UrlBindingParameter.java   
    2009-10-20 14:55:30 UTC (rev 1175)
@@ -131,8 +131,9 @@
     public boolean equals(Object o) {
         if (!(o instanceof UrlBindingParameter))
             return false;
+
         UrlBindingParameter that = (UrlBindingParameter) o;
-        return this.value == that.value || ((this.value != null) && 
this.value.equals(that.value));
+        return this.value == null ? that.value == null : 
this.value.equals(that.value);
     }
 
     @Override

Modified: 
trunk/tests/src/net/sourceforge/stripes/controller/UrlBindingFactoryTests.java
===================================================================
--- 
trunk/tests/src/net/sourceforge/stripes/controller/UrlBindingFactoryTests.java  
    2009-10-20 14:42:33 UTC (rev 1174)
+++ 
trunk/tests/src/net/sourceforge/stripes/controller/UrlBindingFactoryTests.java  
    2009-10-20 14:55:30 UTC (rev 1175)
@@ -251,10 +251,50 @@
         checkBinding("/foo/goo/1/", FooActionBean8.class);
         checkBinding("/foo/goo/1/2", FooActionBean8.class);
     }
-    
-    public static void main(String[] args) {
-        UrlBindingFactoryTests tests = new UrlBindingFactoryTests();
-        tests.setupClass();
-        tests.testUrlBindings();
+
+    @Test(groups = "fast")
+    public void testConflictDetectionIndependentOfClassLoadingOrder() {
+        UrlBindingFactory factory;
+        UrlBinding prototype;
+
+        // This order works
+        factory = new UrlBindingFactory();
+        factory.addBinding(FooActionBean.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean.class));
+        factory.addBinding(FooActionBean2.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean2.class));
+        factory.addBinding(FooActionBean3.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean3.class));
+        factory.addBinding(FooActionBean4.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean4.class));
+        factory.addBinding(FooActionBean5.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean5.class));
+        factory.addBinding(FooActionBean6.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean6.class));
+        factory.addBinding(FooActionBean7.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean7.class));
+        factory.addBinding(FooActionBean8.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean8.class));
+        prototype = factory.getBindingPrototype("/foo");
+        Assert.assertNotNull(prototype);
+        Assert.assertSame(prototype.getBeanType(), FooActionBean.class);
+
+        // This order was failing
+        factory = new UrlBindingFactory();
+        factory.addBinding(FooActionBean8.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean8.class));
+        factory.addBinding(FooActionBean7.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean7.class));
+        factory.addBinding(FooActionBean6.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean6.class));
+        factory.addBinding(FooActionBean5.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean5.class));
+        factory.addBinding(FooActionBean4.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean4.class));
+        factory.addBinding(FooActionBean3.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean3.class));
+        factory.addBinding(FooActionBean2.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean2.class));
+        factory.addBinding(FooActionBean.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean.class));
+        factory.getBindingPrototype("/foo");
+        Assert.assertNotNull(prototype);
+        Assert.assertSame(prototype.getBeanType(), FooActionBean.class);
+
+        // And this should still fail, regardless of order
+        factory = new UrlBindingFactory();
+        factory.addBinding(FooActionBean.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean.class));
+        factory.addBinding(FooActionBean2.class, 
UrlBindingFactory.parseUrlBinding(FooActionBean.class));
+        try {
+            factory.getBindingPrototype("/foo");
+            Assert.assertTrue(false, "A URL binding conflict was expected but 
it didn't happen!");
+        }
+        catch (UrlBindingConflictException e) {
+            log.debug("Got expected URL binding conflict");
+        }
     }
 }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to