Package muntjac :: Package terminal :: Package gwt :: Package server :: Module abstract_web_application_context
[hide private]
[frames] | no frames]

Source Code for Module muntjac.terminal.gwt.server.abstract_web_application_context

  1  # Copyright (C) 2012 Vaadin Ltd.  
  2  # Copyright (C) 2012 Richard Lincoln 
  3  #  
  4  # Licensed under the Apache License, Version 2.0 (the "License");  
  5  # you may not use this file except in compliance with the License.  
  6  # You may obtain a copy of the License at  
  7  #  
  8  #     http://www.apache.org/licenses/LICENSE-2.0  
  9  #  
 10  # Unless required by applicable law or agreed to in writing, software  
 11  # distributed under the License is distributed on an "AS IS" BASIS,  
 12  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
 13  # See the License for the specific language governing permissions and  
 14  # limitations under the License. 
 15   
 16  """Defines a base class for web application contexts that handles the common 
 17  tasks.""" 
 18   
 19  import logging 
 20  import urllib 
 21   
 22  from muntjac.service.application_context import IApplicationContext 
 23  from muntjac.terminal.gwt.server.web_browser import WebBrowser 
 24   
 25   
 26  logger = logging.getLogger(__name__) 
 27   
 28   
29 -class AbstractWebApplicationContext(IApplicationContext):
30 """Base class for web application contexts that handles the common tasks. 31 """ 32
33 - def __init__(self):
34 self.listeners = list() 35 self.applications = set() 36 self.browser = WebBrowser() 37 self.applicationToAjaxAppMgrMap = dict()
38 39
40 - def addTransactionListener(self, listener):
41 if listener is not None: 42 self.listeners.append(listener)
43 44
45 - def removeTransactionListener(self, listener):
46 self.listeners.remove(listener)
47 48
49 - def startTransaction(self, application, request):
50 """Sends a notification that a transaction is starting. 51 52 @param application: 53 The application associated with the transaction. 54 @param request: 55 the HTTP request that triggered the transaction. 56 """ 57 for listener in self.listeners: 58 listener.transactionStart(application, request)
59 60
61 - def endTransaction(self, application, request):
62 """Sends a notification that a transaction has ended. 63 64 @param application: 65 The application associated with the transaction. 66 @param request: 67 the HTTP request that triggered the transaction. 68 """ 69 exceptions = None 70 for listener in self.listeners: 71 try: 72 listener.transactionEnd(application, request) 73 except RuntimeError, t: 74 if exceptions is None: 75 exceptions = list() 76 exceptions.append(t) 77 78 # If any runtime exceptions occurred, throw a combined exception 79 if exceptions is not None: 80 msg = str() 81 for e in exceptions: 82 if len(msg) == 0: 83 msg += '\n\n--------------------------\n\n' 84 msg += str(e) + '\n' 85 raise RuntimeError(msg)
86 87
88 - def valueBound(self, arg0):
89 """@see: L{HttpSessionBindingListener.valueBound}""" 90 pass # We are not interested in bindings
91 92
93 - def valueUnbound(self, event):
94 """@see: L{HttpSessionBindingListener.valueUnbound}""" 95 # If we are going to be unbound from the session, the session 96 # must be closing. 97 try: 98 for app in self.applications: 99 app.close() 100 self.removeApplication(app) 101 except Exception: 102 # This should never happen but is possible with rare 103 # configurations (e.g. robustness tests). If you have one 104 # thread doing HTTP socket write and another thread trying to 105 # remove same application here. Possible if you got e.g. session 106 # lifetime 1 min but socket write may take longer than 1 min. 107 # FIXME: Handle exception 108 logger.critical('Could not remove application, leaking memory.')
109 110
111 - def getBrowser(self):
112 """Get the web browser associated with this application context. 113 114 Because application context is related to the http session and server 115 maintains one session per browser-instance, each context has exactly 116 one web browser associated with it. 117 """ 118 return self.browser
119 120
121 - def getApplications(self):
122 return self.applications
123 124
125 - def removeApplication(self, application):
126 self.applications.remove(application) 127 if application in self.applicationToAjaxAppMgrMap: 128 del self.applicationToAjaxAppMgrMap[application]
129 130
131 - def generateApplicationResourceURL(self, resource, mapKey):
132 filename = resource.getFilename() 133 if filename is None: 134 return 'app://APP/' + mapKey + '/' 135 else: 136 # In case serlet container refuses requests containing 137 # encoded slashes or backslashes in URLs. Application resource URLs 138 # should really be passed in another way than as part of the path 139 # in the future. 140 encodedFileName = self.urlEncode(filename) 141 return "app://APP/" + mapKey + "/" + encodedFileName
142 143
144 - def urlEncode(self, filename):
145 return urllib.quote(filename, safe='/\\')
146 147
148 - def isApplicationResourceURL(self, context, relativeUri):
149 # If the relative uri is null, we are ready 150 if relativeUri is None: 151 return False 152 153 # Resolves the prefix 154 prefix = relativeUri 155 index = relativeUri.find('/') 156 if index >= 0: 157 prefix = relativeUri[:index] 158 159 # Handles the resource requests 160 return prefix == 'APP'
161 162
163 - def getURLKey(self, context, relativeUri):
164 index = relativeUri.find('/') 165 nxt = relativeUri.find('/', index + 1) 166 if nxt < 0: 167 return None 168 169 return relativeUri[index + 1:nxt]
170