1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.FileOutputStream;
18 import java.io.IOException;
19 import java.io.UnsupportedEncodingException;
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.security.GeneralSecurityException;
23 import java.util.TimerTask;
24
25 import javax.swing.JLabel;
26 import javax.swing.JOptionPane;
27 import javax.swing.JPasswordField;
28
29 import org.apache.commons.ssl.OpenSSL;
30 import org.apache.log4j.Logger;
31 import org.apache.log4j.xml.DOMConfigurator;
32
33 import com.eviware.soapui.config.SoapuiSettingsDocumentConfig;
34 import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
35 import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
36 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
37 import com.eviware.soapui.model.settings.Settings;
38 import com.eviware.soapui.monitor.JettyMockEngine;
39 import com.eviware.soapui.monitor.MockEngine;
40 import com.eviware.soapui.settings.HttpSettings;
41 import com.eviware.soapui.settings.ProxySettings;
42 import com.eviware.soapui.settings.SecuritySettings;
43 import com.eviware.soapui.settings.UISettings;
44 import com.eviware.soapui.settings.WSISettings;
45 import com.eviware.soapui.settings.WebRecordingSettings;
46 import com.eviware.soapui.settings.WsaSettings;
47 import com.eviware.soapui.settings.WsdlSettings;
48 import com.eviware.soapui.support.StringUtils;
49 import com.eviware.soapui.support.action.SoapUIActionRegistry;
50 import com.eviware.soapui.support.listener.SoapUIListenerRegistry;
51 import com.eviware.soapui.support.types.StringList;
52
53 /***
54 * Initializes core objects. Transform to a Spring "ApplicationContext"?
55 *
56 * @author ole.matzura
57 */
58
59 public class DefaultSoapUICore implements SoapUICore
60 {
61 public static Logger log;
62
63 private boolean logIsInitialized;
64 private String root;
65 protected SoapuiSettingsDocumentConfig settingsDocument;
66 private MockEngine mockEngine;
67 private XmlBeansSettingsImpl settings;
68 private SoapUIListenerRegistry listenerRegistry;
69 private SoapUIActionRegistry actionRegistry;
70 private long lastSettingsLoad = 0;
71
72 private String settingsFile;
73 private String password;
74 protected boolean initialImport;
75 private TimerTask settingsWatcher;
76 private SoapUIExtensionClassLoader extClassLoader;
77
78 public boolean isSavingSettings;
79
80 public boolean getInitialImport()
81 {
82 return initialImport;
83 }
84
85 public void setInitialImport( boolean initialImport )
86 {
87 this.initialImport = initialImport;
88 }
89
90 public static DefaultSoapUICore createDefault()
91 {
92 return new DefaultSoapUICore( null, DEFAULT_SETTINGS_FILE );
93 }
94
95 public DefaultSoapUICore()
96 {
97 }
98
99
100
101
102
103
104 public DefaultSoapUICore( boolean settingPassword, String soapUISettingsPassword )
105 {
106 this.password = soapUISettingsPassword;
107 }
108
109 public DefaultSoapUICore( String root )
110 {
111 this.root = root;
112 }
113
114 public DefaultSoapUICore( String root, String settingsFile )
115 {
116 this( root );
117 init( settingsFile );
118 }
119
120 public DefaultSoapUICore( String root, String settingsFile, String password )
121 {
122 this( root );
123 this.password = password;
124 init( settingsFile );
125 }
126
127 public void init( String settingsFile )
128 {
129 initLog();
130
131 SoapUI.setSoapUICore( this );
132
133 loadExternalLibraries();
134 initSettings( settingsFile == null ? DEFAULT_SETTINGS_FILE : settingsFile );
135
136 initCoreComponents();
137 initExtensions( getExtensionClassLoader() );
138
139 SoapVersion.Soap11.equals( SoapVersion.Soap12 );
140
141 }
142
143 protected void initExtensions( ClassLoader extensionClassLoader )
144 {
145 String extDir = System.getProperty( "soapui.ext.listeners" );
146 addExternalListeners( extDir != null ? extDir : root == null ? "listeners" : root + File.separatorChar
147 + "listeners", extensionClassLoader );
148 }
149
150 protected void initCoreComponents()
151 {
152 }
153
154 public String getRoot()
155 {
156 if( root == null || root.length() == 0 )
157 root = System.getProperty( "soapui.home", new File( "." ).getAbsolutePath() );
158 return root;
159 }
160
161 protected Settings initSettings( String fileName )
162 {
163
164
165
166 File settingsFile = new File( fileName ).exists() ? new File( fileName ) : null;
167
168 try
169 {
170 if( settingsFile == null )
171 {
172 settingsFile = new File( new File( getRoot() ), DEFAULT_SETTINGS_FILE );
173 if( !settingsFile.exists() )
174 {
175 settingsFile = new File( new File( System.getProperty( "user.home", "." ) ), DEFAULT_SETTINGS_FILE );
176 lastSettingsLoad = 0;
177 }
178 }
179 else
180 {
181 settingsFile = new File( fileName );
182 if( !settingsFile.getAbsolutePath().equals( this.settingsFile ) )
183 lastSettingsLoad = 0;
184 }
185
186 if( !settingsFile.exists() )
187 {
188 if( settingsDocument == null )
189 {
190 log.info( "Creating new settings at [" + settingsFile.getAbsolutePath() + "]" );
191 settingsDocument = SoapuiSettingsDocumentConfig.Factory.newInstance();
192 setInitialImport( true );
193 }
194
195 lastSettingsLoad = System.currentTimeMillis();
196 }
197 else if( settingsFile.lastModified() > lastSettingsLoad )
198 {
199 settingsDocument = SoapuiSettingsDocumentConfig.Factory.parse( settingsFile );
200
201 byte[] encryptedContent = settingsDocument.getSoapuiSettings().getEncryptedContent();
202 if( encryptedContent != null )
203 {
204 char[] password = null;
205 if( this.password == null )
206 {
207
208 JPasswordField passwordField = new JPasswordField();
209 JLabel qLabel = new JLabel( "Password" );
210 JOptionPane.showConfirmDialog( null, new Object[] { qLabel, passwordField }, "Global Settings",
211 JOptionPane.OK_CANCEL_OPTION );
212 password = passwordField.getPassword();
213 }
214 else
215 {
216 password = this.password.toCharArray();
217 }
218
219 byte[] data = OpenSSL.decrypt( "des3", password, encryptedContent );
220 try
221 {
222 settingsDocument = SoapuiSettingsDocumentConfig.Factory.parse( new String( data, "UTF-8" ) );
223 }
224 catch( Exception e )
225 {
226 log.warn( "Wrong password." );
227 JOptionPane.showMessageDialog( null, "Wrong password, creating backup settings file [ "
228 + settingsFile.getAbsolutePath() + ".bak.xml. ]\nSwitch to default settings.",
229 "Error - Wrong Password", JOptionPane.ERROR_MESSAGE );
230 settingsDocument.save( new File( settingsFile.getAbsolutePath() + ".bak.xml" ) );
231 throw e;
232 }
233 }
234
235 log.info( "initialized soapui-settings from [" + settingsFile.getAbsolutePath() + "]" );
236 lastSettingsLoad = settingsFile.lastModified();
237
238 if( settingsWatcher == null )
239 {
240 settingsWatcher = new SettingsWatcher();
241 SoapUI.getSoapUITimer().scheduleAtFixedRate( settingsWatcher, 10000, 10000 );
242 }
243 }
244 }
245 catch( Exception e )
246 {
247 log.warn( "Failed to load settings from [" + e.getMessage() + "], creating new" );
248 settingsDocument = SoapuiSettingsDocumentConfig.Factory.newInstance();
249 lastSettingsLoad = 0;
250 }
251
252 if( settingsDocument.getSoapuiSettings() == null )
253 {
254 settingsDocument.addNewSoapuiSettings();
255 settings = new XmlBeansSettingsImpl( null, null, settingsDocument.getSoapuiSettings() );
256
257 initDefaultSettings( settings );
258 }
259 else
260 {
261 settings = new XmlBeansSettingsImpl( null, null, settingsDocument.getSoapuiSettings() );
262 }
263
264 this.settingsFile = settingsFile.getAbsolutePath();
265
266 if( !settings.isSet( WsdlSettings.EXCLUDED_TYPES ) )
267 {
268 StringList list = new StringList();
269 list.add( "schema@http://www.w3.org/2001/XMLSchema" );
270 settings.setString( WsdlSettings.EXCLUDED_TYPES, list.toXml() );
271 }
272
273 if( !settings.isSet( WebRecordingSettings.EXCLUDED_HEADERS ) )
274 {
275 StringList list = new StringList();
276 list.add( "Cookie" );
277 list.add( "Set-Cookie" );
278 list.add( "Referer" );
279 list.add( "Keep-Alive" );
280 list.add( "Connection" );
281 list.add( "Proxy-Connection" );
282 list.add( "Pragma" );
283 list.add( "Cache-Control" );
284 list.add( "Transfer-Encoding" );
285 list.add( "Date" );
286 settings.setString( WebRecordingSettings.EXCLUDED_HEADERS, list.toXml() );
287 }
288
289 if( settings.getString( HttpSettings.HTTP_VERSION, HttpSettings.HTTP_VERSION_1_1 ).equals(
290 HttpSettings.HTTP_VERSION_0_9 ) )
291 {
292 settings.setString( HttpSettings.HTTP_VERSION, HttpSettings.HTTP_VERSION_1_1 );
293 }
294
295 setIfNotSet( WsdlSettings.NAME_WITH_BINDING, true );
296 setIfNotSet( WsdlSettings.NAME_WITH_BINDING, 500 );
297 setIfNotSet( HttpSettings.HTTP_VERSION, HttpSettings.HTTP_VERSION_1_1 );
298 setIfNotSet( HttpSettings.MAX_TOTAL_CONNECTIONS, 2000 );
299 setIfNotSet( HttpSettings.RESPONSE_COMPRESSION, true );
300 setIfNotSet( HttpSettings.LEAVE_MOCKENGINE, true );
301 setIfNotSet( UISettings.AUTO_SAVE_PROJECTS_ON_EXIT, true );
302 setIfNotSet( UISettings.SHOW_DESCRIPTIONS, true );
303 setIfNotSet( WsdlSettings.XML_GENERATION_ALWAYS_INCLUDE_OPTIONAL_ELEMENTS, true );
304 setIfNotSet( WsaSettings.USE_DEFAULT_RELATES_TO, true );
305 setIfNotSet( WsaSettings.USE_DEFAULT_RELATIONSHIP_TYPE, true );
306 setIfNotSet( UISettings.SHOW_STARTUP_PAGE, true );
307 setIfNotSet( UISettings.GC_INTERVAL, "60" );
308 setIfNotSet( WsdlSettings.CACHE_WSDLS, true );
309 setIfNotSet( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES, true );
310 setIfNotSet( HttpSettings.RESPONSE_COMPRESSION, true );
311 setIfNotSet( HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN, true );
312 setIfNotSet( HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN, true );
313 setIfNotSet( HttpSettings.LEAVE_MOCKENGINE, true );
314 setIfNotSet( UISettings.AUTO_SAVE_INTERVAL, "0" );
315 setIfNotSet( UISettings.GC_INTERVAL, "60" );
316 setIfNotSet( UISettings.SHOW_STARTUP_PAGE, true );
317 setIfNotSet( WsaSettings.SOAP_ACTION_OVERRIDES_WSA_ACTION, false );
318 setIfNotSet( WsaSettings.USE_DEFAULT_RELATIONSHIP_TYPE, true );
319 setIfNotSet( WsaSettings.USE_DEFAULT_RELATES_TO, true );
320 setIfNotSet( WsaSettings.OVERRIDE_EXISTING_HEADERS, false );
321 setIfNotSet( WsaSettings.ENABLE_FOR_OPTIONAL, false );
322
323 boolean setWsiDir = false;
324 String wsiLocationString = settings.getString( WSISettings.WSI_LOCATION, null );
325 if( StringUtils.isNullOrEmpty( wsiLocationString ) )
326 {
327 setWsiDir = true;
328 }
329 else
330 {
331 File wsiFile = new File( wsiLocationString );
332 if( !wsiFile.exists() )
333 {
334 setWsiDir = true;
335 }
336 }
337 if( setWsiDir )
338 {
339 String wsiDir = System.getProperty( "wsi.dir", new File( "." ).getAbsolutePath() );
340 settings.setString( WSISettings.WSI_LOCATION, wsiDir );
341 }
342 HttpClientSupport.addSSLListener( settings );
343
344 return settings;
345 }
346
347 private void setIfNotSet( String id, boolean value )
348 {
349 if( !settings.isSet( id ) )
350 settings.setBoolean( id, true );
351 }
352
353 private void setIfNotSet( String id, String value )
354 {
355 if( !settings.isSet( id ) )
356 settings.setString( id, value );
357 }
358
359 private void setIfNotSet( String id, long value )
360 {
361 if( !settings.isSet( id ) )
362 settings.setLong( id, value );
363 }
364
365
366
367
368
369
370 public Settings importSettings( File file ) throws Exception
371 {
372 if( file != null )
373 {
374 log.info( "Importing preferences from [" + file.getAbsolutePath() + "]" );
375 return initSettings( file.getAbsolutePath() );
376 }
377 return null;
378 }
379
380
381
382
383
384
385 public Settings getSettings()
386 {
387 if( settings == null )
388 {
389 initSettings( DEFAULT_SETTINGS_FILE );
390 }
391
392 return settings;
393 }
394
395 protected void initDefaultSettings( Settings settings2 )
396 {
397
398 }
399
400
401
402
403
404
405 public String saveSettings() throws Exception
406 {
407 isSavingSettings = true;
408 try
409 {
410 if( settingsFile == null )
411 settingsFile = getRoot() + File.separatorChar + DEFAULT_SETTINGS_FILE;
412
413
414 File file = new File( settingsFile );
415 if( !file.canWrite() )
416 {
417 file = new File( new File( System.getProperty( "user.home", "." ) ), DEFAULT_SETTINGS_FILE );
418 }
419
420 SoapuiSettingsDocumentConfig settingsDocument = ( SoapuiSettingsDocumentConfig )this.settingsDocument.copy();
421 String password = settings.getString( SecuritySettings.SHADOW_PASSWORD, null );
422
423 if( password != null && password.length() > 0 )
424 {
425 try
426 {
427 byte[] data = settingsDocument.xmlText().getBytes();
428 byte[] encryptedData = OpenSSL.encrypt( "des3", password.toCharArray(), data );
429 settingsDocument.setSoapuiSettings( null );
430 settingsDocument.getSoapuiSettings().setEncryptedContent( encryptedData );
431 }
432 catch( UnsupportedEncodingException e )
433 {
434 log.error( "Encryption error", e );
435 }
436 catch( IOException e )
437 {
438 log.error( "Encryption error", e );
439 }
440 catch( GeneralSecurityException e )
441 {
442 log.error( "Encryption error", e );
443 }
444 }
445
446 FileOutputStream out = new FileOutputStream( file );
447 settingsDocument.save( out );
448 out.flush();
449 out.close();
450 log.info( "Settings saved to [" + file.getAbsolutePath() + "]" );
451 lastSettingsLoad = file.lastModified();
452 return file.getAbsolutePath();
453 }
454 finally
455 {
456 isSavingSettings = false;
457 }
458 }
459
460 public String getSettingsFile()
461 {
462 return settingsFile;
463 }
464
465 public void setSettingsFile( String settingsFile )
466 {
467 this.settingsFile = settingsFile;
468 }
469
470 protected void initLog()
471 {
472 if( !logIsInitialized )
473 {
474 File log4jconfig = root == null ? new File( "soapui-log4j.xml" ) : new File( new File( getRoot() ),
475 "soapui-log4j.xml" );
476 if( log4jconfig.exists() )
477 {
478 System.out.println( "Configuring log4j from [" + log4jconfig.getAbsolutePath() + "]" );
479 DOMConfigurator.configureAndWatch( log4jconfig.getAbsolutePath(), 5000 );
480 }
481 else
482 {
483 URL url = SoapUI.class.getResource( "/com/eviware/soapui/resources/conf/soapui-log4j.xml" );
484 if( url != null )
485 {
486 DOMConfigurator.configure( url );
487 }
488 else
489 System.err.println( "Missing soapui-log4j.xml configuration" );
490 }
491
492 logIsInitialized = true;
493
494 log = Logger.getLogger( DefaultSoapUICore.class );
495 }
496 }
497
498 public synchronized void loadExternalLibraries()
499 {
500 if( extClassLoader == null )
501 {
502 try
503 {
504 extClassLoader = SoapUIExtensionClassLoader.create( getRoot(), getExtensionClassLoaderParent() );
505 }
506 catch( MalformedURLException e )
507 {
508 SoapUI.logError( e );
509 }
510 }
511 }
512
513 protected ClassLoader getExtensionClassLoaderParent()
514 {
515 return SoapUI.class.getClassLoader();
516 }
517
518 public SoapUIExtensionClassLoader getExtensionClassLoader()
519 {
520 if( extClassLoader == null )
521 loadExternalLibraries();
522
523 return extClassLoader;
524 }
525
526
527
528
529
530
531 public MockEngine getMockEngine()
532 {
533 if( mockEngine == null )
534 mockEngine = buildMockEngine();
535
536 return mockEngine;
537 }
538
539 protected MockEngine buildMockEngine()
540 {
541 return new JettyMockEngine();
542 }
543
544
545
546
547
548
549 public SoapUIListenerRegistry getListenerRegistry()
550 {
551 if( listenerRegistry == null )
552 initListenerRegistry();
553
554 return listenerRegistry;
555 }
556
557 protected void initListenerRegistry()
558 {
559 listenerRegistry = new SoapUIListenerRegistry( null );
560 }
561
562
563
564
565
566
567 public SoapUIActionRegistry getActionRegistry()
568 {
569 if( actionRegistry == null )
570 actionRegistry = initActionRegistry();
571
572 return actionRegistry;
573 }
574
575 protected SoapUIActionRegistry initActionRegistry()
576 {
577 return new SoapUIActionRegistry(
578 DefaultSoapUICore.class.getResourceAsStream( "/com/eviware/soapui/resources/conf/soapui-actions.xml" ) );
579 }
580
581 protected void addExternalListeners( String folder, ClassLoader classLoader )
582 {
583 File[] actionFiles = new File( folder ).listFiles();
584 if( actionFiles != null )
585 {
586 for( File actionFile : actionFiles )
587 {
588 if( actionFile.isDirectory() )
589 {
590 addExternalListeners( actionFile.getAbsolutePath(), classLoader );
591 continue;
592 }
593
594 if( !actionFile.getName().toLowerCase().endsWith( "-listeners.xml" ) )
595 continue;
596
597 try
598 {
599 log.info( "Adding listeners from [" + actionFile.getAbsolutePath() + "]" );
600
601 SoapUI.getListenerRegistry().addConfig( new FileInputStream( actionFile ), classLoader );
602 }
603 catch( Exception e )
604 {
605 SoapUI.logError( e );
606 }
607 }
608 }
609 }
610
611 private class SettingsWatcher extends TimerTask
612 {
613 @Override
614 public void run()
615 {
616 if( settingsFile != null && !isSavingSettings )
617 {
618 File file = new File( settingsFile );
619 if( file.exists() && file.lastModified() > lastSettingsLoad )
620 {
621 log.info( "Reloading updated settings file" );
622 initSettings( settingsFile );
623 SoapUI.setProxyEnabled( getSettings().getBoolean( ProxySettings.ENABLE_PROXY ) );
624 }
625 }
626 }
627 }
628 }