You are viewing a plain text version of this content. The canonical link for it is here.
Posted to woden-dev@ws.apache.org by jk...@apache.org on 2007/03/10 02:11:46 UTC
svn commit: r516631 - in /incubator/woden/trunk/java:
src/org/apache/woden/wsdl20/extensions/http/HTTPLocation.java
test/org/apache/woden/wsdl20/extensions/http/HTTPLocationTest.java
Author: jkaputin
Date: Fri Mar 9 17:11:46 2007
New Revision: 516631
URL: http://svn.apache.org/viewvc?view=rev&rev=516631
Log:
WODEN-148 modified HTTPLocation to support changes
to spec under CR117
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=516631&r1=516630&r2=516631
==============================================================================
--- 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 Fri Mar 9 17:11:46 2007
@@ -51,6 +51,8 @@
* "abc{{def" becomes "abc{def" in the derived location and this literal left brace is
* not used for matching purposes with a right curly brace.
* <p>
+ * TODO Replace behaviour described below with new EBNF grammar added to spec to fix this ambiguity
+ * <p>
* 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>
@@ -73,56 +75,585 @@
*/
public class HTTPLocation {
- private String fLocationTemplate;
- private String fDerivedLocation = null;
+ private String fLocationTemplate; //deprecated by WODEN-148
+ private String fDerivedLocation = null; //deprecated by WODEN-148
+
+ private String fOriginalLocation;
boolean fValid = true;
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 questionMark = "?".intern();
private final String leftBrace = "{".intern();
private final String rightBrace = "}".intern();
private final String doubleLeftBraces = "{{".intern();
private final String doubleRightBraces = "}}".intern();
+ private final String exclamatedLeftBrace = "{!".intern();
private final List curlyBraces = Arrays.asList(new String[] {
- leftBrace, rightBrace, doubleLeftBraces, doubleRightBraces});
+ leftBrace, rightBrace, doubleLeftBraces, doubleRightBraces, exclamatedLeftBrace});
+
+ /**
+ * This constructor creates an HTTPLocation object from the specified String. This
+ * String is the original value of the {http location} property, prior to any template
+ * substitution of element local names enclosed in curly braces with element values.
+ * If the property was parsed from a WSDL document, this will be the value of the
+ * <code>whttp:location</code> attribute within a binding operation element.
+ * <p>
+ * The location template String argument must not be null.
+ *
+ * @param location the String value of the http location
+ */
+ public HTTPLocation(String location) {
+ fLocationTemplate = location;
+
+ 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();
+ }
+ }
+ }
+
+ /**
+ * TODO javadoc ... created for WODEN-148
+ *
+ * @return true if the format of the original HTTP location string is valid
+ */
+ public boolean isLocationValid() {
+ return fValid;
+ }
+
+ /**
+ * TODO javadoc ... Created for WODEN-148
+ *
+ * @return the original String value of the HTTP location,
+ * prior to any template substitution
+ */
+ public String getOriginalLocation() {
+ return fOriginalLocation;
+ }
+
+ /**
+ * Same behaviour as toString()
+ *
+ * @return the formatted HTTP location, after any template substitution
+ */
+ public String getFormattedLocation() {
+ return toString();
+ }
+
+ /**
+ * Returns a String representing the HTTP Location template with any element name/value
+ * substitution that has taken place via the <code>substitute</code> methods.
+ * If any element local name has not yet been substituted with a value then that
+ * local name will appear in the String in its original template form, enclosed in
+ * curly braces.
+ * <p>
+ * If the HTTP Location does not contain any curly brace template syntax then substitution
+ * is not applicable and this method will return the same String value as the
+ * <code>getLocationTemplate()</code> method.
+ */
+ public String toString() {
+
+ if(fDerivedLocation != null) {
+ return fDerivedLocation;
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ Object currToken;
+ HTTPLocationTemplate template;
+ Iterator it = fParsedList.iterator();
+
+ while(it.hasNext()) {
+ currToken = it.next();
+ if(currToken instanceof HTTPLocationTemplate) {
+ template = (HTTPLocationTemplate)currToken;
+ String value = template.getValue();
+ if(value != null) {
+ //the substituted element value replaces the template in HTTP location
+ buffer.append(value);
+
+ //Note, if a template value is null this indicates it has not yet been matched to any
+ //element instance data and in this case, the template is replaced in the formatted
+ //HTTP location output by the empty string "" (i.e. do nothing here).
+ }
+ } else {
+ buffer.append(currToken);
+ }
+ }
+
+ fDerivedLocation = buffer.toString();
+
+ return fDerivedLocation;
+ }
+
+ /**
+ * Return all templates in this HTTP location.
+ *
+ * @return an array of HTTPLocationTemplate objects
+ */
+ public HTTPLocationTemplate[] getTemplates() {
+ List templates = new Vector();
+
+ Iterator it = fParsedList.iterator();
+ while(it.hasNext()) {
+ Object next = it.next();
+ if(next instanceof HTTPLocationTemplate) {
+ templates.add(next);
+ }
+ }
+
+ HTTPLocationTemplate[] array = new HTTPLocationTemplate[templates.size()];
+ templates.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return the templates in this HTTP location that appear in the path
+ * (i.e. before the first occurrence of "?").
+ *
+ * @return an array of HTTPLocationTemplate objects
+ */
+ public HTTPLocationTemplate[] getTemplatesInPath() {
+ List templates = new Vector();
+
+ Iterator it = fParsedList.iterator();
+ while(it.hasNext()) {
+ Object next = it.next();
+ if(next instanceof HTTPLocationTemplate) {
+ HTTPLocationTemplate template = (HTTPLocationTemplate)next;
+ if(!template.isQuery()) {
+ templates.add(next);
+ }
+ }
+ }
+
+ HTTPLocationTemplate[] array = new HTTPLocationTemplate[templates.size()];
+ templates.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return the templates in this HTTP location that appear in the query
+ * (i.e. after the first occurrence of "?").
+ *
+ * @return an array of HTTPLocationTemplate objects
+ */
+ public HTTPLocationTemplate[] getTemplatesInQuery() {
+ List templates = new Vector();
+
+ Iterator it = fParsedList.iterator();
+ while(it.hasNext()) {
+ Object next = it.next();
+ if(next instanceof HTTPLocationTemplate) {
+ HTTPLocationTemplate template = (HTTPLocationTemplate)next;
+ if(template.isQuery()) {
+ templates.add(next);
+ }
+ }
+ }
+
+ HTTPLocationTemplate[] array = new HTTPLocationTemplate[templates.size()];
+ templates.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return names of all templates in this HTTP location in the order they appear.
+ */
+ public String[] getTemplateNames() {
+ List names = new Vector();
+
+ Iterator it = fParsedList.iterator();
+ while(it.hasNext()) {
+ Object next = it.next();
+ if(next instanceof HTTPLocationTemplate) {
+ HTTPLocationTemplate template = (HTTPLocationTemplate)next;
+ names.add(template.getName());
+ }
+ }
+
+ String[] array = new String[names.size()];
+ names.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return names of all templates from the path portion of this HTTP location in the order they appear.
+ */
+ public String[] getTemplateNamesInPath() {
+ List names = new Vector();
+
+ Iterator it = fParsedList.iterator();
+ while(it.hasNext()) {
+ Object next = it.next();
+ if(next instanceof HTTPLocationTemplate) {
+ HTTPLocationTemplate template = (HTTPLocationTemplate)next;
+ if(!template.isQuery()) {
+ names.add(template.getName());
+ }
+ }
+ }
+
+ String[] array = new String[names.size()];
+ names.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return names of all templates from the query portion of this HTTP location in the order they appear.
+ */
+ public String[] getTemplateNamesInQuery() {
+ List names = new Vector();
+
+ Iterator it = fParsedList.iterator();
+ while(it.hasNext()) {
+ Object next = it.next();
+ if(next instanceof HTTPLocationTemplate) {
+ HTTPLocationTemplate template = (HTTPLocationTemplate)next;
+ if(template.isQuery()) {
+ names.add(template.getName());
+ }
+ }
+ }
+
+ String[] array = new String[names.size()];
+ names.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return the first template with the specified name.
+ */
+ public HTTPLocationTemplate getTemplate(String name) {
+ HTTPLocationTemplate namedTemplate = null;
+ if(name != null) {
+ HTTPLocationTemplate[] templates = getTemplates();
+ for(int i=0; i<templates.length; i++) {
+ if(templates[i].getName().equals(name)) {
+ namedTemplate = templates[i];
+ break;
+ }
+ }
+ }
+ return namedTemplate;
+ }
+
+ /**
+ * Return an array of templates with the specified name.
+ */
+ public HTTPLocationTemplate[] getTemplates(String name) {
+ List namedTemplates = new Vector();
+ if(name != null) {
+ HTTPLocationTemplate[] templates = getTemplates();
+ for(int i=0; i<templates.length; i++) {
+ if(templates[i].getName().equals(name)) {
+ namedTemplates.add(templates[i]);
+ }
+ }
+ }
+
+ HTTPLocationTemplate[] array = new HTTPLocationTemplate[namedTemplates.size()];
+ namedTemplates.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return the first template from the path with the specified name
+ * (i.e. before the first occurrence of "?").
+ */
+ public HTTPLocationTemplate getTemplateInPath(String name) {
+ HTTPLocationTemplate namedTemplate = null;
+ if(name != null) {
+ HTTPLocationTemplate[] templates = getTemplatesInPath();
+ for(int i=0; i<templates.length; i++) {
+ if(templates[i].getName().equals(name)) {
+ namedTemplate = templates[i];
+ break;
+ }
+ }
+ }
+ return namedTemplate;
+ }
+
+ /**
+ * Return an array of templates from the path with the specified name
+ * (i.e. before the first occurrence of "?").
+ */
+ public HTTPLocationTemplate[] getTemplatesInPath(String name) {
+ List namedTemplates = new Vector();
+ if(name != null) {
+ HTTPLocationTemplate[] templates = getTemplatesInPath();
+ for(int i=0; i<templates.length; i++) {
+ if(templates[i].getName().equals(name)) {
+ namedTemplates.add(templates[i]);
+ }
+ }
+ }
+
+ HTTPLocationTemplate[] array = new HTTPLocationTemplate[namedTemplates.size()];
+ namedTemplates.toArray(array);
+ return array;
+ }
+
+ /**
+ * Return the first template from the query with the specified name
+ * (i.e. after the first occurrence of "?").
+ */
+ public HTTPLocationTemplate getTemplateInQuery(String name) {
+ HTTPLocationTemplate namedTemplate = null;
+ if(name != null) {
+ HTTPLocationTemplate[] templates = getTemplatesInQuery();
+ for(int i=0; i<templates.length; i++) {
+ if(templates[i].getName().equals(name)) {
+ namedTemplate = templates[i];
+ break;
+ }
+ }
+ }
+ return namedTemplate;
+ }
+
+ /**
+ * Return an array of templates from the query with the specified name
+ * (i.e. after the first occurrence of "?").
+ */
+ public HTTPLocationTemplate[] getTemplatesInQuery(String name) {
+ List namedTemplates = new Vector();
+ if(name != null) {
+ HTTPLocationTemplate[] templates = getTemplatesInQuery();
+ for(int i=0; i<templates.length; i++) {
+ if(templates[i].getName().equals(name)) {
+ namedTemplates.add(templates[i]);
+ }
+ }
+ }
+
+ HTTPLocationTemplate[] array = new HTTPLocationTemplate[namedTemplates.size()];
+ namedTemplates.toArray(array);
+ return array;
+ }
+
+
+ /*
+ * TODO - for WODEN-148, fully support the EBNF grammar in this parsing logic
+ *
+ * Scan location char by char left to right. Add {!, {, }, {{ or }} or any
+ * string between these add as tokens in a new ordered list. Also, scan for
+ * the first occurrence of the '?' character, which separates
+ * the path from the query, and add this to the list.
+ * Return this new tokenized list to be used as input to the template validation step.
+ */
+ private List tokenizeTemplate() {
+
+ StringBuffer buffer = new StringBuffer();
+ int len = fLocationTemplate.length();
+ char currChar;
+ int lastPos = len-1;
+ List tokens = new Vector();
+ boolean questionMarkFound = false;
+
+ for(int i=0; i<len; i++) {
+ currChar = fLocationTemplate.charAt(i);
+ if(currChar == '?' && !questionMarkFound) {
+ questionMarkFound = true;
+ tokens.add(questionMark);
+ } else if(currChar == '{') {
+ if(buffer.length() > 0) {
+ tokens.add(buffer.toString());
+ buffer = new StringBuffer();
+ }
+ if(i < lastPos && fLocationTemplate.charAt(i+1) == '{') {
+ tokens.add(doubleLeftBraces);
+ i++; //continue scan from the 2nd left curly brace
+ } else if(i < lastPos && fLocationTemplate.charAt(i+1) == '!') {
+ tokens.add(exclamatedLeftBrace);
+ i++; //continue scan from the exclamation mark
+ } else {
+ tokens.add(leftBrace);
+ }
+ } else if(currChar == '}') {
+ if(buffer.length() > 0) {
+ tokens.add(buffer.toString());
+ buffer = new StringBuffer();
+ }
+ if(i < lastPos && fLocationTemplate.charAt(i+1) == '}') {
+ tokens.add(doubleRightBraces);
+ i++; //move loop position to the 2nd right curly brace
+ } else {
+ tokens.add(rightBrace);
+ }
+
+ } else {
+ buffer.append(currChar);
+ }
+ }
+
+ if(buffer.length() > 0) {
+ tokens.add(buffer.toString());
+ }
+
+ return tokens;
+ }
+
+ /*
+ * Identify any encoded or raw templates and check that their enclosed string is of type
+ * xs:NCName (i.e. the type required for an element local name).
+ * Encoded templates have a matching pairs of left and right curly braces "{...}".
+ * Raw templates have an exclamated left brace and a right brace "{!...}".
+ *
+ * TODO modify the validation logic below to match the EBNF grammar added to the spec. WODEN-148
+ *
+ * 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 right braces follow a left brace, pair the left most one with the left brace
+ * and treat the others as unmatched right braces.
+ * Any unmatched left or right braces are added to the output list. Their presence in this list
+ * can be used later to identify this type of error.
+ *
+ * Replace curly brace-enclosed strings with an HTTPLocationTemplate object in the output list.
+ * If the enclosed string is not of type NCName, add it to the output list as a single string
+ * with its enclosing left and right braces (e.g. "{invalid:name}"). This type of string can be
+ * used later to identify this type of error.
+ *
+ * Any double curly braces '{{' or '}}' are copied directly to the output list.
+ * Any other strings in the input list are also copied directly to the output list.
+ *
+ * This output list of valid and in-error items can be used to identify particular types of
+ * errors present in the template and is also used as input to the final parsing step.
+ *
+ */
+ private void validateTemplate(List tokenizedList) {
+
+ boolean valid = true;
+ List tokens = new Vector();
+ Object currToken;
+ String nextToken;
+ Object nextNextToken;
+ int size = tokenizedList.size();
+ ListIterator it = tokenizedList.listIterator();
+ boolean isQuery = false;
+
+ while(it.hasNext()) {
+ currToken = it.next();
+ int currIndex = it.previousIndex();
+ if(currToken == leftBrace || currToken == exclamatedLeftBrace) {
+ if(size-currIndex < 3) {
+ valid = false; //left brace or exclamated left brace not followed by a name and a right brace
+ tokens.add(currToken);
+ } else {
+ 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)) {
+ boolean isEncoded = (currToken == leftBrace);
+ HTTPLocationTemplate template =
+ new HTTPLocationTemplate(nextToken, isEncoded, isQuery);
+ tokens.add(template);
+ } else {
+ valid = false; //invalid format for a local name
+ StringBuffer buffer = new StringBuffer(leftBrace);
+ buffer.append(nextToken);
+ buffer.append(rightBrace);
+ tokens.add(buffer.toString());
+ }
+ it.next(); //local name
+ it.next(); //right curly brace
+ } else {
+ //TODO handle a string containing double curly brace as an invalid local name, not an unmatched left brace.
+ valid = false; //left brace not followed by a name and a right brace
+ tokens.add(leftBrace);
+ }
+ }
+ } else if(currToken == rightBrace) {
+ //right brace not preceded by a name and a left brace
+ valid = false;
+ tokens.add(rightBrace);
+ } else if(currToken == questionMark) {
+ isQuery = true; //this marks the start of the query string
+ tokens.add(questionMark);
+ } else {
+ //This token is double left or double right curly braces or some string
+ //other than "{", "{!", "}" or "?".
+ tokens.add(currToken);
+ }
+
+ } //end while loop
+
+ fValid = valid;
+ fValidatedList = tokens;
+ }
- /**
- * This constructor creates an HTTPLocation object from the specified String. This
- * String is the original value of the {http location} property, prior to any template
- * substitution of element local names enclosed in curly braces with element values.
- * If the property was parsed from a WSDL document, this will be the value of the
- * <code>whttp:location</code> attribute within a binding operation element.
- * <p>
- * The location template String argument must not be null.
- *
- * @param location the String value of the http location
+ /*
+ * Create a final parsed list of items from the location template, which can be used
+ * for value substitution and for creating the external representation of the
+ * location after substitution. The output list will contain just HTTPLocationTemplate
+ * object and strings concatenating any other content that appears between templates.
+ * These string concatentations will include any double curly braces, replaced by a single brace.
+ * They will also include any invalid curly brace-enclosed strings (e.g. "{invalid:name}").
*/
- public HTTPLocation(String location) {
- fLocationTemplate = location;
+ private void parseTemplate() {
- 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();
+ StringBuffer buffer = new StringBuffer();
+ Object currToken;
+ List tokens = new Vector();
+ Iterator it = fValidatedList.iterator();
+
+ while(it.hasNext()) {
+ currToken = it.next();
+ if(currToken instanceof HTTPLocationTemplate) {
+ //This is a templated local name, so output any previously concatentated
+ //string content then output this template.
+ if(buffer.length() > 0) {
+ tokens.add(buffer.toString());
+ buffer = new StringBuffer();
+ }
+ tokens.add(currToken);
+ } else if(currToken == doubleLeftBraces) {
+ buffer.append(leftBrace);
+ } else if(currToken == doubleRightBraces) {
+ buffer.append(rightBrace);
+ } else {
+ //just append this to any previous string content
+ buffer.append(currToken);
}
}
+
+ if(buffer.length() > 0) {
+ tokens.add(buffer.toString());
+ }
+
+ fParsedList = tokens;
}
+ //===============================================================================
+
+ /*
+ * The following methods are deprecated from Woden M7. JIRA WODEN-148 has modified the way
+ * HTTP location template is treated and has introduced a new type, HTTPLocationTemplate,
+ * and new methods to access this type. Once we have confirmed this new approach is
+ * suitable and functionally correct, the following deprecated methods will be removed
+ * (i.e. prior to Woden M8)
+ */
+
+ //===============================================================================
+
/**
* Returns true if the format of the the {http location} property prior to any
* template substitution is valid, otherwise false.
*
* TODO add more javadoc
- *
+ * @deprecated by WODEN-148
*/
public boolean isTemplateValid() {
return fValid;
@@ -133,6 +664,8 @@
* substitution of element local names enclosed in curly braces with element values.
* If the property was parsed from a WSDL document, this will be the value of the
* <code>whttp:location</code> attribute within a binding operation element.
+ *
+ * @deprecated by WODEN-148
*/
public String getLocationTemplate() {
return fLocationTemplate;
@@ -145,6 +678,8 @@
* the template, multiple corresponding occurrences will be present in the array.
*
* @return a String array containing all element local names from the template
+ *
+ * @deprecated by WODEN-148
*/
public String[] getLocalNames() {
@@ -173,6 +708,8 @@
* only the first occurrence will be present in the array.
*
* @return a String array containing the distinct element local names from the template
+ *
+ * @deprecated by WODEN-148
*/
public String[] getDistinctLocalNames() {
@@ -202,6 +739,8 @@
* This is equal to <code>getLocalNames().length</code>.
*
* @return the number of occurrences of <code>localName</code>
+ *
+ * @deprecated by WODEN-148
*/
public int countLocalNames() {
@@ -226,6 +765,8 @@
*
* @param localName the local name of an element from the instance data of the message
* @return the number of occurrences of <code>localName</code>
+ *
+ * @deprecated by WODEN-148
*/
public int countOccurrences(String localName) {
@@ -260,6 +801,8 @@
*
* @param localName the local name of an element from the instance data of the message
* @param value the value to be substitute for <code>localName</code>
+ *
+ * @deprecated by WODEN-148
*/
public void substitute(String localName, String value) {
@@ -281,6 +824,8 @@
* or just the first
*
* //TODO determine if this method is actually needed and if not, remove it.
+ *
+ * @deprecated by WODEN-148
*/
public void substitute(String localName, String value, boolean allOccurrences) {
@@ -324,6 +869,8 @@
* @param localName the local name of an element from the instance data of the message
* @param values a String array containing the values to be substituted for occurrences of
* <code>localName</code>, in order.
+ *
+ * @deprecated by WODEN-148
*/
public void substitute(String localName, String[] values) {
@@ -363,6 +910,8 @@
*
* @param values a String array containing the values to be substituted for any occurrences of an
* element local name within the template, in order.
+ *
+ * @deprecated by WODEN-148
*/
public void substitute(String[] values) {
@@ -401,6 +950,8 @@
*
* @param localName the local name of an element from the instance data of the message
* @return the String value associated with <code>localName</code>
+ *
+ * @deprecated by WODEN-148
*/
public String getValue(String localName) {
@@ -436,6 +987,7 @@
*
* @param localName the local name of an element from the instance data of the message
* @return an array of String values associated with occurrences of <code>localName</code>
+ * @deprecated by WODEN-148
*/
public String[] getValues(String localName) {
@@ -470,6 +1022,7 @@
* yet happened for a local name, the corresponding array element will be null.
*
* @return an array of String values associated with element local names within the template
+ * @deprecated by WODEN-148
*/
public String[] getValues() {
@@ -490,224 +1043,6 @@
values.toArray(array);
return array;
}
-
- /**
- * Returns a String representing the HTTP Location template with any element name/value
- * substitution that has taken place via the <code>substitute</code> methods.
- * If any element local name has not yet been substituted with a value then that
- * local name will appear in the String in its original template form, enclosed in
- * curly braces.
- * <p>
- * If the HTTP Location does not contain any curly brace template syntax then substitution
- * is not applicable and this method will return the same String value as the
- * <code>getLocationTemplate()</code> method.
- */
- public String toString() {
-
- if(fDerivedLocation != null) {
- return fDerivedLocation;
- }
-
- StringBuffer buffer = new StringBuffer();
- Object currToken;
- String[] nameValue;
- Iterator it = fParsedList.iterator();
-
- while(it.hasNext()) {
- currToken = it.next();
- if(currToken instanceof String[]) {
- nameValue = (String[])currToken;
- if(nameValue[1] == null) {
- //no value substitution, so append the original curly brace-enclosed string
- buffer.append(leftBrace);
- buffer.append(nameValue[0]);
- buffer.append(rightBrace);
- } else {
- //append the substituted element value
- buffer.append(nameValue[1]);
- }
- } else {
- buffer.append(currToken);
- }
- }
-
- fDerivedLocation = buffer.toString();
-
- return fDerivedLocation;
- }
-
- /*
- * Scan location char by char left to right. Add {, }, {{ or }} or any
- * string between these add as tokens in a new ordered list. Return this new
- * tokenized list to be used as input to the template validation step.
- */
- private List tokenizeTemplate() {
-
- StringBuffer buffer = new StringBuffer();
- int len = fLocationTemplate.length();
- char currChar;
- int lastPos = len-1;
- List tokens = new Vector();
-
- for(int i=0; i<len; i++) {
- currChar = fLocationTemplate.charAt(i);
- if(currChar == '{') {
- if(buffer.length() > 0) {
- tokens.add(buffer.toString());
- buffer = new StringBuffer();
- }
- if(i < lastPos && fLocationTemplate.charAt(i+1) == '{') {
- tokens.add(doubleLeftBraces);
- i++; //move loop position to the 2nd left curly brace
- } else {
- tokens.add(leftBrace);
- }
- } else if(currChar == '}') {
- if(buffer.length() > 0) {
- tokens.add(buffer.toString());
- buffer = new StringBuffer();
- }
- if(i < lastPos && fLocationTemplate.charAt(i+1) == '}') {
- tokens.add(doubleRightBraces);
- i++; //move loop position to the 2nd right curly brace
- } else {
- tokens.add(rightBrace);
- }
-
- } else {
- buffer.append(currChar);
- }
- }
-
- if(buffer.length() > 0) {
- tokens.add(buffer.toString());
- }
-
- return tokens;
- }
- /*
- * Identify matching pairs of left and right curly braces with a string in between and check
- * that the string between them is of type xs:NCName (i.e. the type required for an element
- * local name).
- * 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 right braces follow a left brace, pair the left most one with the left brace
- * and treat the others as unmatched right braces.
- * Any unmatched left or right braces are added to the output list. Their presence in this list
- * can be used later to identify this type of error.
- *
- * Replace valid curly brace-enclosed strings with a 2 element String array in the output list.
- * The first element is the local name string and the second element, initialized to null,
- * represents the element value.
- * If the enclosed string is not of type NCName, add it to the output list as a single string
- * with its enclosing left and right braces (e.g. "{invalid:name}"). This type of string can be
- * used later to identify this type of error.
- *
- * Any double curly braces '{{' or '}}' are copied directly to the output list.
- * Any other strings in the input list are also copied directly to the output list.
- *
- * This output list of valid and in-error items can be used to identify particular types of
- * errors present in the template and is also used as input to the final parsing step.
- *
- */
- private void validateTemplate(List tokenizedList) {
-
- boolean valid = true;
- List tokens = new Vector();
- Object currToken;
- String nextToken;
- Object nextNextToken;
- int size = tokenizedList.size();
- ListIterator it = tokenizedList.listIterator();
-
- while(it.hasNext()) {
- 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 {
- 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)) {
- String[] nameValue = new String[] {nextToken, null};
- tokens.add(nameValue);
- } else {
- valid = false; //invalid format for a local name
- StringBuffer buffer = new StringBuffer(leftBrace);
- buffer.append(nextToken);
- buffer.append(rightBrace);
- tokens.add(buffer.toString());
- }
- it.next(); //local name
- it.next(); //right curly brace
- } else {
- //TODO handle a string containing double curly brace as an invalid local name, not an unmatched left brace.
- valid = false; //left brace not followed by a name and a right brace
- tokens.add(leftBrace);
- }
- }
- } else if(currToken == rightBrace) {
- //right brace not preceded by a name and a left brace
- valid = false;
- tokens.add(rightBrace);
- } else {
- //This token is double left or double right curly braces or some string
- //other than a single curly brace.
- tokens.add(currToken);
- }
-
- } //end while loop
-
- fValid = valid;
- fValidatedList = tokens;
- }
-
- /*
- * Create a final parsed list of items from the location template, which can be used
- * for value substitution and for creating the external representation of the
- * location after substitution. The output list will contain either the 2 element
- * string arrays representing templated local names or strings concatenating any
- * other content that appears between templated names. These string concatentations
- * will include any double curly braces, replaced by a single brace. They will also
- * include any invalid curly brace-enclosed strings (e.g. "{invalid:name}").
- */
- private void parseTemplate() {
-
- StringBuffer buffer = new StringBuffer();
- Object currToken;
- List tokens = new Vector();
- Iterator it = fValidatedList.iterator();
-
- while(it.hasNext()) {
- 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.
- if(buffer.length() > 0) {
- tokens.add(buffer.toString());
- buffer = new StringBuffer();
- }
- tokens.add(currToken);
- } else if(currToken == doubleLeftBraces) {
- buffer.append(leftBrace);
- } else if(currToken == doubleRightBraces) {
- buffer.append(rightBrace);
- } else {
- //just append this to any previous string content
- buffer.append(currToken);
- }
- }
-
- if(buffer.length() > 0) {
- tokens.add(buffer.toString());
- }
-
- fParsedList = tokens;
- }
}
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=516631&r1=516630&r2=516631
==============================================================================
--- 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 Fri Mar 9 17:11:46 2007
@@ -80,6 +80,45 @@
}
+ public void testGetTemplate() {
+
+ //TODO rewrite these tests as sep methods.
+
+ HTTPLocation loc;
+ loc = new HTTPLocation("/temperature/{town}/{!state}/{country}?acct={acctNo}&bal={!balance}");
+
+ HTTPLocationTemplate template;
+ HTTPLocationTemplate[] templates;
+
+ templates = loc.getTemplates();
+ assertEquals("Incorrect number of templates", 5, templates.length);
+
+ templates = loc.getTemplatesInPath();
+ assertEquals("Incorrect number of templates", 3, templates.length);
+
+ templates = loc.getTemplatesInQuery();
+ assertEquals("Incorrect number of templates", 2, templates.length);
+
+ template = loc.getTemplate("town");
+ assertNotNull("expected a template", template);
+ assertTrue(template.isEncoded());
+ assertNull(template.getValue());
+
+ templates = loc.getTemplatesInPath("state");
+ assertEquals(1, templates.length);
+ assertFalse(templates[0].isEncoded());
+ assertFalse(templates[0].isQuery());
+
+ template = loc.getTemplateInQuery("acctNo");
+ assertTrue(template.isQuery());
+ template.setValue("dummy");
+ assertEquals("dummy", template.getValue());
+
+ }
+
+
+/* The following tests are for methods deprecated by WODEN-148...to be removed
+
public void testGetLocationTemplate() throws Exception
{
HTTPLocation loc;
@@ -151,13 +190,14 @@
loc = new HTTPLocation("/foo/{bar}/man{");
result = loc.isTemplateValid();
assertFalse(result);
-
+ */
/* 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);
@@ -187,12 +227,13 @@
loc = new HTTPLocation("/foo/{bar}/man}");
result = loc.isTemplateValid();
assertFalse(result);
-
+ */
/* 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);
@@ -584,6 +625,7 @@
assertEquals("?op={EchoInt};f}{irst{}=Dougal;middle}=Malcolm;last{=MacDonald;{", actual);
}
+*/
private boolean arraysEqual(String[] a1, String[] a2) {
boolean result = true;
---------------------------------------------------------------------
To unsubscribe, e-mail: woden-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: woden-dev-help@ws.apache.org