1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
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
91
92
93 - def valueUnbound(self, event):
94 """@see: L{HttpSessionBindingListener.valueUnbound}"""
95
96
97 try:
98 for app in self.applications:
99 app.close()
100 self.removeApplication(app)
101 except Exception:
102
103
104
105
106
107
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
137
138
139
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
150 if relativeUri is None:
151 return False
152
153
154 prefix = relativeUri
155 index = relativeUri.find('/')
156 if index >= 0:
157 prefix = relativeUri[:index]
158
159
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