DCL 3.7.4
Loading...
Searching...
No Matches
EShopServlet.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4#include <windows.h>
5#endif
6
7#include <dcl/Charset.h>
8#include <dcl/Files.h>
9#include <dcl/IniFile.h>
10
11//#include <dcl/net/HttpCollection.h>
12#include <dcl/Html.h>
13
14#include "EShopServlet.h"
15#include "EShopSession.h"
16#include "VisitorBook.h"
17
18#if __DCL_HAVE_THIS_FILE__
19#undef __THIS_FILE__
20static const char_t __THIS_FILE__[] = __T("dcl/eshop/EShopServlet.cpp");
21#endif
22
23__DCL_BEGIN_NAMESPACE
24
25HTTP_SERVLET_INSTANCE(EShopServlet, L"온라인 쇼핑몰")
26
28
29EShopServlet::EShopServlet()
30{
31 __pSQLConnPool = NULL;
32 __pHead = NULL;
33 __pFoot = NULL;
34 __pViewOrder = NULL;
35 __pViewProduct = NULL;
36 __pViewShoppingBasket = NULL;
37}
38
40{
41 HttpServlet::onInitialize(); // 항상 true
42
43#ifdef __WINNT__
44#define INI_FILENAME L"HSAEShop_w.ini"
45#else
46#define INI_FILENAME L"HSAEShop.ini"
47#endif
48
49 String strIniFile = getIniFileName(INI_FILENAME);
50 if (strIniFile.isEmpty()) {
51 __DCL_TRACE1(L"not found : %ls\n", strIniFile.data());
52 return;
53 }
54
55 String strSQLDriverName;
56 String strSQLConnectionString;
57
58 try {
59 IniFile ini(strIniFile);
60
61#ifdef __DCL_DEBUG
62 String strEnableDebugOut = ini.getString(L"DEBUG", L"ENABLE_DEBUG_OUT");
63 if (strEnableDebugOut.compareNoCase(L"FALSE") == 0)
64 HttpServletEx::__enableDebugOut = false;
65#endif
66
67 strSQLDriverName = ini.getString(L"DATABASE", L"DRIVER");
68 strSQLConnectionString = ini.getString(L"DATABASE", L"CONNECT");
69
70 __DCL_TRACE3(L"%ls, %ls, %ls\n",
71 strIniFile.data(),
72 strSQLDriverName.data(),
73 strSQLConnectionString.data()
74 );
75
76 __strTemplateDir = ini.getString(L"HTML_TEMPLATE", L"DIR");
77
78 __pSQLConnPool = new SQLConnectionPool(
79 strSQLConnectionString,
80 strSQLDriverName
81 );
82
83 __pHead = new TextTemplate(readTemplate(L"header.html"));
84 __pFoot = new TextTemplate(readTemplate(L"footer.html"));
85 __pViewProduct = new TextTemplate(readTemplate(L"view_product.html"));
86 __pViewShoppingBasket = new TextTemplate(readTemplate(L"view_shopping_basket.html"));
87 __pViewOrder = new TextTemplate(readTemplate(L"view_order.html"));
88 }
89 catch (Exception* e) {
90 __DCL_TRACE1(L"Init Failed %ls\n", e->toStringAll().data());
91 e->destroy();
92
93 onCleanup();
94 }
95}
96
98{
99 if (__pSQLConnPool) {
100 delete __pSQLConnPool;
101 __pSQLConnPool = NULL;
102 }
103
104 if (__pHead) {
105 delete __pHead;
106 __pHead = NULL;
107 }
108
109 if (__pFoot) {
110 delete __pFoot;
111 __pFoot = NULL;
112 }
113
114 if (__pViewOrder) {
115 delete __pViewOrder;
116 __pViewOrder = NULL;
117 }
118
119 if (__pViewProduct) {
120 delete __pViewProduct;
121 __pViewProduct = NULL;
122 }
123
124 if (__pViewShoppingBasket) {
125 delete __pViewShoppingBasket;
126 __pViewShoppingBasket = NULL;
127 }
128
130 __DCL_TRACE0(L"onCleanup()\n");
131}
132
134{
135 if (!(ctx.methodNo() == HTTP_METHOD_GET
136 || ctx.methodNo() == HTTP_METHOD_POST)
137 ) {
138 // GET나 POST 아니면
139 ctx.setStatusCode(HTTP_STATUS_METHOD_NOT_ALLOWED);
140 return;
141 }
142
143 __DCL_ASSERT(__pSQLConnPool != NULL);
144 __DCL_ASSERT(__pHead != NULL);
145 __DCL_ASSERT(__pFoot != NULL);
146 __DCL_ASSERT(__pViewProduct != NULL);
147
148 SQLConnection* pSQLConn = __pSQLConnPool->getConnection();
149 if (!pSQLConn) {
150 printError(ctx, L"데이터베이스 서버에 연결할 수 없습니다.");
151 return;
152 }
153
154 try {
155 if (pSQLConn->canTransact()) {
156 pSQLConn->startTrans();
157 }
158
159 Writer& out = ctx.writer();
160 EShopSession session(ctx, pSQLConn);
161 switch(session.command()) {
162 case CM_LOGIN: {
163 if (session.login(ctx.__formMap))
165 else
167 break;
168 }
169 case CM_LOGOUT: {
170 session.logout();
171 session.setCommand(CM_ABOUT);
172 }
173 }
174
175 // 복사본을 만들어 템플릿의 메크로들을 완성한다.
176
177 printPageHeader(out, session);
178
179 switch(session.command()) {
180 case CM_VIEW_PRODUCT: {
181 onViewProduct(ctx, session);
182 break;
183 }
184 case CM_VIEW_LOGIN_FORM: {
185 printLoginForm(out);
186 break;
187 }
189 onViewShoppingBasket(ctx, session);
190 break;
191 }
192 case CM_ORDER :
193 case CM_VIEW_ORDER: {
194 onViewOrder(ctx, session);
195 break;
196 }
197 case CM_VIEW_QNA: {
198 VisitorBook vb(
201 L"vcm",
202 *this);
203 if (!vb.onVisitorBook(ctx, out, pSQLConn)) {
204 printFile(out, L"notfound.html");
205 }
206 break;
207 }
208 case CM_SALES_REPORT: {
209 if (session.isAdmin())
210 onViewSalesReport(ctx, session);
211 else
212 printLoginForm(out);
213 break;
214 }
216 session.onViewSessions(
217 ctx.__queryMap,
218 out,
221 L"vses",
222 *this
223 );
224 break;
225 }
226 case CM_ABOUT: {
227 printFile(out, L"about.html");
228 break;
229 }
230 default: {
231 printFile(out, L"notfound.html");
232 }
233 }
234
235 if (pSQLConn->inTransaction()) {
236 pSQLConn->commitTrans();
237 }
238 __pSQLConnPool->release(pSQLConn);
239 pSQLConn = NULL;
240
241 TextTemplate tplFooter = *__pFoot;
242 out << tplFooter;
243
244 ctx.setContentType(L"text/html");
245 ctx.setStatusCode(HTTP_STATUS_OK); // HTTP_OK
246 }
247 catch (Exception* _e) {
248 if (pSQLConn) {
249 if (pSQLConn->inTransaction()) {
250 pSQLConn->rollbackTrans();
251 }
252 __pSQLConnPool->release(pSQLConn);
253 }
254 throw _e;
255 }
256}
257
258void EShopServlet::printError(HttpServletContextEx& ctx, const String str)
259{
260 Writer& out = ctx.writer();
261 out << L""
262 "<!DOCTYPE html>\n"
263 "<html lang=\"ko-KR\">\n"
264 "<head>\n"
265 "<meta charset=\"UTF-8\">\n"
266 "<title>에러!</title>\n"
267 "</head>\n"
268 "<body>\n"
269 "<h3>에러가 발생하여 요청을 완료할 수 없습니다.</h3>\n"
270 "<hr>\n<p>"
271 << Html::format(str, 4, L"<p>", L"</p>\n")
272 << L"</p>\n"
273 << L"</body>\n</html>\n";
274
275 ctx.setContentType(L"text/html", L"utf-8");
276 ctx.setStatusCode(HTTP_STATUS_OK); // HTTP_OK
277}
278
279void EShopServlet::printLoginForm(
280 Writer& out
281)
282{
283 TextTemplate tpl(readTemplate(L"login_form.html"));
284 String strHREF = String::format(L"?%ls=%d", COMMAND_STR, CM_LOGIN);
285 tpl.assign(L"HREF_LOGIN_ACTION", strHREF);
286
287 out << tpl;
288}
289
291{
294 const wchar_t* psz;
295};
296
297static MAIN_MENU menus[] =
298{
299 { false, CM_VIEW_PRODUCT, L"상품정보" },
300 { false, CM_VIEW_SHOPPING_BASKET, L"장바구니" },
301 { false, CM_VIEW_ORDER, L"주문정보" },
302 { false, CM_VIEW_QNA, L"Q&A" },
303 { true, CM_PRODUCT_MANAGEMENT, L"상품관리" },
304 { true, CM_SALES_REPORT, L"매출현황" },
305 { true, CM_SESSION_MANAGEMENT, L"세션관리" },
306 { false, CM_ABOUT, L"About" },
307// { false, CM_VIEW_LOGIN_FORM, L"로그인" }
308};
309
310void EShopServlet::printPageHeader(
311 Writer& out,
312 const EShopSession& session
313)
314{
315 TextTemplate tplHeader = *__pHead;
316
317 if (!session.isGuest()) {
318 StringBuilder str = L"<strong>" + session.userName();
319 if (session.isAdmin()) {
320 str += L"<span style=\"color:red\">";
321 str += L"(관리자 권한)</span>";
322 }
323 str += L"</strong> 님 로그인 하셨습니다";
324 tplHeader.assign(L"USER_HELLO", str);
325 }
326 else
327 tplHeader.assign(L"USER_HELLO", L"&nbsp");
328
329 // main menu
330 String strTitle;
331 for(unsigned int i = 0; i < (sizeof(menus) / sizeof(MAIN_MENU)); i++) {
332 if (menus[i].bAdminOnly) {
333 if (!session.isAdmin())
334 continue;
335 }
336
337 if (i) {
338 tplHeader.append(L"HREF", L"<span style=\"color: red\"> | </span>");
339 }
340
341 if (menus[i].nCmd == session.command()) {
342 StringBuilder strHREF = L"<span style=\"color:blue\">";
343 strHREF += menus[i].psz;
344 strHREF += L"</span>\n";
345
346 tplHeader.append(L"HREF", strHREF);
347 strTitle = menus[i].psz;
348 }
349 else {
350 String strHREF = String::format(L"<a class=\"menu\" href=\"?%ls=%d\">%ls</a>\n",
351 COMMAND_STR, menus[i].nCmd, menus[i].psz);
352 tplHeader.append(L"HREF", strHREF);
353 }
354 }
355
356 tplHeader.append(L"HREF", L"<span style=\"color: red\"> | </span>");
357
358 if (session.isGuest()) {
359 if (session.command() == CM_VIEW_LOGIN_FORM) {
360 StringBuilder strHREF = L"<span style=\"color:blue\">";
361 strHREF += L"로그인";
362 strHREF += L"</span>\n";
363 tplHeader.append(L"HREF", strHREF);
364 strTitle = L"로그인";
365 }
366 else {
367 String strHREF = String::format(L"<a class=\"menu\" href=\"?%ls=%d\">%ls</a>\n",
368 COMMAND_STR, CM_VIEW_LOGIN_FORM, L"로그인");
369 tplHeader.append(L"HREF", strHREF);
370 }
371 }
372 else {
373 String strHREF = String::format(L"<a class=\"menu\" href=\"?%ls=%d\">%ls</a>",
374 COMMAND_STR, CM_LOGOUT, L"로그아웃");
375 tplHeader.append(L"HREF", strHREF);
376 }
377
378 if (strTitle.isEmpty())
379 tplHeader.erase(L"TITLE");
380 else
381 tplHeader.assign(L"TITLE", strTitle);
382
383 out << tplHeader;
384}
385
386void EShopServlet::printFile(
387 Writer& out,
388 const wchar_t* _filename
389)
390{
391 out << readTemplate(_filename);
392}
393
394String EShopServlet::readTemplate(const wchar_t* _filename) const
396{
397 String path = __strTemplateDir;
398 if (!path.endsWith(L"/")) {
399 path = path + L"/";
400 }
401 path = path + _filename;
402
403 __DCL_TRACE1(L"readTemplate [%ls]\n", path.data());
404
405 UTF8Decoder dec;
406 return Files::readText(path, dec);
407}
408
409__DCL_END_NAMESPACE
410
411#ifdef __WINNT_NEW_DELETE_OVERRIDE
412#undef new
413__WINNT_NEW_DELETE_OVERRIDE
414#endif
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
#define INI_FILENAME
#define COMMAND_STR
COMMAND_ID
@ CM_VIEW_SHOPPING_BASKET
@ CM_VIEW_PRODUCT
@ CM_ABOUT
@ CM_SESSION_MANAGEMENT
@ CM_LOGIN
@ CM_ORDER
@ CM_VIEW_ORDER
@ CM_PRODUCT_MANAGEMENT
@ CM_VIEW_QNA
@ CM_LOGOUT
@ CM_VIEW_LOGIN_FORM
@ CM_SALES_REPORT
@ HTTP_METHOD_POST
@ HTTP_METHOD_GET
@ HTTP_STATUS_METHOD_NOT_ALLOWED
@ HTTP_STATUS_OK
#define HTTP_SERVLET_INSTANCE(ServletClass, Description)
#define __DCL_TRACE0(psz)
Definition Object.h:398
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
Definition Object.h:401
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
virtual void onInitialize() __DCL_THROWS1(Exception *)
virtual void onCleanup() __DCL_THROWS1(Exception *)
String readTemplate(const wchar_t *filename) const __DCL_THROWS1(IOException *)
virtual void onService(HttpServletContextEx &ctx) __DCL_THROWS1(Exception *)
const String & userName() const
bool login(ListedStringToStringArrayMap &params)
void onViewSessions(ListedStringToStringArrayMap &params, Writer &out, const String &strMainCommand, int nMainCommandID, const String &strCommandID, const EShopServlet &_servlet)
void setCommand(int nCM)
bool isGuest() const
bool isAdmin() const
int command() const
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
static String readText(const String &_filename) __DCL_THROWS1(IOException *)
Definition Files.cpp:435
static String format(const String &_str, int _tab2Space, const String &_beginOfLine, const String &_endOfLine)
Definition Html.cpp:122
StringWriter & writer()
virtual void onInitialize() __DCL_THROWS1(Exception *)
virtual void onCleanup() __DCL_THROWS1(Exception *)
bool canTransact() const
void rollbackTrans() __DCL_THROWS1(SQLException *)
bool inTransaction() const
void commitTrans() __DCL_THROWS1(SQLException *)
void startTrans() __DCL_THROWS1(SQLException *)
bool onVisitorBook(HttpServletContextEx &ctx, Writer &out, SQLConnection *pSQLConn)
const wchar_t * psz
COMMAND_ID nCmd