View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.model.propertyexpansion;
14  
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  import com.eviware.soapui.SoapUI;
19  import com.eviware.soapui.model.ModelItem;
20  import com.eviware.soapui.model.propertyexpansion.resolvers.ContextPropertyResolver;
21  import com.eviware.soapui.model.propertyexpansion.resolvers.DynamicPropertyResolver;
22  import com.eviware.soapui.model.propertyexpansion.resolvers.EvalPropertyResolver;
23  import com.eviware.soapui.model.propertyexpansion.resolvers.GlobalPropertyResolver;
24  import com.eviware.soapui.model.propertyexpansion.resolvers.MockRunPropertyResolver;
25  import com.eviware.soapui.model.propertyexpansion.resolvers.ModelItemPropertyResolver;
26  import com.eviware.soapui.model.propertyexpansion.resolvers.PropertyResolver;
27  import com.eviware.soapui.model.propertyexpansion.resolvers.SubmitPropertyResolver;
28  import com.eviware.soapui.model.propertyexpansion.resolvers.TestRunPropertyResolver;
29  import com.eviware.soapui.settings.GlobalPropertySettings;
30  import com.eviware.soapui.support.StringUtils;
31  import com.eviware.soapui.support.xml.XmlUtils;
32  
33  /***
34   * Class that can expand properties using property resolvers
35   * 
36   * @author ole
37   */
38  
39  public class PropertyExpander
40  {
41  	private List<PropertyResolver> propertyResolvers = new ArrayList<PropertyResolver>();
42  	private static List<PropertyResolver> defaultResolvers = new ArrayList<PropertyResolver>();
43  	private static PropertyExpander defaultExpander;
44  
45  	static
46  	{
47  		// add default resolvers - this should be read from some external config
48  		// in the future
49  		defaultResolvers.add( new ModelItemPropertyResolver() );
50  		defaultResolvers.add( new TestRunPropertyResolver() );
51  		defaultResolvers.add( new MockRunPropertyResolver() );
52  		defaultResolvers.add( new SubmitPropertyResolver() );
53  		defaultResolvers.add( new ContextPropertyResolver() );
54  		defaultResolvers.add( new DynamicPropertyResolver() );
55  		defaultResolvers.add( new GlobalPropertyResolver() );
56  		defaultResolvers.add( new EvalPropertyResolver() );
57  
58  		defaultExpander = new PropertyExpander( true );
59  	}
60  
61  	public PropertyExpander( boolean addDefaultResolvers )
62  	{
63  		if( addDefaultResolvers )
64  		{
65  			propertyResolvers.addAll( defaultResolvers );
66  		}
67  	}
68  
69  	public static PropertyExpander getDefaultExpander()
70  	{
71  		return defaultExpander;
72  	}
73  
74  	public static void addDefaultResolver( PropertyResolver resolver )
75  	{
76  		defaultResolvers.add( resolver );
77  		defaultExpander.addResolver( resolver );
78  	}
79  
80  	public void addResolver( PropertyResolver propertyResolver )
81  	{
82  		propertyResolvers.add( propertyResolver );
83  	}
84  
85  	public static String expandProperties( String content )
86  	{
87  		return defaultExpander.expand( content );
88  	}
89  
90  	public static String expandProperties( PropertyExpansionContext context, String content )
91  	{
92  		return defaultExpander.expand( context, content, false );
93  	}
94  
95  	public static String expandProperties( PropertyExpansionContext context, String content, boolean entitize )
96  	{
97  		return defaultExpander.expand( context, content, entitize );
98  	}
99  
100 	public String expand( String content )
101 	{
102 		return expand( new PropertyExpansionUtils.GlobalPropertyExpansionContext(), content, false );
103 	}
104 
105 	public String expand( PropertyExpansionContext context, String content )
106 	{
107 		return expand( context, content, false );
108 	}
109 
110 	public String expand( PropertyExpansionContext context, String content, boolean entitize )
111 	{
112 		if( StringUtils.isNullOrEmpty( content ) )
113 			return content;
114 
115 		int ix = content.indexOf( "${" );
116 		if( ix == -1 )
117 			return content;
118 
119 		StringBuffer buf = new StringBuffer();
120 		int lastIx = 0;
121 		while( ix != -1 )
122 		{
123 			if( ix > lastIx )
124 				buf.append( content.substring( lastIx, ix ) );
125 
126 			int ix2 = content.indexOf( '}', ix + 2 );
127 			if( ix2 == -1 )
128 				break;
129 
130 			// check for nesting
131 			int ix3 = content.lastIndexOf( "${", ix2 );
132 			if( ix3 != ix )
133 			{
134 				// buf.append( content.substring( ix, ix3 ));
135 				content = content.substring( 0, ix3 ) + expand( context, content.substring( ix3, ix2 + 1 ) )
136 						+ content.substring( ix2 + 1 );
137 
138 				lastIx = ix;
139 				continue;
140 			}
141 
142 			String propertyName = content.substring( ix + 2, ix2 );
143 			String propertyValue = null;
144 
145 			if( StringUtils.hasContent( propertyName ) )
146 			{
147 				boolean globalOverrideEnabled = SoapUI.getSettings().getBoolean( GlobalPropertySettings.ENABLE_OVERRIDE );
148 
149 				for( int c = 0; c < propertyResolvers.size() && propertyValue == null; c++ )
150 				{
151 					propertyValue = propertyResolvers.get( c )
152 							.resolveProperty( context, propertyName, globalOverrideEnabled );
153 				}
154 			}
155 
156 			// found a value?
157 			if( propertyValue != null )
158 			{
159 				if( !content.equals( propertyValue ) )
160 					propertyValue = expand( context, propertyValue );
161 
162 				if( entitize )
163 					propertyValue = XmlUtils.entitizeContent( propertyValue );
164 
165 				buf.append( propertyValue );
166 			}
167 			else
168 			{
169 				// if( log.isEnabledFor( Priority.WARN ))
170 				// log.warn( "Missing property value for [" + propertyName + "]" );
171 
172 				// buf.append( "${" ).append( propertyName ).append( '}' );
173 			}
174 
175 			lastIx = ix2 + 1;
176 			ix = content.indexOf( "${", lastIx );
177 		}
178 
179 		if( lastIx < content.length() )
180 			buf.append( content.substring( lastIx ) );
181 
182 		return buf.toString();
183 	}
184 
185 	public String expand( ModelItem contextModelItem, String content )
186 	{
187 		return expand( new DefaultPropertyExpansionContext( contextModelItem ), content );
188 	}
189 
190 	public static String expandProperties( ModelItem contextModelItem, String content )
191 	{
192 		return defaultExpander.expand( contextModelItem, content );
193 	}
194 
195 }