001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.submit.filters;
014:
015: import org.apache.log4j.Logger;
016: import org.apache.log4j.Priority;
017: import org.apache.xmlbeans.XmlObject;
018:
019: import com.eviware.soapui.SoapUI;
020: import com.eviware.soapui.impl.wsdl.WsdlRequest;
021: import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
022: import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
023: import com.eviware.soapui.model.iface.SubmitContext;
024: import com.eviware.soapui.model.testsuite.TestRunContext;
025: import com.eviware.soapui.support.xml.XmlUtils;
026:
027: /**
028: * RequestFilter that expands properties in request content
029: *
030: * @author Ole.Matzura
031: */
032:
033: public class PropertyExpansionRequestFilter implements RequestFilter {
034: private static final char PROPERTY_SEPARATOR = '#';
035: private final static Logger log = Logger
036: .getLogger(PropertyExpansionRequestFilter.class);
037:
038: public void filterRequest(SubmitContext context,
039: WsdlRequest wsdlRequest) {
040: String content = (String) context
041: .getProperty(BaseHttpRequestTransport.REQUEST_CONTENT);
042: if (content == null) {
043: log
044: .warn("Missing request content in context, skipping property expansion");
045: } else {
046: content = expandProperties(context, content);
047: if (content != null)
048: context.setProperty(
049: BaseHttpRequestTransport.REQUEST_CONTENT,
050: content);
051: }
052: }
053:
054: @SuppressWarnings("deprecation")
055: public static String expandProperties(SubmitContext context,
056: String content) {
057: int ix = content.indexOf("${");
058: if (ix == -1)
059: return content;
060:
061: StringBuffer buf = new StringBuffer();
062: int lastIx = 0;
063: while (ix != -1) {
064: if (ix > lastIx)
065: buf.append(content.substring(lastIx, ix));
066:
067: int ix2 = content.indexOf('}', ix + 2);
068: if (ix2 == -1)
069: break;
070:
071: // check for nesting
072: int ix3 = content.lastIndexOf("${", ix2);
073: if (ix3 != ix) {
074: //buf.append( content.substring( ix, ix3 ));
075: content = content.substring(0, ix3)
076: + expandProperties(context, content.substring(
077: ix3, ix2 + 1))
078: + content.substring(ix2 + 1);
079:
080: lastIx = ix;
081: continue;
082: }
083:
084: String propertyName = content.substring(ix + 2, ix2);
085: Object property = context.getProperty(propertyName);
086: if (property != null) {
087: String value = property.toString();
088: if (!content.equals(value))
089: value = expandProperties(context, value);
090:
091: buf.append(value);
092: } else if (context instanceof TestRunContext) {
093: int sepIx = propertyName.indexOf(PROPERTY_SEPARATOR);
094: if (sepIx >= 0) {
095: String step = propertyName.substring(0, sepIx);
096: String name = propertyName.substring(sepIx + 1);
097:
098: sepIx = name.indexOf(PROPERTY_SEPARATOR);
099: if (sepIx != -1) {
100: String xpath = name.substring(sepIx + 1);
101: name = name.substring(0, sepIx);
102:
103: if (step.length() == 0)
104: property = ((TestRunContext) context)
105: .getProperty(name);
106: else
107: property = ((TestRunContext) context)
108: .getProperty(step, name);
109:
110: if (property != null) {
111: property = extractXPathPropertyValue(
112: property, xpath);
113: }
114: } else {
115: if (step.length() == 0)
116: property = ((TestRunContext) context)
117: .getProperty(name);
118: else
119: property = ((TestRunContext) context)
120: .getProperty(step, name);
121: }
122:
123: if (property != null) {
124: String value = property.toString();
125: if (!content.equals(value))
126: value = expandProperties(context, value);
127:
128: buf.append(value);
129: }
130: }
131: } else if (propertyName.charAt(0) == PROPERTY_SEPARATOR) {
132: int sepIx = propertyName.indexOf(PROPERTY_SEPARATOR, 1);
133: if (sepIx > 0) {
134: String xpath = propertyName.substring(sepIx + 1);
135: propertyName = propertyName.substring(1, sepIx);
136:
137: property = context.getProperty(propertyName);
138: if (property != null) {
139: property = extractXPathPropertyValue(property,
140: expandProperties(context, xpath));
141: }
142: } else {
143: property = context.getProperty(propertyName
144: .substring(1));
145: }
146:
147: if (property != null) {
148: String value = property.toString();
149: if (!content.equals(value))
150: value = expandProperties(context, value);
151:
152: buf.append(value);
153: }
154: }
155:
156: if (property == null) {
157: if (log.isEnabledFor(Priority.WARN))
158: log.warn("Missing property value for ["
159: + propertyName + "]");
160:
161: buf.append("${").append(propertyName).append('}');
162: }
163:
164: lastIx = ix2 + 1;
165: ix = content.indexOf("${", lastIx);
166: }
167:
168: if (lastIx < content.length())
169: buf.append(content.substring(lastIx));
170:
171: return buf.toString();
172: }
173:
174: public static String extractXPathPropertyValue(Object property,
175: String xpath) {
176: try {
177: XmlObject xmlObject = XmlObject.Factory.parse(property
178: .toString());
179: String ns = XmlUtils.declareXPathNamespaces(xmlObject);
180: XmlObject[] paths = xmlObject.selectPath(ns + xpath);
181: if (paths.length > 0)
182: return XmlUtils.getNodeValue(paths[0].getDomNode());
183: } catch (Exception e) {
184: SoapUI.logError(e);
185: }
186:
187: return null;
188: }
189: }
|