Author: jkaputin Date: Sat Jan 6 20:56:08 2007 New Revision: 493645 URL: http://svn.apache.org/viewvc?view=rev&rev=493645 Log: WODEN-86 finished implementing behaviour of this class including methods to substitute values for local names and query the values. Added unit tests.
Modified: incubator/woden/trunk/java/src/org/apache/woden/wsdl20/extensions/http/HTTPLocation.java incubator/woden/trunk/java/test/org/apache/woden/wsdl20/extensions/http/HTTPLocationTest.java Modified: incubator/woden/trunk/java/src/org/apache/woden/wsdl20/extensions/http/HTTPLocation.java URL: http://svn.apache.org/viewvc/incubator/woden/trunk/java/src/org/apache/woden/wsdl20/extensions/http/HTTPLocation.java?view=diff&rev=493645&r1=493644&r2=493645 ============================================================================== --- incubator/woden/trunk/java/src/org/apache/woden/wsdl20/extensions/http/HTTPLocation.java (original) +++ incubator/woden/trunk/java/src/org/apache/woden/wsdl20/extensions/http/HTTPLocation.java Sat Jan 6 20:56:08 2007 @@ -53,15 +53,19 @@ * The specification of the WSDL 2.0 HTTP Binding extensions does not explicitly state how to * interpret extraneous, unmatched curly braces, so this class adopts the following strategy: * <p> - * If multiple left braces precede a right brace, pair the right most one with the right brace - * and treat the others as unmatched left braces. + * If multiple single left braces precede a right brace, pair the right most one with the right + * brace and treat the others as unmatched left braces. * <pre> - * e.g. "{ { {..}" + * e.g. "{..{..{xxxx}" * </pre> - * If multiple right braces follow a left brace, pair the left most one with the left brace - * and treat the others as unmatched right braces. + * If multiple single right braces follow a left brace, pair the left most one with the left + * brace and treat the others as unmatched right braces. * <pre> - * e.g. "{..} } }" + * e.g. "{xxxx}..}..}" + * </pre> + * Double left or right braces take precedence over potentially matching pairs of single braces. + * <pre> + * e.g. "{xxxx}}}" is evaluated as {xxxx,}},} not as {xxxx},}} * </pre> * * @author John Kaputin ([EMAIL PROTECTED]) @@ -75,6 +79,7 @@ private List fValidatedList = new Vector(); //identifies syntax errors in the template private List fParsedList = new Vector(); //working list for value substitution + private final String emptyString = "".intern(); private final String leftBrace = "{".intern(); private final String rightBrace = "}".intern(); private final String doubleLeftBraces = "{{".intern(); @@ -96,15 +101,18 @@ public HTTPLocation(String location) { fLocationTemplate = location; - if(fLocationTemplate != null) { + if(location == null) { + //TODO throw NPE with suitable error message + fValid = false; + } else if(location.equals(emptyString)) { + fValidatedList.add(emptyString); + fParsedList.add(emptyString); + } else { List tokenizedList = tokenizeTemplate(); validateTemplate(tokenizedList); if(fValidatedList.size() > 0) { parseTemplate(); } - } else { - //TODO decide whether to throw NPE or simply flag location template as invalid - fValid = false; } } @@ -178,7 +186,23 @@ * @return a String array containing all element local names from the template */ public String[] getLocalNames() { - return null; //TODO implement this method + + List names = new Vector(); + Object next; + String[] elem; + + Iterator it = fParsedList.iterator(); + while(it.hasNext()) { + next = it.next(); + if(next instanceof String[]) { + elem = (String[]) next; + names.add(elem[0]); + } + } + + String[] array = new String[names.size()]; + names.toArray(array); + return array; } /** @@ -190,7 +214,26 @@ * @return a String array containing the distinct element local names from the template */ public String[] getDistinctLocalNames() { - return null; //TODO implement this method + + List names = new Vector(); + Object next; + String[] elem; + + Iterator it = fParsedList.iterator(); + while(it.hasNext()) { + next = it.next(); + if(next instanceof String[]) { + elem = (String[]) next; + String name = elem[0]; + if(!names.contains(name)) { + names.add(name); + } + } + } + + String[] array = new String[names.size()]; + names.toArray(array); + return array; } /** @@ -200,7 +243,19 @@ * @return the number of occurrences of <code>localName</code> */ public int countLocalNames() { - return 0; //TODO implement this method + + Object next; + int count = 0; + + Iterator it = fParsedList.iterator(); + while(it.hasNext()) { + next = it.next(); + if(next instanceof String[]) { + count++; + } + } + + return count; } /** @@ -212,7 +267,25 @@ * @return the number of occurrences of <code>localName</code> */ public int countOccurrences(String localName) { - return 0; //TODO implement this method + + int count = 0; + Object next; + String[] elem; + + if(localName != null) { + Iterator it = fParsedList.iterator(); + while(it.hasNext()) { + next = it.next(); + if(next instanceof String[]) { + elem = (String[]) next; + if (elem[0].equals(localName)) { + count++; + } + } + } + } + + return count; } //TODO public void substitute(String localName, int occurrence, String value) {}, required? @@ -221,7 +294,7 @@ * Substitute the specified element local name and its enclosing curly braces within the * location template with the specified String value of that element. * Note, this method assumes a single occurrence only of the specified local name, so if - * the the local name appears multiple times in the template only the first occurrence + * if the local name appears multiple times in the template only the first occurrence * will be substituted. It does not handle multiple substitution. * * @param localName the local name of an element from the instance data of the message @@ -229,8 +302,7 @@ */ public void substitute(String localName, String value) { - fDerivedLocation = null; - + substitute(localName, value, false); } /** @@ -251,7 +323,27 @@ */ public void substitute(String localName, String value, boolean allOccurrences) { - fDerivedLocation = null; + if(localName == null) { + //TODO throw NPE? + return; + } + fDerivedLocation = null; //flush the cached value + + Object next; + String[] elem; + Iterator it = fParsedList.iterator(); + while(it.hasNext()) { + next = it.next(); + if(next instanceof String[]) { + elem = (String[])next; + if(elem[0].equals(localName)) { + elem[1] = value; + if(!allOccurrences) { + break; + } + } + } + } } @@ -274,7 +366,26 @@ */ public void substitute(String localName, String[] values) { - fDerivedLocation = null; + if(localName == null || values == null) { + //TODO throw NPE? + return; + } + fDerivedLocation = null; //flush the cached value + + Object next; + String[] elem; + int i = 0; + Iterator it = fParsedList.iterator(); + while(it.hasNext() && i<values.length) { + next = it.next(); + if(next instanceof String[]) { + elem = (String[])next; + if(elem[0].equals(localName)) { + elem[1] = values[i]; + i++; + } + } + } } @@ -294,8 +405,25 @@ */ public void substitute(String[] values) { - fDerivedLocation = null; + if(values == null) { + //TODO throw NPE? + return; + } + fDerivedLocation = null; //flush the cached value + Object next; + String[] elem; + int i = 0; + Iterator it = fParsedList.iterator(); + while(it.hasNext() && i<values.length) { + next = it.next(); + if(next instanceof String[]) { + elem = (String[])next; + elem[1] = values[i]; + i++; + } + } + } /** @@ -314,7 +442,26 @@ * @return the String value associated with <code>localName</code> */ public String getValue(String localName) { - return null; //TODO implement this method + + Object next; + String[] elem; + String value = null; + + if(localName != null) { + Iterator it = fParsedList.iterator(); + while (it.hasNext()) { + next = it.next(); + if (next instanceof String[]) { + elem = (String[]) next; + if (elem[0].equals(localName)) { + value = elem[1]; + break; + } + } + } + } + + return value; } /** @@ -330,7 +477,27 @@ * @return an array of String values associated with occurrences of <code>localName</code> */ public String[] getValues(String localName) { - return null; //TODO implement this method + + List values = new Vector(); + Object next; + String[] elem; + + if(localName != null) { + Iterator it = fParsedList.iterator(); + while (it.hasNext()) { + next = it.next(); + if (next instanceof String[]) { + elem = (String[]) next; + if (elem[0].equals(localName)) { + values.add(elem[1]); + } + } + } + } + + String[] array = new String[values.size()]; + values.toArray(array); + return array; } /** @@ -344,7 +511,23 @@ * @return an array of String values associated with element local names within the template */ public String[] getValues() { - return null; //TODO implement this method + + List values = new Vector(); + Object next; + String[] elem; + + Iterator it = fParsedList.iterator(); + while (it.hasNext()) { + next = it.next(); + if (next instanceof String[]) { + elem = (String[]) next; + values.add(elem[1]); + } + } + + String[] array = new String[values.size()]; + values.toArray(array); + return array; } /** @@ -365,12 +548,14 @@ } StringBuffer buffer = new StringBuffer(); + Object currToken; + String[] nameValue; Iterator it = fParsedList.iterator(); while(it.hasNext()) { - Object currToken = it.next(); + currToken = it.next(); if(currToken instanceof String[]) { - String[] nameValue = (String[])currToken; + nameValue = (String[])currToken; if(nameValue[1] == null) { //no value substitution, so append the original curly brace-enclosed string buffer.append(leftBrace); @@ -467,26 +652,24 @@ */ private void validateTemplate(List tokenizedList) { - if(tokenizedList.size() == 0) { - fValid = false; - return; - } - boolean valid = true; List tokens = new Vector(); + Object currToken; + String nextToken; + Object nextNextToken; int size = tokenizedList.size(); ListIterator it = tokenizedList.listIterator(); while(it.hasNext()) { - Object currToken = it.next(); + currToken = it.next(); int currIndex = it.previousIndex(); if(currToken == leftBrace) { if(size-currIndex < 3) { valid = false; //left brace not followed by a name and a right brace tokens.add(leftBrace); } else { - String nextToken = (String)tokenizedList.get(currIndex+1); - Object nextNextToken = tokenizedList.get(currIndex+2); + nextToken = (String)tokenizedList.get(currIndex+1); + nextNextToken = tokenizedList.get(currIndex+2); if(!curlyBraces.contains(nextToken) && nextNextToken == rightBrace) { //we have a string enclosed by a pair of left and right curly braces if(NCName.isValid(nextToken)) { @@ -535,11 +718,12 @@ private void parseTemplate() { StringBuffer buffer = new StringBuffer(); + Object currToken; List tokens = new Vector(); Iterator it = fValidatedList.iterator(); while(it.hasNext()) { - Object currToken = it.next(); + currToken = it.next(); if(currToken instanceof String[]) { //This is a templated local name, so output any previously concatentated //string content then output this string array. Modified: incubator/woden/trunk/java/test/org/apache/woden/wsdl20/extensions/http/HTTPLocationTest.java URL: http://svn.apache.org/viewvc/incubator/woden/trunk/java/test/org/apache/woden/wsdl20/extensions/http/HTTPLocationTest.java?view=diff&rev=493645&r1=493644&r2=493645 ============================================================================== --- incubator/woden/trunk/java/test/org/apache/woden/wsdl20/extensions/http/HTTPLocationTest.java (original) +++ incubator/woden/trunk/java/test/org/apache/woden/wsdl20/extensions/http/HTTPLocationTest.java Sat Jan 6 20:56:08 2007 @@ -28,11 +28,6 @@ */ public class HTTPLocationTest extends TestCase { - private String httpLoc0 = "?op=Cancel"; - private String httpLoc1 = "/temperature/{town}"; - private String httpLoc2 = "?op=Quote;key={symbol};amt={amount}"; - private String httpLoc3 = "?first={FirstName};middle={MiddleName};last={LastName}"; - public static Test suite() { return new TestSuite(HTTPLocationTest.class); @@ -54,82 +49,581 @@ super.tearDown(); } - public void test1ArgCtor() throws Exception + public void testCtor() throws Exception { - HTTPLocation loc = new HTTPLocation(httpLoc1); + HTTPLocation loc; + + //empty string + loc = new HTTPLocation(""); + assertNotNull(loc); + + //no curly braces + loc = new HTTPLocation("/temperature/"); + assertNotNull(loc); + + //one local name + loc = new HTTPLocation("/temperature/{town}/"); + assertNotNull(loc); + + //multiple local names + loc = new HTTPLocation("/temperature/{town}/{state}/{country}"); + assertNotNull(loc); + + //with double curly braces + loc = new HTTPLocation("{{XXX}}/temperature/{town}/{{{state}}}/{country}"); + assertNotNull(loc); + + //invalid template + loc = new HTTPLocation("{{XXX}}/te}mp}erature/{town}/{state}/{coun{try}"); assertNotNull(loc); } - public void testGetHttpLocationTemplate() throws Exception + public void testGetLocationTemplate() throws Exception { - HTTPLocation loc = new HTTPLocation(httpLoc1); - assertEquals(httpLoc1, loc.getLocationTemplate()); + HTTPLocation loc; + + //after ctor + loc = new HTTPLocation("/temperature/{town}"); + assertEquals("/temperature/{town}", loc.getLocationTemplate()); + + //after substitution ... template still has its original value + loc = new HTTPLocation("/temperature/{town}"); + loc.substitute("town","London"); + assertEquals("/temperature/{town}", loc.getLocationTemplate()); + + } public void testIsTemplateValid() throws Exception { + HTTPLocation loc; + boolean result; - HTTPLocation loc = new HTTPLocation(httpLoc0); - boolean result = loc.isTemplateValid(); + //empty string + loc = new HTTPLocation(""); + result = loc.isTemplateValid(); assertTrue(result); - loc = new HTTPLocation(httpLoc1); + //no curly braces + loc = new HTTPLocation("/temperature/"); result = loc.isTemplateValid(); assertTrue(result); - loc = new HTTPLocation(httpLoc2); + //one local name + loc = new HTTPLocation("/temperature/{town}/"); result = loc.isTemplateValid(); assertTrue(result); - loc = new HTTPLocation(httpLoc3); + //multiple local names + loc = new HTTPLocation("/temperature/{town}/{state}/{country}"); result = loc.isTemplateValid(); assertTrue(result); - loc = new HTTPLocation("/foo/{bar{"); //unmatched left brace + //with double curly braces + loc = new HTTPLocation("{{XXX}}/temperature/{town}/}}{state}{{/{country};Tic{{Tac{{Toe"); + result = loc.isTemplateValid(); + assertTrue(result); + + //invalid .. unmatched left braces + + loc = new HTTPLocation("/foo/{bar{"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/{bar"); //unmatched left brace + loc = new HTTPLocation("/foo/{bar"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/bar{"); //unmatched left brace + loc = new HTTPLocation("/foo/bar{"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/}bar}"); //unmatched right brace + loc = new HTTPLocation("/f{oo/{bar}"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/}bar"); //unmatched right brace + loc = new HTTPLocation("{/f{oo/{bar}"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/bar}"); //unmatched right brace + loc = new HTTPLocation("/foo/{bar}/man{"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/{b{ar}"); //unmatched left brace + /* One might expect the template "{{{state}}}" to be parsed as {{,{state},}} where inner + * most braces are matched as a pair enclosing the string "state", but in the + * Woden implementation the double curly braces take precedence so it is parsed as + * {{,{,state,}},} which flags the template as invalid. The WSDL 2.0 spec is silent on the + * precedence of double curly braces over pairs of matching single braces. + */ + loc = new HTTPLocation("{{{state}}}"); result = loc.isTemplateValid(); assertFalse(result); + + //invalid .. unmatched right braces - loc = new HTTPLocation("/foo/{ba}r}"); //unmatched left brace + loc = new HTTPLocation("/foo/}bar}"); result = loc.isTemplateValid(); assertFalse(result); - loc = new HTTPLocation("/foo/{bar}"); //valid local name + loc = new HTTPLocation("/foo/}bar"); result = loc.isTemplateValid(); - assertTrue(result); + assertFalse(result); + + loc = new HTTPLocation("/foo/bar}"); + result = loc.isTemplateValid(); + assertFalse(result); + + loc = new HTTPLocation("/f}oo/{bar}"); + result = loc.isTemplateValid(); + assertFalse(result); + + loc = new HTTPLocation("}/f}oo/{bar}"); + result = loc.isTemplateValid(); + assertFalse(result); + + loc = new HTTPLocation("/foo/{bar}/man}"); + result = loc.isTemplateValid(); + assertFalse(result); - loc = new HTTPLocation("/foo/{ba:r}"); //invalid local name + /* ditto the previous comment about double curly braces taking precedence over a + * potentially matching pair of single curly braces. The template "{state}}}" is + * parsed as {,state,}},} not as {state},}}. + * + */ + loc = new HTTPLocation("{state}}}"); result = loc.isTemplateValid(); assertFalse(result); + + //invalid local name ... not of type xs:NCName + + loc = new HTTPLocation("/foo/{bar:man}"); + result = loc.isTemplateValid(); + assertFalse(result); + } + + public void testGetLocalNames() { + HTTPLocation loc; + String[] actual; + String[] expected; + boolean result; + + loc = new HTTPLocation("?op=EchoInt"); + actual = loc.getLocalNames(); + expected = new String[] {}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + actual = loc.getLocalNames(); + expected = new String[] {"fname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + actual = loc.getLocalNames(); + expected = new String[] {"fname","mname","lname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + } + + public void testGetDistinctLocalNames() { + HTTPLocation loc; + String[] actual; + String[] expected; + boolean result; + + loc = new HTTPLocation("?op=EchoInt"); + actual = loc.getDistinctLocalNames(); + expected = new String[] {}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + actual = loc.getDistinctLocalNames(); + expected = new String[] {"fname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + actual = loc.getDistinctLocalNames(); + expected = new String[] {"fname","mname","lname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={lname}"); + actual = loc.getDistinctLocalNames(); + expected = new String[] {"fname","lname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={fname}"); + actual = loc.getDistinctLocalNames(); + expected = new String[] {"fname","mname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={fname}"); + actual = loc.getDistinctLocalNames(); + expected = new String[] {"fname"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + } + + + public void testCountLocalNames() { + HTTPLocation loc; + int count; + + loc = new HTTPLocation("?op=EchoInt"); + count = loc.countLocalNames(); + assertEquals(0,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + count = loc.countLocalNames(); + assertEquals(1,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + count = loc.countLocalNames(); + assertEquals(3,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={fname}"); + count = loc.countLocalNames(); + assertEquals(3,count); + + } + + public void testCountOccurrences() { + HTTPLocation loc; + int count; + String localName = "fname"; + + loc = new HTTPLocation("?op=EchoInt"); + count = loc.countOccurrences(localName); + assertEquals(0,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + count = loc.countOccurrences(localName); + assertEquals(1,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + count = loc.countOccurrences(localName); + assertEquals(1,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={fname}"); + count = loc.countOccurrences(localName); + assertEquals(2,count); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={fname}"); + count = loc.countOccurrences(localName); + assertEquals(3,count); + + loc = new HTTPLocation("?op=EchoInt;first={lname};middle={lname};last={lname}"); + count = loc.countOccurrences(localName); + assertEquals(0,count); + + } + + public void testSubstitute_StringString() { + HTTPLocation loc; + String actual; + + loc = new HTTPLocation("?op=EchoInt"); + loc.substitute("fname", "Dougal"); //no effect + actual = loc.toString(); + assertEquals("?op=EchoInt", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute("fname", "Dougal"); + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute("fname", "Dougal"); + loc.substitute("lname", "Smith"); + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle={mname};last=Smith", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={mname}"); + loc.substitute("mname", "Dougal"); + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle=Dougal;last={mname}", actual); + + } + + public void testSubstitute_StringStringBoolean() { + HTTPLocation loc; + String actual; + + loc = new HTTPLocation("?op=EchoInt"); + loc.substitute("fname", "Dougal", false); //no effect + actual = loc.toString(); + assertEquals("?op=EchoInt", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute("fname", "Dougal", false); + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute("fname", "Dougal", true); + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute("mname", "Dougal", true); + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle=Dougal;last={lname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={mname}"); + loc.substitute("mname", "Dougal", false); + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle=Dougal;last={mname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={mname}"); + loc.substitute("mname", "Dougal", true); + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle=Dougal;last=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute(null, "Dougal", true); //arg1 null so ignored + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle={mname};last={lname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={mname}"); + loc.substitute("mname", "Dougal", true); + loc.substitute("mname", null, false); //1st value 'Dougal' removed + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle={mname};last=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={mname}"); + loc.substitute("mname", "Dougal", true); + loc.substitute("mname", null, true); //both values 'Dougal' removed + actual = loc.toString(); + assertEquals("?op=EchoInt;first={fname};middle={mname};last={mname}", actual); + + } + + public void testSubstitute_StringStringArray() { + HTTPLocation loc; + String actual; + + loc = new HTTPLocation("?op=EchoInt"); + loc.substitute("fname", new String[] {"Dougal"}); //no effect + actual = loc.toString(); + assertEquals("?op=EchoInt", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute("fname", new String[] {"Dougal"}); //1 to 1 + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute("fname", new String[] {"Dougal","Malcolm"}); //array > template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle={mname};last={lname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={lname}"); + loc.substitute("fname", new String[] {"Dougal","Malcolm"}); //array = template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle=Malcolm;last={lname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={fname}"); + loc.substitute("fname", new String[] {"Dougal","Malcolm"}); //array < template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle=Malcolm;last={fname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={fname}"); + loc.substitute("fname", new String[] {"Dougal","Malcolm","MacDonald","McDouglas"}); //array > template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle=Malcolm;last=MacDonald", actual); + + } + + public void testSubstitute_StringArray() { + HTTPLocation loc; + String actual; + + loc = new HTTPLocation("?op=EchoInt"); + loc.substitute(new String[] {"Dougal"}); //no effect + actual = loc.toString(); + assertEquals("?op=EchoInt", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute(new String[] {"Dougal"}); //1 to 1 + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute(new String[] {"Dougal","Malcolm"}); //array < template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle=Malcolm;last={lname}", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute(new String[] {"Dougal","Malcolm","MacDonald"}); //array = template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle=Malcolm;last=MacDonald", actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={lname}"); + loc.substitute(new String[] {"Dougal","Malcolm","MacDonald","McDouglas"}); //array > template + actual = loc.toString(); + assertEquals("?op=EchoInt;first=Dougal;middle=Malcolm;last=MacDonald", actual); + + } + + public void testGetValue_String() { + HTTPLocation loc; + String actual; + + loc = new HTTPLocation("?op=EchoInt"); + actual = loc.getValue("fname"); //no effect + assertNull(actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + actual = loc.getValue("fname"); + assertNull(actual); + loc.substitute(new String[] {"Dougal"}); + actual = loc.getValue("fname"); + assertEquals("Dougal",actual); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={mname}"); + loc.substitute(new String[] {"Dougal","Malcolm","MacDonald"}); + actual = loc.getValue("mname"); + assertEquals("Malcolm",actual); + + } + + public void testGetValues_String() { + HTTPLocation loc; + String[] actual; + String[] expected; + boolean result; + + loc = new HTTPLocation("?op=EchoInt"); + actual = loc.getValues("fname"); //no effect + expected = new String[] {}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + actual = loc.getValues("fname"); + expected = new String[] {(String)null}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + actual = loc.getValues("mname"); + expected = new String[] {}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute("fname", "Dougal"); + actual = loc.getValues("fname"); + expected = new String[] {"Dougal"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={fname};last={mname}"); + loc.substitute("fname", new String[] {"Dougal","Malcolm"}); + actual = loc.getValues("fname"); + expected = new String[] {"Dougal","Malcolm"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + } + + public void testGetValues() { + HTTPLocation loc; + String[] actual; + String[] expected; + boolean result; + + loc = new HTTPLocation("?op=EchoInt"); + actual = loc.getValues(); //no effect + expected = new String[] {}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + actual = loc.getValues(); + expected = new String[] {(String)null}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname}"); + loc.substitute("fname", "Dougal"); + actual = loc.getValues(); + expected = new String[] {"Dougal"}; + result = arraysEqual(expected,actual); + assertTrue(result); + + loc = new HTTPLocation("?op=EchoInt;first={fname};middle={mname};last={fname}"); + loc.substitute("fname", new String[] {"Dougal","Malcolm"}); + actual = loc.getValues(); + expected = new String[] {"Dougal",null,"Malcolm"}; + result = arraysEqual(expected,actual); + assertTrue(result); } - public void testGetHttpLocationSubstituted() throws Exception + public void testToString() { + + //toString() has been significantly tested by the testSubstituteXXX methods + + HTTPLocation loc; + String actual; + + loc = new HTTPLocation("?op={{EchoInt}};f}{irst{{}}={fname};middle}={mname};last{={lname};{{"); + loc.substitute(new String[] {"Dougal","Malcolm","MacDonald","McDouglas"}); //array > template + actual = loc.toString(); + assertEquals("?op={EchoInt};f}{irst{}=Dougal;middle}=Malcolm;last{=MacDonald;{", actual); + + } + + private boolean arraysEqual(String[] a1, String[] a2) { + boolean result = true; + Object o1, o2; + + if(a1.length != a2.length) { + result = false; + } else { + for(int i=0; i<a1.length; i++) { + o1 = a1[i]; + o2 = a2[i]; + if(o1 == null && o2 == null) { + continue; + } + if(o1 == null || o2 == null) { + result = false; + break; + } + if(!a1[i].equals(a2[i])) { + result = false; + break; + } + } + } + + return result; + } + + + + + + //TODO remove this test method when the getLocationSubtituted method is removed. + public void testGetLocationSubstituted() throws Exception { + String httpLoc0 = "?op=Cancel"; + String httpLoc1 = "/temperature/{town}"; + String httpLoc2 = "?op=Quote;key={symbol};amt={amount}"; + String httpLoc3 = "?first={FirstName};middle={MiddleName};last={LastName}"; + + String[] values0 = new String[] {}; String[] values1 = new String[] {"ONE"}; String[] values2 = new String[] {"ONE","TWO"}; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]