001: package poker.business;
002:
003: import java.util.Vector;
004: import java.sql.SQLException;
005: import poker.data.DODS_GameData.*;
006: import poker.data.DODS_Fortune.*;
007: import com.lutris.appserver.server.sql.*;
008: import com.lutris.appserver.server.Enhydra;
009: import com.lutris.logging.Logger;
010: import com.lutris.util.*; //import dods.builder.sourceGenerators.Query.*;
011: import com.lutris.dods.builder.generator.query.*;
012: import poker.spec.*;
013:
014: /**
015: *
016: * EnhyDraw!, beta 4, 5/21/99
017: *
018: * Copyright 1999, Larry Wolcot & Daryl Tempesta
019: * ALL rights reserved. Not for commercial use
020: * without written permission from both authors.
021: *
022: * This is the GameList object that does all of the database dirtywork.
023: * The GameManager class started off just using a Vector to keep a list
024: * of all active PokerGame classes. It's not the most direct way of doing
025: * things, but by far the easiest way to illustrate how the DODS Objects
026: * can easily be used within a standard application.
027: *
028: * In the GameManager, I just changed the gameList to extend this object
029: * instead of a Vector. Now, we can simply divert some of the Vector's
030: * methods and use it more like a standard database adapter. Otherwise,
031: * if the useDB flag is set to false, we can just do a pass-through to
032: * the Super Object (Vector).
033: */
034: public class GameList extends Vector implements java.io.Serializable {
035:
036: private boolean useDB = false;
037:
038: /**
039: * Public Constructor
040: */
041: public GameList(int n) {
042: super (n);
043: }
044:
045: /**
046: * Private Constructor used by getCopy() method
047: */
048: private GameList() {
049: super (0);
050: }
051:
052: /**
053: * This method returns a copy of the gameList object.
054: */
055: protected GameList getCopy() {
056: GameList newCopy = new GameList();
057: newCopy = this ;
058: return newCopy;
059: }
060:
061: /**
062: * Here is where we determine how to store our data.. db or memory.
063: */
064: public void setUseDB(boolean useDB) throws Exception {
065: try {
066: this .useDB = useDB;
067: } catch (Exception e) {
068: throw e;
069: }
070: }
071:
072: /**
073: * Send to the Vector() or the DB depending on the useDB flag
074: * This is where we hook into the DODS_GameData Object
075: */
076: public synchronized void addGame(PokerGame this Game) {
077: if (useDB == false) {
078: super .addElement(this Game);
079: } else {
080: try {
081: addGameToDB(this Game);
082: } catch (Exception e) {
083: //There was a problem adding the game! bummer..
084: }
085: }
086: }
087:
088: /**
089: * This is a private method that maps the PokerGame to
090: * a GameDataDO Object so it can be inserted into the database.
091: */
092: public synchronized void addGameToDB(PokerGame newGame)
093: throws Exception {
094: //remap the PokerGame Object into a GameDataDO built by DODS.
095: GameDataDO nullDO = null;
096: GameDataDO newGameDataDO = mapToDO(nullDO, newGame);
097:
098: try {
099: DBTransaction db = Enhydra.getDatabaseManager()
100: .createTransaction();
101:
102: try {
103:
104: //Insert the newly mapped object into the DB
105: db.insert(newGameDataDO);
106: db.commit();
107: } catch (SQLException se) {
108:
109: //Something went wrong, so roll it back and pass it on!
110: db.rollback();
111: throw se;
112: } finally {
113:
114: //This releases all resources allocated in last trans
115: db.release();
116: }
117: } catch (Exception e) {
118: throw e;
119: }
120: }
121:
122: /**
123: * This private method takes a PokerGame object and maps it
124: * into a DODS GameDataDO object. Ideally, they would be the same
125: * but this is used to illustrate adding a DODS objects to
126: * a completed application.
127: * Hopefully, Jay will finish the "fake persistance" sooner
128: * or later, then this will look archaic.
129: */
130: private synchronized GameDataDO mapToDO(GameDataDO newGameDataDO,
131: PokerGame newGame) {
132: try {
133: newGameDataDO = GameDataDO.createVirgin();
134: newGameDataDO.setName(newGame.getName());
135: newGameDataDO.setPassword(newGame.getPassword());
136: newGameDataDO.setEmail(newGame.getEmail());
137: newGameDataDO.setCash(newGame.getCash());
138: newGameDataDO.setLargestBet(newGame.getLargestBet());
139: newGameDataDO.setSmallestBet(newGame.getSmallestBet());
140: newGameDataDO.setTotalPlayed(newGame.getTotalPlayed());
141: newGameDataDO.setTotalWon(newGame.getTotalWon());
142: newGameDataDO.setDeck(newGame.getDeck());
143: } catch (Exception e) {
144: System.out.print(e.getMessage());
145: e.printStackTrace();
146: //This is a DODS sourceGenetaror exception
147: }
148: return newGameDataDO;
149: }
150:
151: /**
152: * This private method takes a GameDataDO object and maps it
153: * into a PokerGame object. Ideally, they would be the same
154: * but this is used to illustrate adding a DODS objects to
155: * a completed application. Ditto from the method above
156: */
157: private synchronized PokerGame mapNewPokerGame(GameDataDO this Game) {
158: PokerGameImpl newPokerGame = new PokerGameImpl("", "", "", 0);
159:
160: try {
161: newPokerGame.setName(this Game.getName());
162: newPokerGame.setPassword(this Game.getPassword());
163: newPokerGame.setEmail(this Game.getEmail());
164: newPokerGame.setCash(this Game.getCash());
165: newPokerGame.setLargestBet(this Game.getLargestBet());
166: newPokerGame.setSmallestBet(this Game.getSmallestBet());
167: newPokerGame.setTotalPlayed(this Game.getTotalPlayed());
168: newPokerGame.setTotalWon(this Game.getTotalWon());
169: newPokerGame.setDeck(this Game.getDeck());
170: newPokerGame.setID(this Game.getOId().toString());
171: } catch (Exception e) {
172: //There really shouldn't be an exception
173: }
174: return newPokerGame;
175: }
176:
177: /**
178: * This method detremines the storage medium, then dishes
179: * the removeGame call out to the proper method
180: */
181: public synchronized void removeGame(String this Name) {
182: if (this .useDB) {
183: try {
184: removeDBGame(this Name);
185: } catch (Exception e) {
186: //FIX: nothing done!
187: }
188: } else {
189: removeMemoryGame(this Name);
190: }
191: }
192:
193: /**
194: * This method removes thisGame's record from the DB
195: */
196: public synchronized void removeDBGame(String name) throws Exception {
197: GameDataDO gameDataDO = getGameDataByName(name);
198: try {
199: DBTransaction db = Enhydra.getDatabaseManager()
200: .createTransaction();
201: try {
202: // Multiple data objects could be update, deleted,inserted
203: // here as a single transaction.....
204: //Thread.currentThread().dumpStack();
205: db.delete(gameDataDO);
206: db.commit();
207: } catch (SQLException sqle) {
208: db.rollback();
209: throw sqle;
210: } finally {
211: // You must call this to free any resources (such as
212: // connections) that were allocated by the transaction.
213: db.release();
214: }
215: } catch (Exception e) {
216: // You should deal with any exceptions here....
217: throw e;
218: }
219: }
220:
221: /**
222: * This method removes the thisGame object from the Vector
223: */
224: public void removeMemoryGame(String name) {
225: int marker = 0;
226: PokerGame thatGame;
227:
228: //Lock gamelist before opps, for thread paranoia!
229: synchronized (this ) {
230: //get the index equal to thisGame, then remove it
231: for (int i = 0; i < super .size(); i++) {
232: thatGame = (PokerGame) super .elementAt(i);
233: //if(thatGame.getName().equalsIgnoreCase(name)){
234: if (thatGame.getName().equals(name)) {
235: marker = i;
236: }
237: }
238: super .removeElementAt(marker);
239: }
240: }
241:
242: /**
243: * This is a provate method that returns the GameDataDO
244: * from the database where oId = id
245: */
246: private GameDataDO getGameDataByName(String name) throws Exception {
247: GameDataDO gotGameDataDO = null;
248: GameDataQuery dq = new GameDataQuery();
249: dq.setQueryName(name);
250: try {
251: gotGameDataDO = (GameDataDO) dq.getNextDO();
252: } finally {
253: // Free up any resources
254: // dq.reset();
255: }
256: return gotGameDataDO;
257: }
258:
259: /**
260: * This method ddtermines which storage medium is ised, then
261: * doles the getGameByName request to the right place.
262: */
263: public PokerGame getGame(String name) {
264: PokerGame this Game = null;
265:
266: if (useDB) {
267: try {
268: GameDataDO this DO = null;
269: this DO = getGameDataByName(name);
270: this Game = mapNewPokerGame(this DO);
271:
272: } catch (Exception e) {
273: Enhydra.getLogChannel().write(Logger.DEBUG,
274: "ERROR! " + e.toString());
275: //FIX: Still need to take care of some exceptions :)
276: }
277: } else {
278: this Game = getGameInMemory(name);
279: }
280:
281: return this Game;
282:
283: }
284:
285: /**
286: * This method ddtermines which storage medium is ised, then
287: * doles the getIsNameUsed request to the right place.
288: */
289: public boolean getIsNameUsed(String name) {
290: boolean isUsed = true;
291:
292: if (this .useDB) {
293: isUsed = getIsNameUsedInDB(name);
294: } else {
295: isUsed = getIsNameUsedInMemory(name);
296: }
297:
298: return isUsed;
299: }
300:
301: /**
302: * This method ddtermines which storage medium is ised, then
303: * doles the getTopTen method to the right place.
304: */
305: public Vector getTopTen() {
306: Vector topTen = new Vector(0);
307: if (this .useDB) {
308: topTen = getTopTenInDB();
309: } else {
310: topTen = getTopTenInMemory();
311: }
312:
313: return topTen;
314: }
315:
316: /**
317: * This method ddtermines which storage medium is ised, then
318: * doles the authenticate request to the right place.
319: */
320: public boolean authenticate(String name, String pw) {
321: boolean auth = false;
322:
323: if (useDB) {
324: auth = authenticateInDB(name, pw);
325: } else {
326: auth = authenticateInMemory(name, pw);
327: }
328:
329: return auth;
330: }
331:
332: /**
333: * Check to see if this name has been used in the DB
334: */
335: public synchronized boolean getIsNameUsedInDB(String name) {
336: boolean isUsed = false;
337: // GameDataDO thisGameDataDO = null;
338: try {
339: if (getGameDataByName(name) == null) {
340: isUsed = false;
341: } else {
342: isUsed = true;
343: }
344: } catch (Exception e) {
345: isUsed = false;
346: }
347: return isUsed;
348: }
349:
350: /**
351: * Check to see if this name has been used in Memory
352: */
353: public synchronized boolean getIsNameUsedInMemory(String name) {
354: boolean isUsed = false;
355: PokerGame this Game;
356:
357: //Get copy of gameList object so we dont have to
358: // worry about locking the object for threadsafe opps
359: GameList gameListCopy = this .getCopy();
360:
361: // I used the for-next so that I could use equalsIgnorecase
362: // instead of Vector.contains()
363: for (int i = 0; i < gameListCopy.size(); i++) {
364: this Game = (PokerGame) gameListCopy.elementAt(i);
365: //if (thisGame.getName().equalsIgnoreCase(name)){
366: if (this Game.getName().equals(name)) {
367: isUsed = true;
368: }
369: }
370: return isUsed;
371: }
372:
373: /**
374: * Authenticate user in DB
375: */
376: public synchronized boolean authenticateInDB(String name, String pw) {
377: boolean isAuth = false;
378: try {
379: GameDataDO this GameDataDO = getGameDataByName(name);
380: if (this GameDataDO != null) {
381: if (this GameDataDO.getPassword().equalsIgnoreCase(pw)) {
382: isAuth = true;
383: }
384: } else {
385: isAuth = false;
386: }
387: } catch (Exception e) {
388: e.printStackTrace(); // VR
389: //Ooops! Not much excaption handeling in the app yet!
390: }
391: return isAuth;
392: }
393:
394: /**
395: * Authenticate user in memory
396: */
397: public synchronized boolean authenticateInMemory(String name,
398: String pw) {
399: boolean isAuth = false;
400: PokerGame this Game;
401:
402: //Get copy of the gameList object so we dont have to
403: //worry about locking it for threadsave opps
404: GameList gameListCopy = this .getCopy();
405:
406: // I used the for-next so that I could use equalsIgnorecase
407: // instead of Vector.contains()
408: for (int i = 0; i < gameListCopy.size(); i++) {
409: this Game = (PokerGame) gameListCopy.elementAt(i);
410: //if ((thisGame.getName().equalsIgnoreCase(name)) &
411: // (thisGame.getPassword().equalsIgnoreCase(pw))) {
412: if ((this Game.getName().equals(name))
413: & (this Game.getPassword().equals(pw))) {
414:
415: isAuth = true;
416: }
417: }
418: return isAuth;
419: }
420:
421: /**
422: * Return the game that belongs to user name
423: * from the Vector in memory
424: */
425: public synchronized PokerGame getGameInMemory(String name) {
426: PokerGameImpl this Game = new PokerGameImpl(name, "", "", 0);
427:
428: //Get copy of the gameList object so we dont have to
429: //worry about locking it for threadsafe opps
430: GameList gameListCopy = this .getCopy();
431: synchronized (this Game) {
432: //Yeah, I could have done this another way, but I didn't
433: for (int i = 0; i < gameListCopy.size(); i++) {
434: this Game = (PokerGameImpl) gameListCopy.elementAt(i);
435: //if (thisGame.getName().equalsIgnoreCase(name)){
436: if (this Game.getName().equals(name)) {
437: return this Game;
438: }
439: }
440: }
441: return this Game;
442: }
443:
444: /**
445: * return the top ten players ranked by cash won
446: */
447: public synchronized Vector getTopTenInMemory() {
448: Vector topTen = new Vector(0);
449: PokerGameImpl blankGame;
450: for (int i = 0; i < 10; i++) {
451: blankGame = new PokerGameImpl("", "", "", 0);
452: topTen.addElement(blankGame);
453: }
454: PokerGame game;
455: int rank[] = new int[10];
456: int Cash = 0;
457:
458: //get copy of gameList so we don't have to
459: //worry about locking the object for threadsafe opps
460: GameList gameListCopy = this .getCopy();
461:
462: //Really scary sort routine I came up with.
463: for (int x = 0; x < 10; x++) {
464: for (int i = 0; i < gameListCopy.size(); i++) {
465: game = (PokerGame) gameListCopy.elementAt(i);
466: if (x < 1) {
467: if (game.getCash() > rank[x]) {
468: rank[x] = game.getCash();
469: topTen.setElementAt(game, x);
470: }
471: } else {
472: if ((rank[x - 1] >= game.getCash())
473: & (!topTen.contains(game))
474: & (rank[x] <= game.getCash())) {
475: rank[x] = game.getCash();
476: topTen.setElementAt(game, x);
477: }
478: }
479: }
480: }
481: return topTen;
482: }
483:
484: /**
485: * Check to see if the DO changes need to be updated to the DB
486: */
487: public synchronized void updateGame(PokerGame this Game) {
488: if ((this .useDB) & (this Game.getIsDirty())) {
489: try {
490: GameDataDO gameDataDO = getGameDataByName(this Game
491: .getName());
492: gameDataDO.setDeck(this Game.getDeck());
493: gameDataDO.setLargestBet(this Game.getLargestBet());
494: gameDataDO.setSmallestBet(this Game.getSmallestBet());
495: gameDataDO.setTotalPlayed(this Game.getTotalPlayed());
496: gameDataDO.setTotalWon(this Game.getTotalWon());
497: gameDataDO.setCash(this Game.getCash());
498:
499: //vr DBTransaction db = Enhydra.getDatabaseManager().createTransaction();
500: try {
501: //vr db.update(gameDataDO);
502: //vr db.commit();
503: gameDataDO.save(); //vr
504: } catch (SQLException sqle) {
505: Enhydra.getLogChannel().write(Logger.INFO,
506: "ERROR! " + sqle.toString());
507: //vr db.rollback();
508: //vr throw sqle;
509: } finally {
510: //vr db.release();
511: }
512: } catch (Exception e) {
513: Enhydra.getLogChannel().write(Logger.DEBUG,
514: "ERROR! " + e.toString());
515: //FIX: Still need to take care of some exceptions :)
516: }
517: }
518: }
519:
520: /**
521: * This method returns the total players registered in the
522: * DB or Vector
523: */
524: public int getCount() {
525: int n = 0;
526: if (!useDB) {
527: n = this .size();
528: } else {
529: GameDataQuery dq = new GameDataQuery();
530: dq.getQueryBuilder().addEndClause(" order by Cash");
531: PokerGame tempGame = null;
532: try {
533: GameDataDO[] allGames = dq.getDOArray();
534: n = allGames.length;
535: } catch (Exception e) {
536: Enhydra.getLogChannel().write(Logger.INFO,
537: "ERROR: " + e.toString());
538: }
539:
540: }
541:
542: return n;
543: }
544:
545: /**
546: * This method queries the database for all games sorted
547: * by score, then returns a vector with the top 10
548: */
549: public Vector getTopTenInDB() {
550: GameDataQuery dq = new GameDataQuery();
551: dq.getQueryBuilder().addEndClause(" order by Cash");
552: Vector topTen = new Vector(0);
553: for (int i = 0; i < 10; i++) {
554: topTen.addElement(new PokerGameImpl("", "", "", 0));
555: }
556:
557: PokerGame tempGame = null;
558: try {
559: GameDataDO[] allGames = dq.getDOArray();
560:
561: int x = 0;
562: for (int i = allGames.length - 1; i > -1; i--) {
563: tempGame = mapNewPokerGame(allGames[i]);
564: topTen.setElementAt(tempGame, x);
565: x++;
566: if (x == 10) {
567: i = -1;
568: }
569: }
570:
571: } catch (Exception e) {
572: Enhydra.getLogChannel().write(Logger.INFO,
573: "ERROR: " + e.toString());
574: //FIX: Oops! I really should handle this
575: }
576:
577: return topTen;
578: }
579:
580: /**
581: * get rank of current dollars compared to the gameList
582: */
583: public synchronized int getRank(int cash) {
584: PokerGame game;
585: GameList gameListCopy = this .getCopy();
586: int rank = 0;
587: if (!useDB) {
588: //opps to be done on copy, eliminates need for object lock
589: for (int i = 0; i < gameListCopy.size(); i++) {
590: game = (PokerGame) gameListCopy.elementAt(i);
591: if (game.getCash() > cash) {
592: rank++;
593: }
594: }
595: } else {
596: GameDataQuery dq = new GameDataQuery();
597: dq.getQueryBuilder().addEndClause(" order by Cash");
598: try {
599: GameDataDO[] allGames = dq.getDOArray();
600: for (int i = 0; i < allGames.length; i++) {
601: if (allGames[i].getCash() > cash) {
602: rank++;
603: }
604: }
605: } catch (Exception e) {
606: Enhydra.getLogChannel().write(Logger.INFO,
607: "ERROR: " + e.toString());
608: }
609: }
610:
611: return rank + 1;
612: }
613:
614: }
|