View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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;
14  
15  import com.eviware.soapui.config.SoapuiSettingsDocumentConfig;
16  import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
17  import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
18  import com.eviware.soapui.model.settings.Settings;
19  import com.eviware.soapui.monitor.MockEngine;
20  import com.eviware.soapui.settings.*;
21  import com.eviware.soapui.support.ClasspathHacker;
22  import com.eviware.soapui.support.Tools;
23  import com.eviware.soapui.support.action.SoapUIActionRegistry;
24  import com.eviware.soapui.support.listener.SoapUIListenerRegistry;
25  import com.eviware.soapui.support.types.StringList;
26  import org.apache.commons.ssl.OpenSSL;
27  import org.apache.log4j.Logger;
28  import org.apache.log4j.xml.DOMConfigurator;
29  
30  import javax.swing.*;
31  import java.io.File;
32  import java.io.FileInputStream;
33  import java.io.IOException;
34  import java.io.UnsupportedEncodingException;
35  import java.net.URL;
36  import java.security.GeneralSecurityException;
37  
38  /***
39   * Initializes core objects. Transform to a Spring "ApplicationContext"?
40   * 
41   * @author ole.matzura
42   */
43  
44  public class DefaultSoapUICore implements SoapUICore
45  {
46  	public static Logger log;
47  
48  	private boolean logIsInitialized;
49  	private String root;
50  	protected SoapuiSettingsDocumentConfig settingsDocument;
51  	private MockEngine mockEngine;
52  	private XmlBeansSettingsImpl settings;
53  	private SoapUIListenerRegistry listenerRegistry;
54  	private SoapUIActionRegistry actionRegistry;
55  
56  	private String settingsFile;
57  
58  	private String password;
59  
60  	protected boolean initialImport;
61  
62  	public boolean getInitialImport()
63  	{
64  		return initialImport;
65  	}
66  
67  	public void setInitialImport(boolean initialImport)
68  	{
69  		this.initialImport = initialImport;
70  	}
71  
72  	public static DefaultSoapUICore createDefault()
73  	{
74  		return new DefaultSoapUICore(null, DEFAULT_SETTINGS_FILE);
75  	}
76  
77  	public DefaultSoapUICore()
78  	{
79  	}
80  
81  	public DefaultSoapUICore(String root)
82  	{
83  		this.root = root;
84  	}
85  
86  	public DefaultSoapUICore(String root, String settingsFile)
87  	{
88  		this(root);
89  		init(settingsFile);
90  	}
91  
92  	public DefaultSoapUICore(String root, String settingsFile, String password)
93  	{
94  		this(root);
95  		this.password = password;
96  		init(settingsFile);
97  	}
98  
99  	public void init(String settingsFile)
100 	{
101 		initLog();
102 
103 		SoapUI.setSoapUICore(this);
104 
105 		loadExternalLibraries();
106 		initSettings(settingsFile == null ? DEFAULT_SETTINGS_FILE : settingsFile);
107 
108 		initCoreComponents();
109 		initExtensions(getExtensionClassLoader());
110 
111 		SoapVersion.Soap11.equals(SoapVersion.Soap12);
112 
113 	}
114 
115 	protected void initExtensions(ClassLoader extensionClassLoader)
116 	{
117 		String extDir = System.getProperty("soapui.ext.listeners");
118 		addExternalListeners(extDir != null ? extDir : root == null ? "listeners" : root + File.separatorChar
119 				+ "listeners", extensionClassLoader);
120 	}
121 
122 	protected ClassLoader getExtensionClassLoader()
123 	{
124 		return SoapUI.class.getClassLoader();
125 	}
126 
127 	protected void initCoreComponents()
128 	{
129 	}
130 
131 	public String getRoot()
132 	{
133 		if (root == null || root.length() == 0)
134 			root = System.getProperty("soapui.home", new File("").getAbsolutePath());
135 		return root;
136 	}
137 
138 	protected Settings initSettings(String fileName)
139 	{
140 
141 		try
142 		{
143 			File settingsFile = new File(new File(getRoot()), fileName);
144 			if (!settingsFile.exists())
145 			{
146 				if (settingsDocument == null)
147 				{
148 					log.info("Creating new settings at [" + settingsFile.getAbsolutePath() + "]");
149 					settingsDocument = SoapuiSettingsDocumentConfig.Factory.newInstance();
150 					setInitialImport(true);
151 				}
152 			}
153 			else
154 			{
155 				settingsDocument = SoapuiSettingsDocumentConfig.Factory.parse(settingsFile);
156 
157 				byte[] encryptedContent = settingsDocument.getSoapuiSettings().getEncryptedContent();
158 				if (encryptedContent != null)
159 				{
160 					char[] password = null;
161 					if (this.password == null)
162 					{
163 						// swing element -!! uh!
164 						JPasswordField passwordField = new JPasswordField();
165 						JLabel qLabel = new JLabel("Password");
166 						JOptionPane.showConfirmDialog(null, new Object[] { qLabel, passwordField }, "Global Settings",
167 								JOptionPane.OK_CANCEL_OPTION);
168 						password = passwordField.getPassword();
169 					}
170 					else
171 					{
172 						password = this.password.toCharArray();
173 					}
174 
175 					byte[] data = OpenSSL.decrypt("des3", password, encryptedContent);
176 					try
177 					{
178 						settingsDocument = SoapuiSettingsDocumentConfig.Factory.parse(new String(data, "UTF-8"));
179 					}
180 					catch (Exception e)
181 					{
182 						log.warn("Wrong password.");
183 						JOptionPane.showMessageDialog(null, "Wrong password, creating backup settings file [ "
184 								+ settingsFile.getAbsolutePath() + ".bak.xml. ]\nSwitch to default settings.",
185 								"Error - Wrong Password", JOptionPane.ERROR_MESSAGE);
186 						settingsDocument.save(new File(settingsFile.getAbsolutePath() + ".bak.xml"));
187 						throw e;
188 					}
189 				}
190 
191 				log.info("initialized soapui-settings from [" + settingsFile.getAbsolutePath() + "]");
192 			}
193 		}
194 		catch (Exception e)
195 		{
196 			log.warn("Failed to load settings from [" + e.getMessage() + "], creating new");
197 			settingsDocument = SoapuiSettingsDocumentConfig.Factory.newInstance();
198 		}
199 
200 		if (settingsDocument.getSoapuiSettings() == null)
201 		{
202 			settingsDocument.addNewSoapuiSettings();
203 			settings = new XmlBeansSettingsImpl(null, null, settingsDocument.getSoapuiSettings());
204 
205 			initDefaultSettings(settings);
206 		}
207 		else
208 		{
209 			settings = new XmlBeansSettingsImpl(null, null, settingsDocument.getSoapuiSettings());
210 		}
211 
212 		this.settingsFile = fileName;
213 
214 		if (!settings.isSet(WsdlSettings.EXCLUDED_TYPES))
215 		{
216 			StringList list = new StringList();
217 			list.add("schema@http://www.w3.org/2001/XMLSchema");
218 			settings.setString(WsdlSettings.EXCLUDED_TYPES, list.toXml());
219 		}
220 
221 		if (!settings.isSet(WsdlSettings.NAME_WITH_BINDING))
222 		{
223 			settings.setBoolean(WsdlSettings.NAME_WITH_BINDING, true);
224 		}
225 
226 		if (!settings.isSet(HttpSettings.MAX_CONNECTIONS_PER_HOST))
227 		{
228 			settings.setLong(HttpSettings.MAX_CONNECTIONS_PER_HOST, 500);
229 		}
230 
231 		if (!settings.isSet(HttpSettings.MAX_TOTAL_CONNECTIONS))
232 		{
233 			settings.setLong(HttpSettings.MAX_TOTAL_CONNECTIONS, 2000);
234 		}
235 
236 		if (!settings.isSet(UISettings.AUTO_SAVE_PROJECTS_ON_EXIT))
237 		{
238 			settings.setBoolean(UISettings.AUTO_SAVE_PROJECTS_ON_EXIT, true);
239 		}
240 
241 		if (!settings.isSet(UISettings.SHOW_DESCRIPTIONS))
242 		{
243 			settings.setBoolean(UISettings.SHOW_DESCRIPTIONS, true);
244 		}
245 
246 		if (!settings.isSet(WsaSettings.USE_DEFAULT_RELATES_TO))
247 		{
248 			settings.setBoolean(WsaSettings.USE_DEFAULT_RELATES_TO, true);
249 		}
250 
251 		if (!settings.isSet(WsaSettings.USE_DEFAULT_RELATIONSHIP_TYPE))
252 		{
253 			settings.setBoolean(WsaSettings.USE_DEFAULT_RELATIONSHIP_TYPE, true);
254 		}
255 
256 		return settings;
257 	}
258 
259 	/*
260 	 * (non-Javadoc)
261 	 * 
262 	 * @see com.eviware.soapui.SoapUICore#importSettings(java.io.File)
263 	 */
264 	public void importSettings(File file) throws Exception
265 	{
266 		File toFile = null;
267 		if (file != null)
268 		{
269 			log.info("Importing preferences from [" + file.getAbsolutePath() + "]");
270 			toFile = new File(getRoot(), file.getName());
271 			log.info("Copy preferences from [" + file.getAbsolutePath() + "] to [" + toFile.getAbsolutePath() + "]");
272 			Tools.copyFile(file, toFile, true);
273 			initSettings(file.getName());
274 		}
275 	}
276 
277 	/*
278 	 * (non-Javadoc)
279 	 * 
280 	 * @see com.eviware.soapui.SoapUICore#getSettings()
281 	 */
282 	public Settings getSettings()
283 	{
284 		if (settings == null)
285 		{
286 			initSettings(DEFAULT_SETTINGS_FILE);
287 		}
288 
289 		return settings;
290 	}
291 
292 	protected void initDefaultSettings(Settings settings2)
293 	{
294 		settings.setBoolean(WsdlSettings.CACHE_WSDLS, true);
295 		settings.setBoolean(WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES, true);
296 
297 		settings.setBoolean(HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN, true);
298 		settings.setBoolean(HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN, true);
299 
300 		settings.setString(UISettings.AUTO_SAVE_INTERVAL, "0");
301 		settings.setBoolean(UISettings.SHOW_STARTUP_PAGE, true);
302 
303 		settings.setBoolean(WsaSettings.SOAP_ACTION_OVERRIDES_WSA_ACTION, false);
304 		settings.setBoolean(WsaSettings.USE_DEFAULT_RELATIONSHIP_TYPE, true);
305 		settings.setBoolean(WsaSettings.USE_DEFAULT_RELATES_TO, true);
306 		settings.setBoolean(WsaSettings.OVERRIDE_EXISTING_HEADERS, false);
307 		settings.setBoolean(WsaSettings.ENABLE_FOR_OPTIONAL, false);
308 	}
309 
310 	/*
311 	 * (non-Javadoc)
312 	 * 
313 	 * @see com.eviware.soapui.SoapUICore#saveSettings()
314 	 */
315 	public String saveSettings() throws Exception
316 	{
317 		if (settingsFile == null)
318 			settingsFile = DEFAULT_SETTINGS_FILE;
319 
320 		File file = new File(new File(getRoot()), settingsFile);
321 
322 		SoapuiSettingsDocumentConfig settingsDocument = (SoapuiSettingsDocumentConfig) this.settingsDocument.copy();
323 		String password = settings.getString(SecuritySettings.SHADOW_PASSWORD, null);
324 
325 		if (password != null && password.length() > 0)
326 		{
327 			try
328 			{
329 				byte[] data = settingsDocument.xmlText().getBytes();
330 				byte[] encryptedData = OpenSSL.encrypt("des3", password.toCharArray(), data);
331 				settingsDocument.setSoapuiSettings(null);
332 				settingsDocument.getSoapuiSettings().setEncryptedContent(encryptedData);
333 			}
334 			catch (UnsupportedEncodingException e)
335 			{
336 				log.error("Encryption error", e);
337 			}
338 			catch (IOException e)
339 			{
340 				log.error("Encryption error", e);
341 			}
342 			catch (GeneralSecurityException e)
343 			{
344 				log.error("Encryption error", e);
345 			}
346 		}
347 
348 		settingsDocument.save(file);
349 		log.info("Settings saved to [" + file.getAbsolutePath() + "]");
350 		return file.getAbsolutePath();
351 	}
352 
353 	public String getSettingsFile()
354 	{
355 		return settingsFile;
356 	}
357 
358 	public void setSettingsFile(String settingsFile)
359 	{
360 		this.settingsFile = settingsFile;
361 	}
362 
363 	protected void initLog()
364 	{
365 		if (!logIsInitialized)
366 		{
367 			File log4jconfig = root == null ? new File("soapui-log4j.xml") : new File(new File(getRoot()), "soapui-log4j.xml");
368 			if (log4jconfig.exists())
369 			{
370 				System.out.println("Configuring log4j from [" + log4jconfig.getAbsolutePath() + "]");
371 				DOMConfigurator.configureAndWatch(log4jconfig.getAbsolutePath(), 5000);
372 			}
373 			else
374 			{
375 				URL url = getClass().getResource("/com/eviware/soapui/resources/conf/soapui-log4j.xml");
376 				if (url != null)
377 				{
378 					DOMConfigurator.configure(url);
379 				}
380 				else
381 					System.err.println("Missing soapui-log4j.xml configuration");
382 			}
383 
384 			logIsInitialized = true;
385 
386 			log = Logger.getLogger(DefaultSoapUICore.class);
387 		}
388 	}
389 
390 	protected void loadExternalLibraries()
391 	{
392 		try
393 		{
394 			String extDir = System.getProperty("soapui.ext.libraries");
395 
396 			File dir = extDir != null ? new File(extDir) : new File(new File(getRoot()), "ext");
397 
398 			if (dir.exists() && dir.isDirectory())
399 			{
400 				File[] files = dir.listFiles();
401 				for (File file : files)
402 				{
403 					if (file.getName().toLowerCase().endsWith(".jar"))
404 					{
405 						ClasspathHacker.addFile(file);
406 					}
407 				}
408 			}
409 			else
410 			{
411 				log.warn("Missing folder [" + dir.getAbsolutePath() + "] for external libraries");
412 			}
413 		}
414 		catch (Exception e)
415 		{
416 			log.error(e.toString());
417 		}
418 	}
419 
420 	/*
421 	 * (non-Javadoc)
422 	 * 
423 	 * @see com.eviware.soapui.SoapUICore#getMockEngine()
424 	 */
425 	public MockEngine getMockEngine()
426 	{
427 		if (mockEngine == null)
428 			mockEngine = new MockEngine();
429 
430 		return mockEngine;
431 	}
432 
433 	/*
434 	 * (non-Javadoc)
435 	 * 
436 	 * @see com.eviware.soapui.SoapUICore#getListenerRegistry()
437 	 */
438 	public SoapUIListenerRegistry getListenerRegistry()
439 	{
440 		if (listenerRegistry == null)
441 			initListenerRegistry();
442 
443 		return listenerRegistry;
444 	}
445 
446 	protected void initListenerRegistry()
447 	{
448 		listenerRegistry = new SoapUIListenerRegistry(null);
449 	}
450 
451 	/*
452 	 * (non-Javadoc)
453 	 * 
454 	 * @see com.eviware.soapui.SoapUICore#getActionRegistry()
455 	 */
456 	public SoapUIActionRegistry getActionRegistry()
457 	{
458 		if (actionRegistry == null)
459 			actionRegistry = initActionRegistry();
460 
461 		return actionRegistry;
462 	}
463 
464 	protected SoapUIActionRegistry initActionRegistry()
465 	{
466 		return new SoapUIActionRegistry(DefaultSoapUICore.class
467 				.getResourceAsStream("/com/eviware/soapui/resources/conf/soapui-actions.xml"));
468 	}
469 
470 	protected void addExternalListeners(String folder, ClassLoader classLoader)
471 	{
472 		File[] actionFiles = new File(folder).listFiles();
473 		if (actionFiles != null)
474 		{
475 			for (File actionFile : actionFiles)
476 			{
477 				if (actionFile.isDirectory())
478 				{
479 					addExternalListeners(actionFile.getAbsolutePath(), classLoader);
480 					continue;
481 				}
482 
483 				if (!actionFile.getName().toLowerCase().endsWith("-listeners.xml"))
484 					continue;
485 
486 				try
487 				{
488 					log.info("Adding listeners from [" + actionFile.getAbsolutePath() + "]");
489 
490 					SoapUI.getListenerRegistry().addConfig(new FileInputStream(actionFile), classLoader);
491 				}
492 				catch (Exception e)
493 				{
494 					SoapUI.logError(e);
495 				}
496 			}
497 		}
498 	}
499 }