View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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  package com.eviware.soapui.impl.wsdl.submit.transports.jms.util;
13  
14  import hermes.Hermes;
15  import hermes.HermesInitialContextFactory;
16  import hermes.JAXBHermesLoader;
17  
18  import java.io.File;
19  import java.io.FileNotFoundException;
20  import java.io.IOException;
21  import java.net.MalformedURLException;
22  import java.net.URL;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Properties;
28  
29  import javax.naming.Context;
30  import javax.naming.InitialContext;
31  import javax.naming.NamingException;
32  
33  import com.eviware.soapui.SoapUI;
34  import com.eviware.soapui.SoapUIExtensionClassLoader;
35  import com.eviware.soapui.SoapUIExtensionClassLoader.SoapUIClassLoaderState;
36  import com.eviware.soapui.actions.SoapUIPreferencesAction;
37  import com.eviware.soapui.impl.wsdl.WsdlProject;
38  import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
39  import com.eviware.soapui.settings.ToolsSettings;
40  import com.eviware.soapui.support.Tools;
41  import com.eviware.soapui.support.UISupport;
42  
43  public class HermesUtils
44  {
45  	private static boolean hermesJarsLoaded = false;
46  	private static Map<String, Context> contextMap = new HashMap<String, Context>();
47  	public static String HERMES_CONFIG_XML = "hermes-config.xml";
48  
49  	public static Context hermesContext( WsdlProject project ) throws NamingException, MalformedURLException,
50  			IOException
51  	{
52  		String expandedHermesConfigPath = PropertyExpander.expandProperties( project, project.getHermesConfig() );
53  		String key = project.getName() + expandedHermesConfigPath;
54  		return getHermes( key, expandedHermesConfigPath );
55  	}
56  
57  	public static Context hermesContext( WsdlProject project, String hermesConfigPath ) throws NamingException,
58  			MalformedURLException, IOException
59  	{
60  		String expandedHermesConfigPath = PropertyExpander.expandProperties( project, hermesConfigPath );
61  		String key = project.getName() + expandedHermesConfigPath;
62  		return getHermes( key, expandedHermesConfigPath );
63  	}
64  
65  	// private static URLClassLoader hermesClassLoader;
66  
67  	private static Context getHermes( String key, String hermesConfigPath ) throws IOException, MalformedURLException,
68  			NamingException
69  	{
70  		SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
71  		if( !hermesJarsLoaded )
72  		{
73  			addHermesJarsToClasspath();
74  			hermesJarsLoaded = true;
75  		}
76  
77  		if( contextMap.containsKey( key ) )
78  		{
79  			return contextMap.get( key );
80  		}
81  
82  		// ClassLoader cl = Thread.currentThread().getContextClassLoader();
83  
84  		try
85  		{
86  			Thread.currentThread().setContextClassLoader( JAXBHermesLoader.class.getClassLoader());
87  			Properties props = new Properties();
88  			props.put( Context.INITIAL_CONTEXT_FACTORY, HermesInitialContextFactory.class.getName() );
89  			props.put( Context.PROVIDER_URL, hermesConfigPath + File.separator + HERMES_CONFIG_XML );
90  			props.put( "hermes.loader", JAXBHermesLoader.class.getName() );
91  			Context ctx = new InitialContext( props );
92  			contextMap.put( key, ctx );
93  			return ctx;
94  		}
95  		finally
96  		{
97  			state.restore();
98  		}
99  	}
100 
101 	private static void addHermesJarsToClasspath() throws IOException, MalformedURLException
102 	{
103 		String hermesHome = SoapUI.getSettings().getString( ToolsSettings.HERMES_JMS, defaultHermesJMSPath() );
104 
105 		if( hermesHome == null || "".equals( hermesHome ) )
106 		{
107 			hermesHome = createHermesHomeSetting();
108 			if( hermesHome == null )
109 				throw new FileNotFoundException( "HermesJMS home not specified !!!" );
110 		}
111 
112 		System.setProperty( "hermes.home", hermesHome );
113 
114 		String hermesLib = hermesHome + File.separator + "lib";
115 		File dir = new File( hermesLib );
116 
117 		File[] children = dir.listFiles();
118 		List<URL> urls = new ArrayList<URL>();
119 		for( File file : children )
120 		{
121 			// fix for users using version of hermesJMS which still has
122 			// cglib-2.1.3.jar in lib directory
123 			String filename = file.getName();
124 			if( !filename.endsWith( ".jar" ) || filename.equals( "cglib-2.1.3.jar" ) )
125 				continue;
126 
127 			urls.add( file.toURI().toURL() );
128 		
129 			SoapUIExtensionClassLoader.addUrlToClassLoader(  new File( dir, filename ).toURI().toURL(), JAXBHermesLoader.class.getClassLoader());
130 		}
131 
132 	}
133 
134 	public static void flushHermesCache()
135 	{
136 		contextMap.clear();
137 	}
138 
139 	private static String createHermesHomeSetting()
140 	{
141 		if( Tools.isEmpty( SoapUI.getSettings().getString( ToolsSettings.HERMES_JMS, defaultHermesJMSPath() ) ) )
142 		{
143 			UISupport.showErrorMessage( "HermesJMS Home must be set in global preferences" );
144 
145 			if( UISupport.getMainFrame() != null )
146 			{
147 				if( SoapUIPreferencesAction.getInstance().show( SoapUIPreferencesAction.INTEGRATED_TOOLS ) )
148 				{
149 					return SoapUI.getSettings().getString( ToolsSettings.HERMES_JMS, defaultHermesJMSPath() );
150 				}
151 			}
152 		}
153 		return null;
154 	}
155 
156 	public static String defaultHermesJMSPath()
157 	{
158 		try
159 		{
160 			String path = SoapUI.getSettings().getString( ToolsSettings.HERMES_JMS, null );
161 			if( path == null || "".equals( path ) )
162 			{
163 				String temp = System.getProperty( "soapui.home" ).substring( 0,
164 						System.getProperty( "soapui.home" ).lastIndexOf( "bin" ) - 1 );
165 				path = new File( temp + File.separator + "hermesJMS" ).getAbsolutePath().toString();
166 				SoapUI.log( "HermesJMS path: " + path );
167 			}
168 			setHermesJMSPath( path );
169 			return path;
170 		}
171 		catch( Exception e )
172 		{
173 			SoapUI.log( "No HermesJMS on default path %SOAPUI_HOME%/hermesJMS" );
174 			return null;
175 		}
176 
177 	}
178 
179 	public static void setHermesJMSPath( String path )
180 	{
181 		if( path != null )
182 			SoapUI.getSettings().setString( ToolsSettings.HERMES_JMS, path );
183 	}
184 
185 	/***
186 	 * @param project
187 	 * @param sessionName
188 	 * 
189 	 * @return hermes.Hermes
190 	 * 
191 	 * @throws NamingException
192 	 */
193 	public static Hermes getHermes( WsdlProject project, String sessionName ) throws NamingException
194 	{
195 		SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
196 		try
197 		{
198 			Context ctx = hermesContext( project );
199 
200 			Hermes hermes = ( Hermes )ctx.lookup( sessionName );
201 			return hermes;
202 		}
203 		catch( NamingException ne )
204 		{
205 			UISupport
206 					.showErrorMessage( "Hermes configuration is not valid. Please check that 'Hermes Config' project property is set to path of proper hermes-config.xml file" );
207 			throw new NamingException( "Session name '" + sessionName
208 					+ "' does not exist in Hermes configuration or path to Hermes config ( " + project.getHermesConfig()
209 					+ " )is not valid !!!!" );
210 		}
211 		catch( MalformedURLException mue )
212 		{
213 			SoapUI.logError( mue );
214 		}
215 		catch( IOException ioe )
216 		{
217 			SoapUI.logError( ioe );
218 		}
219 		finally
220 		{
221 			state.restore();
222 		}
223 		return null;
224 	}
225 
226 	public static boolean isHermesJMSSupported()
227 	{
228 		return !UISupport.isIdePlugin();
229 	}
230 }