Author: kkolinko
Date: Tue Jul  8 15:24:51 2014
New Revision: 1608831

URL: http://svn.apache.org/r1608831
Log:
Add reference from an alias Host to its real Host.
Add list of aliases to the real Host.
Amend the test case.

This backports r1606651 r1606680 minus a pair of isAlias() checks that will be 
committed separately.

Modified:
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java
    tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java?rev=1608831&r1=1608830&r2=1608831&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java 
Tue Jul  8 15:24:51 2014
@@ -17,6 +17,12 @@
 
 package org.apache.tomcat.util.http.mapper;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
 import javax.naming.NamingException;
 import javax.naming.directory.DirContext;
 
@@ -82,6 +88,7 @@ public final class Mapper {
      * Add a new host to the mapper.
      *
      * @param name Virtual host name
+     * @param aliases Alias names for the virtual host
      * @param host Host object
      */
     public synchronized void addHost(String name, String[] aliases,
@@ -97,9 +104,14 @@ public final class Mapper {
             // Do not add aliases, as removeHost(hostName) won't be able to 
remove them
             return;
         }
+        List<Host> newAliases = new ArrayList<Host>(aliases.length);
         for (String alias : aliases) {
-            addHostAliasImpl(alias, newHost);
+            Host newAlias = new Host(alias, newHost);
+            if (addHostAliasImpl(newAlias)) {
+                newAliases.add(newAlias);
+            }
         }
+        newHost.addAliases(newAliases);
     }
 
 
@@ -114,21 +126,15 @@ public final class Mapper {
         if (host == null || host.isAlias()) {
             return;
         }
-        Object catalinaHost = host.object;
-        Host[] newHosts = new Host[hosts.length - 1];
-        if (removeMap(hosts, newHosts, name)) {
-            hosts = newHosts;
-
-            // Remove all aliases (they will map to the same host object)
-            for (int i = 0; i < newHosts.length; i++) {
-                if (newHosts[i].object == catalinaHost) {
-                    Host[] newHosts2 = new Host[hosts.length - 1];
-                    if (removeMap(hosts, newHosts2, newHosts[i].name)) {
-                        hosts = newHosts2;
-                    }
-                }
+        Host[] newHosts = hosts.clone();
+        // Remove real host and all its aliases
+        int j = 0;
+        for (int i = 0; i < newHosts.length; i++) {
+            if (newHosts[i].getRealHost() != host) {
+                newHosts[j++] = newHosts[i];
             }
         }
+        hosts = Arrays.copyOf(newHosts, j);
     }
 
     /**
@@ -143,24 +149,28 @@ public final class Mapper {
             // just in case...
             return;
         }
-        addHostAliasImpl(alias, realHost);
+        Host newAlias = new Host(alias, realHost);
+        if (addHostAliasImpl(newAlias)) {
+            realHost.addAlias(newAlias);
+        }
     }
 
-    private void addHostAliasImpl(String alias, Host realHost) {
-        Host newHost = new Host(alias, realHost);
+    private boolean addHostAliasImpl(Host newAlias) {
         Host[] newHosts = new Host[hosts.length + 1];
-        if (insertMap(hosts, newHosts, newHost)) {
+        if (insertMap(hosts, newHosts, newAlias)) {
             hosts = newHosts;
+            return true;
         } else {
-            Host duplicate = hosts[find(hosts, alias)];
-            if (duplicate.object == realHost.object) {
+            Host duplicate = hosts[find(hosts, newAlias.name)];
+            if (duplicate.getRealHost() == newAlias.getRealHost()) {
                 // A duplicate Alias for the same Host.
                 // A harmless redundancy. E.g.
                 // <Host name="localhost"><Alias>localhost</Alias></Host>
-                return;
+                return false;
             }
-            log.error(sm.getString("mapper.duplicateHostAlias", alias,
-                    realHost.getRealHostName(), duplicate.getRealHostName()));
+            log.error(sm.getString("mapper.duplicateHostAlias", newAlias.name,
+                    newAlias.getRealHostName(), duplicate.getRealHostName()));
+            return false;
         }
     }
 
@@ -177,6 +187,7 @@ public final class Mapper {
         Host[] newHosts = new Host[hosts.length - 1];
         if (removeMap(hosts, newHosts, alias)) {
             hosts = newHosts;
+            host.getRealHost().removeAlias(host);
         }
 
     }
@@ -1465,19 +1476,30 @@ public final class Mapper {
     // ------------------------------------------------------- Host Inner Class
 
 
-    protected static final class Host
-        extends MapElement {
+    protected static final class Host extends MapElement {
 
-        private final String realHostName;
         public ContextList contextList;
 
         /**
+         * Link to the "real" MappedHost, shared by all aliases.
+         */
+        private final Host realHost;
+
+        /**
+         * Links to all registered aliases, for easy enumeration. This field
+         * is available only in the "real" MappedHost. In an alias this field
+         * is <code>null</code>.
+         */
+        private final List<Host> aliases;
+
+        /**
          * Creates an object for primary Host
          */
         public Host(String name, Object host) {
             super(name, host);
-            this.realHostName = name;
+            this.realHost = this;
             this.contextList = new ContextList();
+            this.aliases = new CopyOnWriteArrayList<Host>();
         }
 
         /**
@@ -1485,16 +1507,37 @@ public final class Mapper {
          */
         public Host(String alias, Host realHost) {
             super(alias, realHost.object);
-            this.realHostName = realHost.name;
+            this.realHost = realHost;
             this.contextList = realHost.contextList;
+            this.aliases = null;
         }
 
         public boolean isAlias() {
-            return !name.equals(realHostName);
+            return realHost != this;
+        }
+
+        public Host getRealHost() {
+            return realHost;
         }
 
         public String getRealHostName() {
-            return realHostName;
+            return realHost.name;
+        }
+
+        public Collection<Host> getAliases() {
+            return aliases;
+        }
+
+        public void addAlias(Host alias) {
+            aliases.add(alias);
+        }
+
+        public void addAliases(Collection<? extends Host> c) {
+            aliases.addAll(c);
+        }
+
+        public void removeAlias(Host alias) {
+            aliases.remove(alias);
         }
     }
 

Modified: 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java?rev=1608831&r1=1608830&r2=1608831&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java 
Tue Jul  8 15:24:51 2014
@@ -19,6 +19,7 @@ package org.apache.tomcat.util.http.mapp
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.Before;
@@ -148,10 +149,18 @@ public class TestMapper extends LoggingB
         Mapper.Host aliasMapping = mapper.hosts[iowPos + 1];
         assertEquals("iowejoiejfoiew_alias", aliasMapping.name);
         assertTrue(aliasMapping.isAlias());
-        assertEquals(hostMapping.object, aliasMapping.object);
+        assertSame(hostMapping.object, aliasMapping.object);
+
+        assertEquals("iowejoiejfoiew", hostMapping.getRealHostName());
+        assertEquals("iowejoiejfoiew", aliasMapping.getRealHostName());
+        assertSame(hostMapping, hostMapping.getRealHost());
+        assertSame(hostMapping, aliasMapping.getRealHost());
 
         mapper.removeHost("iowejoiejfoiew");
         assertEquals(14, mapper.hosts.length); // Both host and alias removed
+        for (Mapper.Host host : mapper.hosts) {
+            assertTrue(host.name, !host.name.startsWith("iowejoiejfoiew"));
+        }
     }
 
     @Test
@@ -212,7 +221,7 @@ public class TestMapper extends LoggingB
         final Object context3 = new Object(); // "foo#bar#bla";
         final Object context4 = new Object(); // "foo#bar#bla#baz";
 
-        mapper.addHost("localhost", new String[0], host);
+        mapper.addHost("localhost", new String[] { "alias" }, host);
         mapper.setDefaultHostName("localhost");
 
         mapper.addContextVersion("localhost", host, "", "0", contextRoot,
@@ -244,6 +253,8 @@ public class TestMapper extends LoggingB
         MappingData mappingData = new MappingData();
         MessageBytes hostMB = MessageBytes.newInstance();
         hostMB.setString("localhost");
+        MessageBytes aliasMB = MessageBytes.newInstance();
+        aliasMB.setString("alias");
         MessageBytes uriMB = MessageBytes.newInstance();
         char[] uri = "/foo/bar/bla/bobou/foo".toCharArray();
         uriMB.setChars(uri, 0, uri.length);
@@ -251,12 +262,22 @@ public class TestMapper extends LoggingB
         mapper.map(hostMB, uriMB, null, mappingData);
         assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
 
+        mappingData.recycle();
+        uriMB.setChars(uri, 0, uri.length);
+        mapper.map(aliasMB, uriMB, null, mappingData);
+        assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
+
         t.start();
         while (running.get()) {
             mappingData.recycle();
             uriMB.setChars(uri, 0, uri.length);
             mapper.map(hostMB, uriMB, null, mappingData);
             assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
+
+            mappingData.recycle();
+            uriMB.setChars(uri, 0, uri.length);
+            mapper.map(aliasMB, uriMB, null, mappingData);
+            assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to