Subversion Repository Public Repository

litesoft

Diff Revisions 949 vs 950 for /trunk/Java/GWT/OldServer/src/org/litesoft/GWT/eventbus/server/AbstractServerApp.java

Diff revisions: vs.
  @@ -1,613 +1,613 @@
1 - // This Source Code is in the Public Domain per: http://unlicense.org
2 - package org.litesoft.GWT.eventbus.server;
3 -
4 - import org.litesoft.GWT.eventbus.client.*;
5 - import org.litesoft.GWT.eventbus.client.eventpackages.*;
6 - import org.litesoft.GWT.eventbus.client.nonpublic.*;
7 - import org.litesoft.GWT.eventbus.client.rpc.*;
8 - import org.litesoft.GWT.eventbus.server.nonpublic.*;
9 - import org.litesoft.commonfoundation.typeutils.*;
10 - import org.litesoft.commonfoundation.typeutils.gregorian.*;
11 - import org.litesoft.configuration.*;
12 - import org.litesoft.logger.*;
13 - import org.litesoft.logger.nonpublic.*;
14 - import org.litesoft.sequences.*;
15 - import org.litesoft.ui_1_5.def.nonpublic.*;
16 - import org.litesoft.util.*;
17 - import org.litesoft.util.template.*;
18 -
19 - import com.google.gwt.user.client.rpc.*;
20 - import com.google.gwt.user.server.rpc.*;
21 -
22 - import javax.servlet.*;
23 - import javax.servlet.http.*;
24 - import java.io.*;
25 - import java.util.*;
26 -
27 - public abstract class AbstractServerApp extends RemoteServiceServlet // don't forget this!
28 - implements EventBusRemoteService, // don't forget this!
29 - ConfigLoadedListener,
30 - ThreadLocalContextFactory {
31 - public static final String HINT_CATEGORY = "Configuration";
32 -
33 - protected static final String PLUS_OVERFLOW_HIDDEN = " overflow: hidden;";
34 - protected static final String BODY_STYLE_LESS_OVERFLOW = "border: none; padding: 0; margin: 0;";
35 - protected static final String FULL_BODY_STYLE = BODY_STYLE_LESS_OVERFLOW + PLUS_OVERFLOW_HIDDEN;
36 -
37 - protected static Logger getLogger() {
38 - Configuration.chkInstantiated();
39 - return ___NEVER_EVER_TO_USE_DIRECTLY_LOGGER_____USE_GetLogger_METHOD___;
40 - }
41 -
42 - private static final Logger ___NEVER_EVER_TO_USE_DIRECTLY_LOGGER_____USE_GetLogger_METHOD___ = LoggerFactory.getLogger( AbstractServerApp.class );
43 -
44 - private static boolean sOneTimeInitComplete = false;
45 -
46 - private static RuntimeException sOneTimeInitException = null;
47 -
48 - private Map<String, String> mClientConfig = new HashMap<String, String>();
49 -
50 - public void init()
51 - throws ServletException {
52 - super.init();
53 - synchronized ( AbstractServerApp.class ) {
54 - if ( getOneTimeInitException() != null ) {
55 - throw getOneTimeInitException();
56 - }
57 - if ( !isOneTimeInitComplete() ) {
58 - oneTimeInit();
59 - }
60 - }
61 - }
62 -
63 - private static synchronized boolean isOneTimeInitComplete() {
64 - return sOneTimeInitComplete;
65 - }
66 -
67 - private static synchronized RuntimeException getOneTimeInitException() {
68 - return sOneTimeInitException;
69 - }
70 -
71 - private static synchronized void setOneTimeInitException( RuntimeException pOneTimeInitException ) {
72 - sOneTimeInitException = pOneTimeInitException;
73 - }
74 -
75 - /**
76 - * Assumption is that this method will ALWAYS be called under synchronized( AbstractServerApp.class )!
77 - */
78 - protected void oneTimeInit() {
79 - System.err.println( new UtilDateAdaptor() + " | Application Server Start Up" );
80 - Configuration.add( this );
81 - try {
82 - // todo: translate: FormQueryFilter.registerRehydrateFactories();
83 - initializeHintValidators();
84 - instantiateConfiguration();
85 - logConfigurationLoadingWarnings();
86 - getLogger().trace.log( "ClientConfig: ", mClientConfig );
87 - startUpApplication();
88 - logServletContextInitParameterNames();
89 - initComplete();
90 - System.err.println( new UtilDateAdaptor() + " | Application Server Start Up Complete" );
91 - }
92 - catch ( RuntimeException e ) {
93 - setOneTimeInitException( e );
94 - throw e;
95 - }
96 - finally {
97 - sOneTimeInitComplete = true;
98 - }
99 - }
100 -
101 - private void logServletContextInitParameterNames() {
102 - if ( getLogger().info.isEnabled() ) {
103 - Enumeration zParamNames = getServletContext().getInitParameterNames();
104 - while ( zParamNames.hasMoreElements() ) {
105 - String zParamName = (String) zParamNames.nextElement();
106 - getLogger().info.log( "Context Param " + zParamName, " value is ", getServletContext().getInitParameter( zParamName ) );
107 - }
108 - }
109 - }
110 -
111 - protected void initializeHintValidators() {
112 - CommonHintValidators.register();
113 - }
114 -
115 - protected void addClientLoggingLevel( String pName, String pEffectiveLevel ) {
116 - mClientConfig.put( LoggerLevel.CONFIGURATION_BASE + pName, pEffectiveLevel );
117 - }
118 -
119 - private void logConfigurationLoadingWarnings() {
120 - if ( !mConfigurationLoadingWarning.isEmpty() ) {
121 - AbstractLogger logger = getLogger().warn;
122 - if ( logger.isEnabled() ) {
123 - for ( String warning : mConfigurationLoadingWarning ) {
124 - logger.log( warning );
125 - }
126 - }
127 - }
128 - }
129 -
130 - private List<String> mConfigurationLoadingWarning = new ArrayList<String>();
131 -
132 - protected void addConfigurationLoadingWarning( String pWarning ) {
133 - mConfigurationLoadingWarning.add( pWarning );
134 - }
135 -
136 - public void configurationJustLoaded() {
137 - loadClientConfigPath();
138 -
139 - String[] keys = Configuration.getAllKeys();
140 - for ( String key : keys ) {
141 - if ( key.startsWith( LoggerLevel.CONFIGURATION_BASE ) ) {
142 - mClientConfig.put( key, Configuration.getString( key ) );
143 - } else if ( key.startsWith( HintController.HINT_PROPERTY_PREFIX ) ) {
144 - String zName = key.substring( HintController.HINT_PROPERTY_PREFIX.length() ).trim();
145 - if ( zName.length() == 0 ) {
146 - addConfigurationLoadingWarning( "Configuration has entry with nothing after '" + HintController.HINT_PROPERTY_PREFIX + "'" );
147 - } else {
148 - String zValue = Configuration.getString( key );
149 - String problem = HintController.validate( HINT_CATEGORY, null, zName, zValue );
150 - if ( problem != null ) {
151 - if ( problem.length() != 0 ) {
152 - throw new IllegalStateException( "Unacceptable Configuration entry '" + key + "'='" + zValue + "':" + problem );
153 - }
154 - addConfigurationLoadingWarning( HintController.noValidatorText( HINT_CATEGORY, null, zName ) );
155 - }
156 - HintController.addGlobalHint( zName, zValue );
157 - }
158 - }
159 - }
160 - }
161 -
162 - protected void loadClientConfigPath() {
163 - File dir = ServerConfiguration.configFilesSubDirectoryByKey( "ClientConfigPath", null );
164 - if ( dir != null ) {
165 - Properties prop = loadProperties( dir.getAbsolutePath() );
166 - if ( prop != null ) {
167 - for ( Object key : prop.keySet() ) {
168 - if ( key != null ) {
169 - Object value = prop.get( key );
170 - if ( value != null ) {
171 - mClientConfig.put( key.toString(), value.toString() );
172 - }
173 - }
174 - }
175 - }
176 - }
177 - }
178 -
179 - private Properties loadProperties( String pPath ) {
180 - File fileAt = new File( pPath );
181 - FileInputStream is;
182 - try {
183 - is = new FileInputStream( fileAt );
184 - }
185 - catch ( IOException e ) {
186 - getLogger().error.log( e, "Unable to open: ", fileAt.getAbsolutePath() );
187 - return null;
188 - }
189 - try {
190 - Properties props = new Properties();
191 - props.load( is );
192 - System.out.println( "Loaded Client Configuration from: " + fileAt.getAbsolutePath() );
193 - return props;
194 - }
195 - catch ( IOException e ) {
196 - getLogger().error.log( e, "Unable to load: ", fileAt.getAbsolutePath() );
197 - return null;
198 - }
199 - finally {
200 - try {
201 - is.close();
202 - }
203 - catch ( IOException e ) {
204 - // Whatever...
205 - }
206 - }
207 - }
208 -
209 - protected void loadClientConfigConfigurationLoggerLevels() {
210 - String[] keys = Configuration.getAllKeys();
211 - for ( String key : keys ) {
212 - if ( key.startsWith( LoggerLevel.CONFIGURATION_BASE ) ) {
213 - mClientConfig.put( key, Configuration.getString( key ) );
214 - }
215 - }
216 - }
217 -
218 - public synchronized AppInitializationResult initialize( String pEncodedClientId ) {
219 - Integer existingClientIdNumber;
220 - try {
221 - existingClientIdNumber = ClientIdCodec.decode( pEncodedClientId );
222 - }
223 - catch ( RuntimeException e ) {
224 - getLogger().error.log( e, "initialize '", pEncodedClientId, "'" );
225 - throw e;
226 - }
227 - AppInitializationResult result;
228 - try {
229 - result = initializeForBrowserPageRequest( existingClientIdNumber );
230 - }
231 - catch ( RuntimeException e ) {
232 - getLogger().error.log( e, "initialize: ", existingClientIdNumber );
233 - throw e;
234 - }
235 - return result;
236 - }
237 -
238 - public ChannelServiceResult propagate( int pClientIdNumber, int pMessageSequenceNumber, int pPollMillisecs, ChannelServicePackage pToServer ) {
239 - try {
240 - return propagateFromChannelClientProcess( pClientIdNumber, pMessageSequenceNumber, pPollMillisecs, pToServer );
241 - }
242 - catch ( RuntimeException e ) {
243 - getLogger().error.log( e, "Problem processing Client (", pClientIdNumber, ")", pToServer );
244 - throw e;
245 - }
246 - }
247 -
248 - public void clientDead( int pClientIdNumber ) {
249 - try {
250 - clientDeadFromChannelClientProcess( pClientIdNumber );
251 - }
252 - catch ( RuntimeException e ) {
253 - getLogger().error.log( e, "Problem processing Client Dead from Client: ", pClientIdNumber );
254 - // eat it as there is no longer a client to notify!
255 - }
256 - }
257 -
258 - protected void clientDeadFromChannelClientProcess( int pClientIdNumber ) {
259 - HttpServletRequest zRequest = getThreadLocalRequest();
260 -
261 - try {
262 - ServerEventBus zSEB = ServerEventBusSessionMapper.getServerEventBus( zRequest, this, pClientIdNumber );
263 - if ( (zSEB != null) && zSEB.isAliveAndWell() ) {
264 - setThreadLocalContextFrom( zSEB );
265 - try {
266 - zSEB.publishIfNotDisposed( WindowClosingEventPackage.INSTANCE );
267 - zSEB.dispose( "ClientDead" );
268 - }
269 - finally {
270 - clrThreadLocalContext();
271 - }
272 - }
273 - }
274 - catch ( InvalidSessionException e ) {
275 - // Logged by ServerEventBusSessionMapper
276 - return;
277 - }
278 - getLogger().debug.log( "ClientDead: ", pClientIdNumber );
279 - }
280 -
281 - protected ChannelServiceResult propagateFromChannelClientProcess( int pClientIdNumber, int pMessageSequenceNumber, int pPollMillisecs,
282 - ChannelServicePackage pFromClient ) {
283 - HttpServletRequest zRequest = getThreadLocalRequest();
284 -
285 - ServerEventBus zSEB;
286 - try {
287 - zSEB = ServerEventBusSessionMapper.getServerEventBus( zRequest, this, pClientIdNumber );
288 - }
289 - catch ( InvalidSessionException e ) {
290 - // Logged by ServerEventBusSessionMapper
291 - return ChannelServiceResult.forceClose( pMessageSequenceNumber );
292 - }
293 - if ( (zSEB != null) && !zSEB.isAliveAndWell() ) {
294 - getLogger().trace.log( "ServerEventBus Disposed for pClientIdNumber=", pClientIdNumber, //
295 - " is ", zSEB, "!" );
296 - return ChannelServiceResult.forceClose( pMessageSequenceNumber );
297 - }
298 - if ( !(zSEB instanceof NonTemporaryServerEventBus) ) {
299 - getLogger().warn.log( "ServerEventBus for pClientIdNumber=", pClientIdNumber, //
300 - " is ", zSEB, "!" );
301 - return ChannelServiceResult.serverLost( pMessageSequenceNumber );
302 - }
303 - setThreadLocalContextFrom( zSEB );
304 - try {
305 - RemotePeerService zRemotePeerService = ((NonTemporaryServerEventBus) zSEB).getRemotePeerService();
306 - if ( zRemotePeerService instanceof ServerSideRemotePeerService ) {
307 - ServerSideRemotePeerService ssrps = (ServerSideRemotePeerService) zRemotePeerService;
308 - ChannelServicePackage zPackage = ssrps.processClientRequest( pPollMillisecs, pFromClient );
309 - return ChannelServiceResult.normal( pMessageSequenceNumber, zPackage );
310 - }
311 - getLogger().warn.log( "ServerEventBus for pClientIdNumber=", pClientIdNumber, //
312 - " RemotePeerService is ", zRemotePeerService, "!" );
313 - return ChannelServiceResult.serverLost( pMessageSequenceNumber );
314 - }
315 - finally {
316 - clrThreadLocalContext();
317 - }
318 - }
319 -
320 - protected AppInitializationResult initializeForBrowserPageRequest( Integer existingClientIdNumber )
321 - throws InvalidSessionException {
322 - HttpServletRequest zRequest = getThreadLocalRequest();
323 -
324 - Integer zClientIdNumber = getClientIdNumber( zRequest, existingClientIdNumber );
325 -
326 - if ( zClientIdNumber == null ) {
327 - return null; // Force Close!
328 - }
329 -
330 - getLogger().debug.log( "initialize Page Request, existing: ", //
331 - existingClientIdNumber, " -> ", zClientIdNumber );
332 -
333 - NonTemporaryServerEventBus zSEB = createRealServerEventBus( zClientIdNumber );
334 - ServerSideRemotePeerService zSPS = zSEB.initialize( "initializeForBrowserPageRequest" );
335 -
336 - ServerEventBusSessionMapper.addServerEventBus( zRequest, this, zSEB );
337 - setThreadLocalContextFrom( zSEB );
338 -
339 - try {
340 - ServerEventBusSubscriptionCollector collector = new ServerEventBusSubscriptionCollector();
341 -
342 - addEventListenersForNewClient( collector );
343 -
344 - collector.subscribe( new RequestNewClientPackageListener() );
345 - collector.subscribe( new MsgParentPackageListener() );
346 - collector.subscribe( new MsgChildrenPackageListener() );
347 - collector.subscribe( new MsgRelatedPackageListener() );
348 - collector.subscribe( new MsgAllPackageListener() );
349 - collector.subscribe( new MsgSpecificPackageListener() );
350 -
351 - zSEB.apply( collector );
352 -
353 - finalInitializationBeforeInitializationResultReturned( zSEB );
354 -
355 - return new AppInitializationResult( zClientIdNumber, //
356 - ClientIdCodec.encode( zClientIdNumber ), //
357 - mClientConfig, //
358 - zSPS.processClientRequest( 0, null ), //
359 - getApplicationVersion(), //
360 - zSEB.getAuthenticationData() );
361 - }
362 - finally {
363 - clrThreadLocalContext();
364 - }
365 - }
366 -
367 - protected NonTemporaryServerEventBus createRealServerEventBus( int pClientIdNumber ) {
368 - return new RegularServerEventBus( pClientIdNumber );
369 - }
370 -
371 - protected void finalInitializationBeforeInitializationResultReturned( ServerEventBus pSEB ) {
372 - }
373 -
374 - abstract protected String getApplicationVersion();
375 -
376 - /**
377 - * @return !null will be Client ID to use, null means it was Disposed!
378 - */
379 - private Integer getClientIdNumber( HttpServletRequest pRequest, Integer pExistingClientIdNumber )
380 - throws InvalidSessionException {
381 - if ( pExistingClientIdNumber != null ) {
382 - ServerEventBus zSEB = ServerEventBusSessionMapper.getServerEventBus( pRequest, this, pExistingClientIdNumber );
383 - if ( zSEB != null ) {
384 - return zSEB.isAliveAndWell() ? pExistingClientIdNumber : null;
385 - }
386 - }
387 - return ServerEventBusManager.getNextClientIdNumber();
388 - }
389 -
390 - protected void setClientIdNumberSequenceSource( SequenceSource pSequenceSource ) {
391 - ServerEventBusManager.setClientIdNumberSequenceSource( pSequenceSource );
392 - }
393 -
394 - abstract protected void instantiateConfiguration();
395 -
396 - abstract protected void startUpApplication();
397 -
398 - protected void initComplete() {
399 - }
400 -
401 - public void setThreadLocalContextFrom( ServerEventBus pSEB ) {
402 - }
403 -
404 - public void clrThreadLocalContext() {
405 - }
406 -
407 - abstract protected void addEventListenersForNewClient( ServerEventBusSubscriptionCollector pCollector );
408 -
409 - /**
410 - * This method controls how data is exported from the parent event bus to
411 - * the newly created child event bus. Called before a new client window is
412 - * opened. The default implementation simply returns all the browser
413 - * properties set on the parent EB.
414 - *
415 - * @param pParentEventBus the exiting parent event bus
416 - *
417 - * @return a new BrowserDataManager, or <code>null</code>
418 - */
419 - protected ClientWindowInstanceDataManager createChildWindowInstanceData( RequestNewClientEventPackage pEvent, EventBus pParentEventBus ) {
420 - return new ClientWindowInstanceDataManager( pParentEventBus.getClientWindowInstanceDataManager() );
421 - }
422 -
423 - private class RequestNewClientPackageListener implements EventPackageSubscriber {
424 - public String subscribeWith() {
425 - return RequestNewClientEventPackage.SubscribeWith;
426 - }
427 -
428 - public void packageReceivedVia( EventPackage pEventPackage, EventBus pEventBus ) {
429 - RequestNewClientEventPackage zEvent = (RequestNewClientEventPackage) pEventPackage;
430 -
431 - ClientWindowInstanceDataManager zInitialClientData;
432 -
433 - try {
434 - zInitialClientData = createChildWindowInstanceData( zEvent, pEventBus );
435 - }
436 - catch ( RuntimeException e ) {
437 - getLogger().error.log( e );
438 - pEventBus.publish( (EventPackage) null ); // todo - George: Client Error from Server!!!!
439 - return;
440 - }
441 -
442 - TemporaryServerEventBus zTempSEB = createTemporarySEB( "RequestNewClient", //
443 - (ServerEventBus) pEventBus, //
444 - zInitialClientData );
445 - int zClientIdNumber = zTempSEB.getClientIdNumber();
446 - String zNewEncodedClientId = ClientIdCodec.encode( zClientIdNumber );
447 -
448 - pEventBus.publish( new OpenNewClientEventPackage( pEventBus.getForm(), zNewEncodedClientId ) );
449 - }
450 - }
451 -
452 - protected TemporaryServerEventBus createTemporarySEB( String pWhy, ServerEventBus pParent, ClientWindowInstanceDataManager pInitialClientData ) {
453 - return ServerEventBusManager.INSTANCE.createTemporaryServerEventBus( pWhy, pParent, pInitialClientData );
454 - }
455 -
456 - protected TemporaryServerEventBus createTemporarySEB( String pWhy, HttpServletRequest pRequest, ClientWindowInstanceDataManager pInitialClientData ) {
457 - return ServerEventBusManager.INSTANCE.createTemporaryServerEventBus( pWhy, pRequest, this, pInitialClientData );
458 - }
459 -
460 - private abstract static class MsgOtherBus implements EventPackageSubscriber {
461 - public void packageReceivedVia( EventPackage pEventPackage, EventBus pEventBus ) {
462 - EventPackagePayloadEventPackage eventEventPackage = (EventPackagePayloadEventPackage) pEventPackage;
463 - ChannelEventPackage event = eventEventPackage.getEventToForward();
464 - if ( event != null ) {
465 - ServerEventBus bus = getAppropriateServerEventBus( (ServerEventBus) pEventBus, //
466 - eventEventPackage );
467 - if ( bus != null ) {
468 - bus.publishIfNotDisposed( event );
469 - }
470 - }
471 - }
472 -
473 - abstract protected ServerEventBus getAppropriateServerEventBus( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage );
474 - }
475 -
476 - private abstract static class MsgOtherBuses implements EventPackageSubscriber {
477 - public void packageReceivedVia( EventPackage pEventPackage, EventBus pEventBus ) {
478 - EventPackagePayloadEventPackage eventEventPackage = (EventPackagePayloadEventPackage) pEventPackage;
479 - ChannelEventPackage event = eventEventPackage.getEventToForward();
480 - if ( event != null ) {
481 - ServerEventBus serverEventBus = (ServerEventBus) pEventBus;
482 - ServerEventBus[] buses = getAppropriateServerEventBuses( serverEventBus, eventEventPackage );
483 - if ( buses != null ) {
484 - for ( ServerEventBus bus : buses ) {
485 - if ( (bus != null) && (bus != pEventBus) ) {
486 - bus.publishIfNotDisposed( event );
487 - }
488 - }
489 - }
490 - }
491 - }
492 -
493 - abstract protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage );
494 - }
495 -
496 - private static class MsgParentPackageListener extends MsgOtherBus {
497 - public String subscribeWith() {
498 - return MsgParentWindowEventPackage.SubscribeWith;
499 - }
500 -
501 - protected ServerEventBus getAppropriateServerEventBus( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
502 - return pEventBus.getParentServerEventBus();
503 - }
504 - }
505 -
506 - private static class MsgChildrenPackageListener extends MsgOtherBuses {
507 - public String subscribeWith() {
508 - return MsgChildWindowsEventPackage.SubscribeWith;
509 - }
510 -
511 - protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
512 - return pEventBus.getChildrenServerEventBuses();
513 - }
514 - }
515 -
516 - private static class MsgRelatedPackageListener extends MsgOtherBuses {
517 - public String subscribeWith() {
518 - return MsgRelatedWindowsEventPackage.SubscribeWith;
519 - }
520 -
521 - protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
522 - return pEventBus.getAllRelatedServerEventBuses();
523 - }
524 - }
525 -
526 - private static class MsgAllPackageListener extends MsgOtherBuses {
527 - public String subscribeWith() {
528 - return MsgAllWindowsEventPackage.SubscribeWith;
529 - }
530 -
531 - protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
532 - return pEventBus.getAllServerEventBuses();
533 - }
534 - }
535 -
536 - private static class MsgSpecificPackageListener extends MsgOtherBus {
537 - public String subscribeWith() {
538 - return MsgSpecificWindowEventPackage.SubscribeWith;
539 - }
540 -
541 - protected ServerEventBus getAppropriateServerEventBus( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
542 - int clientIdNumber = ((MsgSpecificWindowEventPackage) pEventEventPackage).getClientIdNumber();
543 - return ServerEventBusManager.INSTANCE.getServerEventBus( clientIdNumber );
544 - }
545 - }
546 -
547 - /**
548 - * The keepAliveSession accesses the GWT ThreadLocalRequest forcing it to getSession() and logging the
549 - * particulars of the session at DEBUG level.
550 - */
551 - private void keepAliveSession() {
552 - HttpServletRequest zReq = getThreadLocalRequest();
553 - HttpSession zSession = zReq.getSession();
554 - if ( zSession == null ) {
555 - getLogger().debug.log( "zSession is Null" );
556 - } else if ( zSession.isNew() ) {
557 - getLogger().debug.log( "zSession.getId()=", zSession.getId() );
558 - }
559 - }
560 -
561 - public String processCall( String payload )
562 - throws SerializationException {
563 - try {
564 - keepAliveSession();
565 - return super.processCall( payload );
566 - }
567 - catch ( SerializationException e ) {
568 - getLogger().error.log( e, "payload:", payload );
569 - throw e;
570 - }
571 - catch ( RuntimeException e ) {
572 - getLogger().error.log( e, "payload:", payload );
573 - throw e;
574 - }
575 - }
576 -
577 - protected void service( HttpServletRequest pRequest, HttpServletResponse pResponse )
578 - throws ServletException, IOException {
579 - String query = Strings.noEmpty( pRequest.getQueryString() );
580 - if ( query == null ) {
581 - super.service( pRequest, pResponse );
582 - return;
583 - }
584 - // System.out.println( "service: " + query );
585 - // System.out.println( "RequestURI: " + pHttpServletRequest.getRequestURI() );
586 - // System.out.println( "RequestURL: " + pHttpServletRequest.getRequestURL() );
587 - // System.out.println( "PathInfo: " + pHttpServletRequest.getPathInfo() );
588 - // System.out.println( "PathTranslated: " + pHttpServletRequest.getPathTranslated() );
589 - TemplateControl zTC = resolveQuery( pRequest, query );
590 - if ( zTC == null ) {
591 - throw new ServletException( "Unable to process request: " + query );
592 - }
593 - try {
594 - pResponse.setCharacterEncoding( FileUtils.UTF_8 );
595 - ServletUtils.noCache( pResponse );
596 - Writer zWriter = new OutputStreamWriter( pResponse.getOutputStream(), FileUtils.UTF_8 );
597 - try {
598 - zTC.applyTo( zWriter, "&nbsp;" );
599 - }
600 - finally {
601 - zWriter.close();
602 - }
603 - }
604 - finally {
605 - zTC.dispose();
606 - }
607 - }
608 -
609 - protected TemplateControl resolveQuery( HttpServletRequest pRequest, String pQuery )
610 - throws IOException {
611 - return null;
612 - }
613 - }
1 + // This Source Code is in the Public Domain per: http://unlicense.org
2 + package org.litesoft.GWT.eventbus.server;
3 +
4 + import org.litesoft.GWT.eventbus.client.*;
5 + import org.litesoft.GWT.eventbus.client.eventpackages.*;
6 + import org.litesoft.GWT.eventbus.client.nonpublic.*;
7 + import org.litesoft.GWT.eventbus.client.rpc.*;
8 + import org.litesoft.GWT.eventbus.server.nonpublic.*;
9 + import org.litesoft.commonfoundation.base.*;
10 + import org.litesoft.commonfoundation.typeutils.gregorian.*;
11 + import org.litesoft.configuration.*;
12 + import org.litesoft.logger.*;
13 + import org.litesoft.logger.nonpublic.*;
14 + import org.litesoft.sequences.*;
15 + import org.litesoft.ui_1_5.def.nonpublic.*;
16 + import org.litesoft.util.*;
17 + import org.litesoft.util.template.*;
18 +
19 + import com.google.gwt.user.client.rpc.*;
20 + import com.google.gwt.user.server.rpc.*;
21 +
22 + import javax.servlet.*;
23 + import javax.servlet.http.*;
24 + import java.io.*;
25 + import java.util.*;
26 +
27 + public abstract class AbstractServerApp extends RemoteServiceServlet // don't forget this!
28 + implements EventBusRemoteService, // don't forget this!
29 + ConfigLoadedListener,
30 + ThreadLocalContextFactory {
31 + public static final String HINT_CATEGORY = "Configuration";
32 +
33 + protected static final String PLUS_OVERFLOW_HIDDEN = " overflow: hidden;";
34 + protected static final String BODY_STYLE_LESS_OVERFLOW = "border: none; padding: 0; margin: 0;";
35 + protected static final String FULL_BODY_STYLE = BODY_STYLE_LESS_OVERFLOW + PLUS_OVERFLOW_HIDDEN;
36 +
37 + protected static Logger getLogger() {
38 + Configuration.chkInstantiated();
39 + return ___NEVER_EVER_TO_USE_DIRECTLY_LOGGER_____USE_GetLogger_METHOD___;
40 + }
41 +
42 + private static final Logger ___NEVER_EVER_TO_USE_DIRECTLY_LOGGER_____USE_GetLogger_METHOD___ = LoggerFactory.getLogger( AbstractServerApp.class );
43 +
44 + private static boolean sOneTimeInitComplete = false;
45 +
46 + private static RuntimeException sOneTimeInitException = null;
47 +
48 + private Map<String, String> mClientConfig = new HashMap<String, String>();
49 +
50 + public void init()
51 + throws ServletException {
52 + super.init();
53 + synchronized ( AbstractServerApp.class ) {
54 + if ( getOneTimeInitException() != null ) {
55 + throw getOneTimeInitException();
56 + }
57 + if ( !isOneTimeInitComplete() ) {
58 + oneTimeInit();
59 + }
60 + }
61 + }
62 +
63 + private static synchronized boolean isOneTimeInitComplete() {
64 + return sOneTimeInitComplete;
65 + }
66 +
67 + private static synchronized RuntimeException getOneTimeInitException() {
68 + return sOneTimeInitException;
69 + }
70 +
71 + private static synchronized void setOneTimeInitException( RuntimeException pOneTimeInitException ) {
72 + sOneTimeInitException = pOneTimeInitException;
73 + }
74 +
75 + /**
76 + * Assumption is that this method will ALWAYS be called under synchronized( AbstractServerApp.class )!
77 + */
78 + protected void oneTimeInit() {
79 + System.err.println( new UtilDateAdaptor() + " | Application Server Start Up" );
80 + Configuration.add( this );
81 + try {
82 + // todo: translate: FormQueryFilter.registerRehydrateFactories();
83 + initializeHintValidators();
84 + instantiateConfiguration();
85 + logConfigurationLoadingWarnings();
86 + getLogger().trace.log( "ClientConfig: ", mClientConfig );
87 + startUpApplication();
88 + logServletContextInitParameterNames();
89 + initComplete();
90 + System.err.println( new UtilDateAdaptor() + " | Application Server Start Up Complete" );
91 + }
92 + catch ( RuntimeException e ) {
93 + setOneTimeInitException( e );
94 + throw e;
95 + }
96 + finally {
97 + sOneTimeInitComplete = true;
98 + }
99 + }
100 +
101 + private void logServletContextInitParameterNames() {
102 + if ( getLogger().info.isEnabled() ) {
103 + Enumeration zParamNames = getServletContext().getInitParameterNames();
104 + while ( zParamNames.hasMoreElements() ) {
105 + String zParamName = (String) zParamNames.nextElement();
106 + getLogger().info.log( "Context Param " + zParamName, " value is ", getServletContext().getInitParameter( zParamName ) );
107 + }
108 + }
109 + }
110 +
111 + protected void initializeHintValidators() {
112 + CommonHintValidators.register();
113 + }
114 +
115 + protected void addClientLoggingLevel( String pName, String pEffectiveLevel ) {
116 + mClientConfig.put( LoggerLevel.CONFIGURATION_BASE + pName, pEffectiveLevel );
117 + }
118 +
119 + private void logConfigurationLoadingWarnings() {
120 + if ( !mConfigurationLoadingWarning.isEmpty() ) {
121 + AbstractLogger logger = getLogger().warn;
122 + if ( logger.isEnabled() ) {
123 + for ( String warning : mConfigurationLoadingWarning ) {
124 + logger.log( warning );
125 + }
126 + }
127 + }
128 + }
129 +
130 + private List<String> mConfigurationLoadingWarning = new ArrayList<String>();
131 +
132 + protected void addConfigurationLoadingWarning( String pWarning ) {
133 + mConfigurationLoadingWarning.add( pWarning );
134 + }
135 +
136 + public void configurationJustLoaded() {
137 + loadClientConfigPath();
138 +
139 + String[] keys = Configuration.getAllKeys();
140 + for ( String key : keys ) {
141 + if ( key.startsWith( LoggerLevel.CONFIGURATION_BASE ) ) {
142 + mClientConfig.put( key, Configuration.getString( key ) );
143 + } else if ( key.startsWith( HintController.HINT_PROPERTY_PREFIX ) ) {
144 + String zName = key.substring( HintController.HINT_PROPERTY_PREFIX.length() ).trim();
145 + if ( zName.length() == 0 ) {
146 + addConfigurationLoadingWarning( "Configuration has entry with nothing after '" + HintController.HINT_PROPERTY_PREFIX + "'" );
147 + } else {
148 + String zValue = Configuration.getString( key );
149 + String problem = HintController.validate( HINT_CATEGORY, null, zName, zValue );
150 + if ( problem != null ) {
151 + if ( problem.length() != 0 ) {
152 + throw new IllegalStateException( "Unacceptable Configuration entry '" + key + "'='" + zValue + "':" + problem );
153 + }
154 + addConfigurationLoadingWarning( HintController.noValidatorText( HINT_CATEGORY, null, zName ) );
155 + }
156 + HintController.addGlobalHint( zName, zValue );
157 + }
158 + }
159 + }
160 + }
161 +
162 + protected void loadClientConfigPath() {
163 + File dir = ServerConfiguration.configFilesSubDirectoryByKey( "ClientConfigPath", null );
164 + if ( dir != null ) {
165 + Properties prop = loadProperties( dir.getAbsolutePath() );
166 + if ( prop != null ) {
167 + for ( Object key : prop.keySet() ) {
168 + if ( key != null ) {
169 + Object value = prop.get( key );
170 + if ( value != null ) {
171 + mClientConfig.put( key.toString(), value.toString() );
172 + }
173 + }
174 + }
175 + }
176 + }
177 + }
178 +
179 + private Properties loadProperties( String pPath ) {
180 + File fileAt = new File( pPath );
181 + FileInputStream is;
182 + try {
183 + is = new FileInputStream( fileAt );
184 + }
185 + catch ( IOException e ) {
186 + getLogger().error.log( e, "Unable to open: ", fileAt.getAbsolutePath() );
187 + return null;
188 + }
189 + try {
190 + Properties props = new Properties();
191 + props.load( is );
192 + System.out.println( "Loaded Client Configuration from: " + fileAt.getAbsolutePath() );
193 + return props;
194 + }
195 + catch ( IOException e ) {
196 + getLogger().error.log( e, "Unable to load: ", fileAt.getAbsolutePath() );
197 + return null;
198 + }
199 + finally {
200 + try {
201 + is.close();
202 + }
203 + catch ( IOException e ) {
204 + // Whatever...
205 + }
206 + }
207 + }
208 +
209 + protected void loadClientConfigConfigurationLoggerLevels() {
210 + String[] keys = Configuration.getAllKeys();
211 + for ( String key : keys ) {
212 + if ( key.startsWith( LoggerLevel.CONFIGURATION_BASE ) ) {
213 + mClientConfig.put( key, Configuration.getString( key ) );
214 + }
215 + }
216 + }
217 +
218 + public synchronized AppInitializationResult initialize( String pEncodedClientId ) {
219 + Integer existingClientIdNumber;
220 + try {
221 + existingClientIdNumber = ClientIdCodec.decode( pEncodedClientId );
222 + }
223 + catch ( RuntimeException e ) {
224 + getLogger().error.log( e, "initialize '", pEncodedClientId, "'" );
225 + throw e;
226 + }
227 + AppInitializationResult result;
228 + try {
229 + result = initializeForBrowserPageRequest( existingClientIdNumber );
230 + }
231 + catch ( RuntimeException e ) {
232 + getLogger().error.log( e, "initialize: ", existingClientIdNumber );
233 + throw e;
234 + }
235 + return result;
236 + }
237 +
238 + public ChannelServiceResult propagate( int pClientIdNumber, int pMessageSequenceNumber, int pPollMillisecs, ChannelServicePackage pToServer ) {
239 + try {
240 + return propagateFromChannelClientProcess( pClientIdNumber, pMessageSequenceNumber, pPollMillisecs, pToServer );
241 + }
242 + catch ( RuntimeException e ) {
243 + getLogger().error.log( e, "Problem processing Client (", pClientIdNumber, ")", pToServer );
244 + throw e;
245 + }
246 + }
247 +
248 + public void clientDead( int pClientIdNumber ) {
249 + try {
250 + clientDeadFromChannelClientProcess( pClientIdNumber );
251 + }
252 + catch ( RuntimeException e ) {
253 + getLogger().error.log( e, "Problem processing Client Dead from Client: ", pClientIdNumber );
254 + // eat it as there is no longer a client to notify!
255 + }
256 + }
257 +
258 + protected void clientDeadFromChannelClientProcess( int pClientIdNumber ) {
259 + HttpServletRequest zRequest = getThreadLocalRequest();
260 +
261 + try {
262 + ServerEventBus zSEB = ServerEventBusSessionMapper.getServerEventBus( zRequest, this, pClientIdNumber );
263 + if ( (zSEB != null) && zSEB.isAliveAndWell() ) {
264 + setThreadLocalContextFrom( zSEB );
265 + try {
266 + zSEB.publishIfNotDisposed( WindowClosingEventPackage.INSTANCE );
267 + zSEB.dispose( "ClientDead" );
268 + }
269 + finally {
270 + clrThreadLocalContext();
271 + }
272 + }
273 + }
274 + catch ( InvalidSessionException e ) {
275 + // Logged by ServerEventBusSessionMapper
276 + return;
277 + }
278 + getLogger().debug.log( "ClientDead: ", pClientIdNumber );
279 + }
280 +
281 + protected ChannelServiceResult propagateFromChannelClientProcess( int pClientIdNumber, int pMessageSequenceNumber, int pPollMillisecs,
282 + ChannelServicePackage pFromClient ) {
283 + HttpServletRequest zRequest = getThreadLocalRequest();
284 +
285 + ServerEventBus zSEB;
286 + try {
287 + zSEB = ServerEventBusSessionMapper.getServerEventBus( zRequest, this, pClientIdNumber );
288 + }
289 + catch ( InvalidSessionException e ) {
290 + // Logged by ServerEventBusSessionMapper
291 + return ChannelServiceResult.forceClose( pMessageSequenceNumber );
292 + }
293 + if ( (zSEB != null) && !zSEB.isAliveAndWell() ) {
294 + getLogger().trace.log( "ServerEventBus Disposed for pClientIdNumber=", pClientIdNumber, //
295 + " is ", zSEB, "!" );
296 + return ChannelServiceResult.forceClose( pMessageSequenceNumber );
297 + }
298 + if ( !(zSEB instanceof NonTemporaryServerEventBus) ) {
299 + getLogger().warn.log( "ServerEventBus for pClientIdNumber=", pClientIdNumber, //
300 + " is ", zSEB, "!" );
301 + return ChannelServiceResult.serverLost( pMessageSequenceNumber );
302 + }
303 + setThreadLocalContextFrom( zSEB );
304 + try {
305 + RemotePeerService zRemotePeerService = ((NonTemporaryServerEventBus) zSEB).getRemotePeerService();
306 + if ( zRemotePeerService instanceof ServerSideRemotePeerService ) {
307 + ServerSideRemotePeerService ssrps = (ServerSideRemotePeerService) zRemotePeerService;
308 + ChannelServicePackage zPackage = ssrps.processClientRequest( pPollMillisecs, pFromClient );
309 + return ChannelServiceResult.normal( pMessageSequenceNumber, zPackage );
310 + }
311 + getLogger().warn.log( "ServerEventBus for pClientIdNumber=", pClientIdNumber, //
312 + " RemotePeerService is ", zRemotePeerService, "!" );
313 + return ChannelServiceResult.serverLost( pMessageSequenceNumber );
314 + }
315 + finally {
316 + clrThreadLocalContext();
317 + }
318 + }
319 +
320 + protected AppInitializationResult initializeForBrowserPageRequest( Integer existingClientIdNumber )
321 + throws InvalidSessionException {
322 + HttpServletRequest zRequest = getThreadLocalRequest();
323 +
324 + Integer zClientIdNumber = getClientIdNumber( zRequest, existingClientIdNumber );
325 +
326 + if ( zClientIdNumber == null ) {
327 + return null; // Force Close!
328 + }
329 +
330 + getLogger().debug.log( "initialize Page Request, existing: ", //
331 + existingClientIdNumber, " -> ", zClientIdNumber );
332 +
333 + NonTemporaryServerEventBus zSEB = createRealServerEventBus( zClientIdNumber );
334 + ServerSideRemotePeerService zSPS = zSEB.initialize( "initializeForBrowserPageRequest" );
335 +
336 + ServerEventBusSessionMapper.addServerEventBus( zRequest, this, zSEB );
337 + setThreadLocalContextFrom( zSEB );
338 +
339 + try {
340 + ServerEventBusSubscriptionCollector collector = new ServerEventBusSubscriptionCollector();
341 +
342 + addEventListenersForNewClient( collector );
343 +
344 + collector.subscribe( new RequestNewClientPackageListener() );
345 + collector.subscribe( new MsgParentPackageListener() );
346 + collector.subscribe( new MsgChildrenPackageListener() );
347 + collector.subscribe( new MsgRelatedPackageListener() );
348 + collector.subscribe( new MsgAllPackageListener() );
349 + collector.subscribe( new MsgSpecificPackageListener() );
350 +
351 + zSEB.apply( collector );
352 +
353 + finalInitializationBeforeInitializationResultReturned( zSEB );
354 +
355 + return new AppInitializationResult( zClientIdNumber, //
356 + ClientIdCodec.encode( zClientIdNumber ), //
357 + mClientConfig, //
358 + zSPS.processClientRequest( 0, null ), //
359 + getApplicationVersion(), //
360 + zSEB.getAuthenticationData() );
361 + }
362 + finally {
363 + clrThreadLocalContext();
364 + }
365 + }
366 +
367 + protected NonTemporaryServerEventBus createRealServerEventBus( int pClientIdNumber ) {
368 + return new RegularServerEventBus( pClientIdNumber );
369 + }
370 +
371 + protected void finalInitializationBeforeInitializationResultReturned( ServerEventBus pSEB ) {
372 + }
373 +
374 + abstract protected String getApplicationVersion();
375 +
376 + /**
377 + * @return !null will be Client ID to use, null means it was Disposed!
378 + */
379 + private Integer getClientIdNumber( HttpServletRequest pRequest, Integer pExistingClientIdNumber )
380 + throws InvalidSessionException {
381 + if ( pExistingClientIdNumber != null ) {
382 + ServerEventBus zSEB = ServerEventBusSessionMapper.getServerEventBus( pRequest, this, pExistingClientIdNumber );
383 + if ( zSEB != null ) {
384 + return zSEB.isAliveAndWell() ? pExistingClientIdNumber : null;
385 + }
386 + }
387 + return ServerEventBusManager.getNextClientIdNumber();
388 + }
389 +
390 + protected void setClientIdNumberSequenceSource( SequenceSource pSequenceSource ) {
391 + ServerEventBusManager.setClientIdNumberSequenceSource( pSequenceSource );
392 + }
393 +
394 + abstract protected void instantiateConfiguration();
395 +
396 + abstract protected void startUpApplication();
397 +
398 + protected void initComplete() {
399 + }
400 +
401 + public void setThreadLocalContextFrom( ServerEventBus pSEB ) {
402 + }
403 +
404 + public void clrThreadLocalContext() {
405 + }
406 +
407 + abstract protected void addEventListenersForNewClient( ServerEventBusSubscriptionCollector pCollector );
408 +
409 + /**
410 + * This method controls how data is exported from the parent event bus to
411 + * the newly created child event bus. Called before a new client window is
412 + * opened. The default implementation simply returns all the browser
413 + * properties set on the parent EB.
414 + *
415 + * @param pParentEventBus the exiting parent event bus
416 + *
417 + * @return a new BrowserDataManager, or <code>null</code>
418 + */
419 + protected ClientWindowInstanceDataManager createChildWindowInstanceData( RequestNewClientEventPackage pEvent, EventBus pParentEventBus ) {
420 + return new ClientWindowInstanceDataManager( pParentEventBus.getClientWindowInstanceDataManager() );
421 + }
422 +
423 + private class RequestNewClientPackageListener implements EventPackageSubscriber {
424 + public String subscribeWith() {
425 + return RequestNewClientEventPackage.SubscribeWith;
426 + }
427 +
428 + public void packageReceivedVia( EventPackage pEventPackage, EventBus pEventBus ) {
429 + RequestNewClientEventPackage zEvent = (RequestNewClientEventPackage) pEventPackage;
430 +
431 + ClientWindowInstanceDataManager zInitialClientData;
432 +
433 + try {
434 + zInitialClientData = createChildWindowInstanceData( zEvent, pEventBus );
435 + }
436 + catch ( RuntimeException e ) {
437 + getLogger().error.log( e );
438 + pEventBus.publish( (EventPackage) null ); // todo - George: Client Error from Server!!!!
439 + return;
440 + }
441 +
442 + TemporaryServerEventBus zTempSEB = createTemporarySEB( "RequestNewClient", //
443 + (ServerEventBus) pEventBus, //
444 + zInitialClientData );
445 + int zClientIdNumber = zTempSEB.getClientIdNumber();
446 + String zNewEncodedClientId = ClientIdCodec.encode( zClientIdNumber );
447 +
448 + pEventBus.publish( new OpenNewClientEventPackage( pEventBus.getForm(), zNewEncodedClientId ) );
449 + }
450 + }
451 +
452 + protected TemporaryServerEventBus createTemporarySEB( String pWhy, ServerEventBus pParent, ClientWindowInstanceDataManager pInitialClientData ) {
453 + return ServerEventBusManager.INSTANCE.createTemporaryServerEventBus( pWhy, pParent, pInitialClientData );
454 + }
455 +
456 + protected TemporaryServerEventBus createTemporarySEB( String pWhy, HttpServletRequest pRequest, ClientWindowInstanceDataManager pInitialClientData ) {
457 + return ServerEventBusManager.INSTANCE.createTemporaryServerEventBus( pWhy, pRequest, this, pInitialClientData );
458 + }
459 +
460 + private abstract static class MsgOtherBus implements EventPackageSubscriber {
461 + public void packageReceivedVia( EventPackage pEventPackage, EventBus pEventBus ) {
462 + EventPackagePayloadEventPackage eventEventPackage = (EventPackagePayloadEventPackage) pEventPackage;
463 + ChannelEventPackage event = eventEventPackage.getEventToForward();
464 + if ( event != null ) {
465 + ServerEventBus bus = getAppropriateServerEventBus( (ServerEventBus) pEventBus, //
466 + eventEventPackage );
467 + if ( bus != null ) {
468 + bus.publishIfNotDisposed( event );
469 + }
470 + }
471 + }
472 +
473 + abstract protected ServerEventBus getAppropriateServerEventBus( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage );
474 + }
475 +
476 + private abstract static class MsgOtherBuses implements EventPackageSubscriber {
477 + public void packageReceivedVia( EventPackage pEventPackage, EventBus pEventBus ) {
478 + EventPackagePayloadEventPackage eventEventPackage = (EventPackagePayloadEventPackage) pEventPackage;
479 + ChannelEventPackage event = eventEventPackage.getEventToForward();
480 + if ( event != null ) {
481 + ServerEventBus serverEventBus = (ServerEventBus) pEventBus;
482 + ServerEventBus[] buses = getAppropriateServerEventBuses( serverEventBus, eventEventPackage );
483 + if ( buses != null ) {
484 + for ( ServerEventBus bus : buses ) {
485 + if ( (bus != null) && (bus != pEventBus) ) {
486 + bus.publishIfNotDisposed( event );
487 + }
488 + }
489 + }
490 + }
491 + }
492 +
493 + abstract protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage );
494 + }
495 +
496 + private static class MsgParentPackageListener extends MsgOtherBus {
497 + public String subscribeWith() {
498 + return MsgParentWindowEventPackage.SubscribeWith;
499 + }
500 +
501 + protected ServerEventBus getAppropriateServerEventBus( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
502 + return pEventBus.getParentServerEventBus();
503 + }
504 + }
505 +
506 + private static class MsgChildrenPackageListener extends MsgOtherBuses {
507 + public String subscribeWith() {
508 + return MsgChildWindowsEventPackage.SubscribeWith;
509 + }
510 +
511 + protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
512 + return pEventBus.getChildrenServerEventBuses();
513 + }
514 + }
515 +
516 + private static class MsgRelatedPackageListener extends MsgOtherBuses {
517 + public String subscribeWith() {
518 + return MsgRelatedWindowsEventPackage.SubscribeWith;
519 + }
520 +
521 + protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
522 + return pEventBus.getAllRelatedServerEventBuses();
523 + }
524 + }
525 +
526 + private static class MsgAllPackageListener extends MsgOtherBuses {
527 + public String subscribeWith() {
528 + return MsgAllWindowsEventPackage.SubscribeWith;
529 + }
530 +
531 + protected ServerEventBus[] getAppropriateServerEventBuses( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
532 + return pEventBus.getAllServerEventBuses();
533 + }
534 + }
535 +
536 + private static class MsgSpecificPackageListener extends MsgOtherBus {
537 + public String subscribeWith() {
538 + return MsgSpecificWindowEventPackage.SubscribeWith;
539 + }
540 +
541 + protected ServerEventBus getAppropriateServerEventBus( ServerEventBus pEventBus, EventPackagePayloadEventPackage pEventEventPackage ) {
542 + int clientIdNumber = ((MsgSpecificWindowEventPackage) pEventEventPackage).getClientIdNumber();
543 + return ServerEventBusManager.INSTANCE.getServerEventBus( clientIdNumber );
544 + }
545 + }
546 +
547 + /**
548 + * The keepAliveSession accesses the GWT ThreadLocalRequest forcing it to getSession() and logging the
549 + * particulars of the session at DEBUG level.
550 + */
551 + private void keepAliveSession() {
552 + HttpServletRequest zReq = getThreadLocalRequest();
553 + HttpSession zSession = zReq.getSession();
554 + if ( zSession == null ) {
555 + getLogger().debug.log( "zSession is Null" );
556 + } else if ( zSession.isNew() ) {
557 + getLogger().debug.log( "zSession.getId()=", zSession.getId() );
558 + }
559 + }
560 +
561 + public String processCall( String payload )
562 + throws SerializationException {
563 + try {
564 + keepAliveSession();
565 + return super.processCall( payload );
566 + }
567 + catch ( SerializationException e ) {
568 + getLogger().error.log( e, "payload:", payload );
569 + throw e;
570 + }
571 + catch ( RuntimeException e ) {
572 + getLogger().error.log( e, "payload:", payload );
573 + throw e;
574 + }
575 + }
576 +
577 + protected void service( HttpServletRequest pRequest, HttpServletResponse pResponse )
578 + throws ServletException, IOException {
579 + String query = ConstrainTo.significantOrNull( pRequest.getQueryString() );
580 + if ( query == null ) {
581 + super.service( pRequest, pResponse );
582 + return;
583 + }
584 + // System.out.println( "service: " + query );
585 + // System.out.println( "RequestURI: " + pHttpServletRequest.getRequestURI() );
586 + // System.out.println( "RequestURL: " + pHttpServletRequest.getRequestURL() );
587 + // System.out.println( "PathInfo: " + pHttpServletRequest.getPathInfo() );
588 + // System.out.println( "PathTranslated: " + pHttpServletRequest.getPathTranslated() );
589 + TemplateControl zTC = resolveQuery( pRequest, query );
590 + if ( zTC == null ) {
591 + throw new ServletException( "Unable to process request: " + query );
592 + }
593 + try {
594 + pResponse.setCharacterEncoding( FileUtils.UTF_8 );
595 + ServletUtils.noCache( pResponse );
596 + Writer zWriter = new OutputStreamWriter( pResponse.getOutputStream(), FileUtils.UTF_8 );
597 + try {
598 + zTC.applyTo( zWriter, "&nbsp;" );
599 + }
600 + finally {
601 + zWriter.close();
602 + }
603 + }
604 + finally {
605 + zTC.dispose();
606 + }
607 + }
608 +
609 + protected TemplateControl resolveQuery( HttpServletRequest pRequest, String pQuery )
610 + throws IOException {
611 + return null;
612 + }
613 + }