1 /**********************************************************************
2 * EJExecutor.java
3 * created on 09.07.2006 by netseeker
4 * $Source$
5 * $Date$
6 * $Revision$
7 *
8 * ====================================================================
9 *
10 * Copyright 2006 netseeker aka Michael Manske
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ====================================================================
24 *
25 * This file is part of the de.netseeker.ejoe.ext.crispy framework.
26 * For more information on the author, please see
27 * <http://www.manskes.de/>.
28 *
29 *********************************************************************/
30
31 package de.netseeker.ejoe.ext.crispy;
32
33 import java.lang.reflect.Method;
34 import java.util.Properties;
35
36 import net.sf.crispy.Executor;
37 import net.sf.crispy.InvocationException;
38 import net.sf.crispy.InvocationStrategy;
39 import de.netseeker.ejoe.EJClient;
40 import de.netseeker.ejoe.EJConstants;
41 import de.netseeker.ejoe.adapter.AdapterFactory;
42 import de.netseeker.ejoe.adapter.SerializeAdapter;
43 import de.netseeker.ejoe.request.RemotingRequest;
44 import de.netseeker.ejoe.util.ContentStringBuilder;
45
46 /***
47 * A dynamic proxy implementation for the great Crispy framework. EJExcecutor makes it possible to use EJOE as service
48 * within Crispy:
49 *
50 * <pre>
51 * Properties prop = new Properties();
52 * prop.put(Property.EXECUTOR_CLASS, EJExecutor.class.getName());
53 * prop.put(EJExecutor.EJOE_SERIALIZATION_ADAPTER, ObjectStreamAdapter.class.getName());
54 * prop.put(Property.REMOTE_URL_AND_PORT, "socket://localhost:12577");
55 * prop.put(EJExecutor.EJOE_USE_PERSISTENT_CONNECTION, Boolean.toString(true));
56 * //prop.put(EJExecutor.EJOE_IN_JVM, Boolean.toString(true));
57 * ServiceManager manager = new ServiceManager(prop);
58 * Echo e = (Echo) manager.createService(Echo.class);
59 * ...
60 * </pre>
61 *
62 * @author netseeker
63 * @since 0.3.9.1
64 * @see http://crispy.sourceforge.net/index.html
65 * @see de.netseeker.ejoe.test.crispy.EJCrispyTest
66 */
67 public class EJExecutor extends Executor
68 {
69 /***
70 * Tells the underlying EJClient which SerializationAdapter should be used
71 */
72 public static final String EJOE_SERIALIZATION_ADAPTER = "EJOE_SERIALIZATION_ADAPTER";
73
74 /***
75 * Tells the underlying EJClient if it should compress serialized objects when sending them through the socket
76 */
77 public static final String EJOE_USE_COMPRESSION = "EJOE_USE_COMPRESSION";
78
79 /***
80 * Tells the underlying EJClient if it should request and use a persistent connection from the EJServer
81 */
82 public static final String EJOE_USE_PERSISTENT_CONNECTION = "EJOE_USE_PERSISTENT_CONNECTION";
83
84 /***
85 * Tells the underlying EJClient how long it will wait for server response until it will assume a connection timeout
86 */
87 public static final String EJOE_CONNECTION_TIMEOUT = "EJOE_CONNECTION_TIMEOUT";
88
89 /***
90 * Tells the underlying EJClient if it should try to use EJOE remote classloading feature, eg. load unknown response
91 * types from the server via the EJClassLoader
92 */
93 public static final String EJOE_USE_REMOTE_CLASSLOADER = "EJOE_USE_REMOTE_CLASSLOADER";
94
95 /***
96 * Tells the underlying EJClient if it should use an existent In-JVM instance of EJServer, no socket connections
97 * will be used
98 */
99 public static final String EJOE_IN_JVM = "EJOE_IN_JVM";
100
101 private EJClient _ejclient;
102
103
104
105
106
107
108 public String getDefaultUrlAndPort()
109 {
110 return "socket://localhost:" + EJConstants.EJOE_PORT;
111 }
112
113
114
115
116
117
118 public InvocationStrategy getDefaultInvocationStrategy()
119 {
120 return new ClassAndMethodArrayInvocationStrategy();
121 }
122
123
124
125
126
127
128
129 public Object execute( Class pvProxyClass, Object pvProxy, Method pvMethod, Object[] pvArgs ) throws Exception
130 {
131 if ( _ejclient == null )
132 {
133 Properties props = getProperties();
134 String adapterKey = props.getProperty( EJOE_SERIALIZATION_ADAPTER, EJConstants.EJOE_DEFAULT_ADAPTER
135 .getName() );
136 boolean compression = Boolean
137 .valueOf( props.getProperty( EJOE_USE_COMPRESSION, Boolean.toString( false ) ) ).booleanValue();
138 boolean persistent = Boolean.valueOf(
139 props.getProperty( EJOE_USE_PERSISTENT_CONNECTION, Boolean
140 .toString( true ) ) ).booleanValue();
141 boolean classloading = Boolean.valueOf(
142 props.getProperty( EJOE_USE_REMOTE_CLASSLOADER, Boolean
143 .toString( false ) ) ).booleanValue();
144
145 boolean injvm = Boolean.valueOf( props.getProperty( EJOE_IN_JVM, Boolean.toString( false ) ) )
146 .booleanValue();
147
148 String address[] = getUrlAndPort().split( "://" );
149 boolean isHttp = address[0].equalsIgnoreCase( "http" );
150
151 if ( log.isDebugEnabled() )
152 {
153 log.debug( "EJOE Server address: " + ContentStringBuilder.toString( address ) );
154 log.debug( "Will use serialize adapter: " + adapterKey );
155 }
156
157 SerializeAdapter adapter = AdapterFactory.createAdapter( adapterKey );
158
159 int index = address[1].lastIndexOf( ':' );
160 String host = address[1].substring( 0, index );
161 String sPort = address[1].substring( index + 1 );
162 int port = Integer.parseInt( sPort );
163 _ejclient = new EJClient( host, port, adapter, persistent, isHttp, compression );
164
165 if ( classloading )
166 {
167 _ejclient.enableRemoteClassloading();
168 }
169
170 if ( props.getProperty( EJOE_CONNECTION_TIMEOUT ) != null )
171 {
172 int timeout = Integer.parseInt( props.getProperty( EJOE_CONNECTION_TIMEOUT ) );
173 _ejclient.setConnectionTimeout( timeout );
174 }
175
176 if ( injvm )
177 {
178 _ejclient.setInJVM( true );
179 }
180 }
181
182 Object ret = null;
183 RemotingRequest lvStrService = (RemotingRequest) getInvocationStrategy();
184 lvStrService.setArgs( pvArgs );
185
186 if ( log.isDebugEnabled() )
187 {
188 log.debug( "Invocation target: " + lvStrService.toString() );
189 }
190
191 try
192 {
193 ret = _ejclient.execute( lvStrService );
194 }
195 catch ( Exception e )
196 {
197 Throwable t = e;
198 if ( e.getCause() != null )
199 {
200 t = e.getCause();
201 }
202
203 throw new InvocationException( "Error by execute service: " + lvStrService.toString() + " -- "
204 + t.getMessage(), t );
205 }
206
207 return ret;
208 }
209 }